public static void CreateVDisk(KeyValuePairList <string, string> parameters) { if (!VerifyParameters(parameters, "file", "size")) { Console.WriteLine(); Console.WriteLine("Invalid parameter."); HelpCreate(); return; } long sizeInBytes; if (parameters.ContainsKey("size")) { long requestedSizeInMB = Conversion.ToInt64(parameters.ValueOf("size"), 0); sizeInBytes = requestedSizeInMB * 1024 * 1024; if (requestedSizeInMB <= 0) { Console.WriteLine("Invalid size (must be specified in MB)."); return; } } else { Console.WriteLine("The SIZE parameter must be specified."); return; } if (parameters.ContainsKey("file")) { string path = parameters.ValueOf("file"); if (new FileInfo(path).Exists) { Console.WriteLine("Error: file already exists."); return; } try { m_selectedDisk = VirtualHardDisk.Create(path, sizeInBytes); Console.WriteLine("The virtual disk file was created successfully."); } catch (IOException) { Console.WriteLine("Error: Could not write the virtual disk file."); return; } catch (UnauthorizedAccessException) { Console.WriteLine("Error: Access Denied, Could not write the virtual disk file."); return; } } else { Console.WriteLine("The FILE parameter was not specified."); } }
public static void StartCommand(string[] args) { if (m_server == null) { if (m_targets.Count > 0) { KeyValuePairList <string, string> parameters = ParseParameters(args, 1); if (!VerifyParameters(parameters, "port", "log")) { Console.WriteLine(); Console.WriteLine("Invalid parameter"); HelpStart(); return; } int port = DefaultISCSIPort; if (parameters.ContainsKey("port")) { port = Conversion.ToInt32(parameters.ValueOf("port"), DefaultISCSIPort); } string logFile = String.Empty; if (parameters.ContainsKey("log")) { logFile = parameters.ValueOf("log"); } m_server = new ISCSIServer(m_targets, port, logFile); try { ISCSIServer.Log("Starting Server"); } catch (IOException) { Console.WriteLine("Could not append to log file"); return; } try { m_server.Start(); Console.WriteLine("Server started, listening on port {0}", port); } catch (SocketException) { Console.WriteLine("Could not start iSCSI server"); m_server.Stop(); m_server = null; } } else { Console.WriteLine("No disks have been attached"); } } }
public static void AttachISCSIDisk(Disk disk, string defaultTargetName, KeyValuePairList <string, string> parameters) { if (VerifyParameters(parameters, "readonly", "target")) { bool isReadOnly = parameters.ContainsKey("readonly"); disk.IsReadOnly |= isReadOnly; if (disk is DiskImage) { bool isLocked = ((DiskImage)disk).ExclusiveLock(); if (!isLocked) { Console.WriteLine("Error: Cannot lock the disk image for exclusive access"); return; } } ISCSITarget target = null; string targetName = defaultTargetName; if (parameters.ContainsKey("target")) { string name = parameters.ValueOf("target"); if (IsValidISCSIName(name)) { targetName = name; } else if (IsValidStorageTargetName(name)) { targetName = DefaultTargetIQN + ":" + name; } else { Console.WriteLine("Invalid parameter."); HelpAttach(); } } target = FindTarget(targetName); if (target == null) { target = AddTarget(targetName); } target.Disks.Add(disk); Console.WriteLine("Disk added to target: {0}", target.TargetName); } else { HelpAttach(); } }
public static void SelectCommand(string[] args) { if (args.Length == 1) { HelpSelect(); return; } switch (args[1].ToLower()) { case "disk": { if (args.Length == 3) { int diskIndex = Conversion.ToInt32(args[2], -1); if (diskIndex >= 0) { PhysicalDisk disk = null; try { disk = new PhysicalDisk(diskIndex); } catch { Console.WriteLine(); Console.WriteLine("Error: Invalid disk number"); } if (disk != null) { m_selectedDisk = disk; } } } else { Console.WriteLine(); Console.WriteLine("Error: Invalid number of arguments"); } break; } case "vdisk": { if (args.Length == 3) { KeyValuePairList <string, string> parameters = ParseParameters(args, 2); if (parameters.ContainsKey("file")) { string path = parameters.ValueOf("file"); if (new FileInfo(path).Exists) { try { m_selectedDisk = DiskImage.GetDiskImage(path); } catch (InvalidDataException) { Console.WriteLine("Invalid virtual disk format"); } catch (NotImplementedException) { Console.WriteLine("Unsupported virtual disk format"); } catch (IOException ex) { Console.WriteLine("Cannot read file: " + ex.Message); } } else { Console.WriteLine("File not found: \"{0}\"", path); } } else { Console.WriteLine(); Console.WriteLine("Error: Invalid argument"); } } else { Console.WriteLine("Error: Invalid number of arguments"); } break; } case "partition": { if (m_selectedDisk != null) { if (args.Length == 3) { int partitionIndex = Conversion.ToInt32(args[2], -1); List <Partition> partitions = BasicDiskHelper.GetPartitions(m_selectedDisk); if (partitionIndex >= 0 && partitionIndex < partitions.Count) { m_selectedVolume = partitions[partitionIndex]; } else { Console.WriteLine("Error: Invalid partition number"); } } else { Console.WriteLine(); Console.WriteLine("Error: Partition number was not specified"); } } else { Console.WriteLine("No disk has been selected"); } break; } case "volume": { if (args.Length == 3) { List <Volume> volumes; try { volumes = WindowsVolumeHelper.GetVolumes(); } catch { volumes = new List <Volume>(); } int volumeIndex = Conversion.ToInt32(args[2], -1); if (volumeIndex >= 0 && volumeIndex < volumes.Count) { m_selectedVolume = volumes[volumeIndex]; } else { Console.WriteLine(); Console.WriteLine("Error: Invalid volume number"); } } else { Console.WriteLine(); Console.WriteLine("Error: Volume number was not specified"); } break; } default: HelpSelect(); break; } }
private LoginResponseStatusName SetUpSession(LoginRequestPDU request, KeyValuePairList <string, string> requestParameters, ConnectionParameters connection) { string initiatorName = requestParameters.ValueOf("InitiatorName"); if (String.IsNullOrEmpty(initiatorName)) { // RFC 3720: InitiatorName: The initiator of the TCP connection MUST provide this key [..] // at the first Login of the Login Phase for every connection. string loginIdentifier = String.Format("ISID={0},TSIH={1},CID={2}", request.ISID.ToString("x"), request.TSIH.ToString("x"), request.CID.ToString("x")); Log(Severity.Warning, "[{0}] Initiator error: InitiatorName was not included in the login request", loginIdentifier); return(LoginResponseStatusName.InitiatorError); } if (request.TSIH == 0) { // Note: An initiator could login with the same ISID to a different target (another session), // We should only perform session reinstatement when an initiator is logging in to the same target. // For a new session, the request TSIH is zero, // As part of the response, the target generates a TSIH. connection.Session = m_sessionManager.StartSession(initiatorName, request.ISID); connection.CID = request.CID; Log(Severity.Verbose, "[{0}] Session has been started", connection.Session.SessionIdentifier); connection.Session.CommandNumberingStarted = true; connection.Session.ExpCmdSN = request.CmdSN; string sessionType = requestParameters.ValueOf("SessionType"); if (sessionType == "Discovery") { connection.Session.IsDiscovery = true; } else //sessionType == "Normal" or unspecified (default is Normal) { if (requestParameters.ContainsKey("TargetName")) { string targetName = requestParameters.ValueOf("TargetName"); return(SetUpNormalSession(request, targetName, connection)); } else { // RFC 3720: For any connection within a session whose type is not "Discovery", the first Login Request MUST also include the TargetName key=value pair. Log(Severity.Warning, "[{0}] Initiator error: TargetName was not included in a non-discovery session", connection.ConnectionIdentifier); return(LoginResponseStatusName.InitiatorError); } } } else { ISCSISession existingSession = m_sessionManager.FindSession(initiatorName, request.ISID, request.TSIH); if (existingSession == null) { return(LoginResponseStatusName.SessionDoesNotExist); } else { connection.Session = existingSession; ConnectionState existingConnection = m_connectionManager.FindConnection(existingSession, request.CID); if (existingConnection != null) { // do connection reinstatement Log(Severity.Verbose, "[{0}] Initiating implicit logout", existingConnection.ConnectionIdentifier); m_connectionManager.ReleaseConnection(existingConnection); } else { // add a new connection to the session if (m_connectionManager.GetSessionConnections(existingSession).Count > existingSession.MaxConnections) { return(LoginResponseStatusName.TooManyConnections); } } connection.CID = request.CID; } } return(LoginResponseStatusName.Success); }
private static void UpdateOperationalParameters(KeyValuePairList <string, string> loginParameters, ConnectionParameters connection) { ISCSISession session = connection.Session; string value = loginParameters.ValueOf("MaxRecvDataSegmentLength"); if (value != null) { connection.InitiatorMaxRecvDataSegmentLength = Convert.ToInt32(value); } value = loginParameters.ValueOf("MaxConnections"); if (value != null) { session.MaxConnections = Math.Min(Convert.ToInt32(value), ISCSIServer.DesiredParameters.MaxConnections); } value = loginParameters.ValueOf("InitialR2T"); if (value != null) { session.InitialR2T = (value == "Yes") || ISCSIServer.DesiredParameters.InitialR2T; } value = loginParameters.ValueOf("ImmediateData"); if (value != null) { session.ImmediateData = (value == "Yes") && ISCSIServer.DesiredParameters.ImmediateData; } value = loginParameters.ValueOf("MaxBurstLength"); if (value != null) { session.MaxBurstLength = Math.Min(Convert.ToInt32(value), ISCSIServer.DesiredParameters.MaxBurstLength); } value = loginParameters.ValueOf("FirstBurstLength"); if (value != null) { session.FirstBurstLength = Math.Min(Convert.ToInt32(value), ISCSIServer.DesiredParameters.FirstBurstLength); } value = loginParameters.ValueOf("DataPDUInOrder"); if (value != null) { session.DataPDUInOrder = (value == "Yes") || ISCSIServer.DesiredParameters.DataPDUInOrder; } value = loginParameters.ValueOf("DataSequenceInOrder"); if (value != null) { session.DataSequenceInOrder = (value == "Yes") || ISCSIServer.DesiredParameters.DataSequenceInOrder; } value = loginParameters.ValueOf("DefaultTime2Wait"); if (value != null) { session.DefaultTime2Wait = Math.Max(Convert.ToInt32(value), ISCSIServer.DesiredParameters.DefaultTime2Wait); } value = loginParameters.ValueOf("DefaultTime2Retain"); if (value != null) { session.DefaultTime2Retain = Math.Min(Convert.ToInt32(value), ISCSIServer.DesiredParameters.DefaultTime2Retain); } value = loginParameters.ValueOf("MaxOutstandingR2T"); if (value != null) { session.MaxOutstandingR2T = Math.Min(Convert.ToInt32(value), ISCSIServer.DesiredParameters.MaxOutstandingR2T); } }
internal static void UpdateOperationalParameters(KeyValuePairList <string, string> loginParameters, SessionParameters session, ConnectionParameters connection) { session.InitialR2T = ISCSIClient.OfferedInitialR2T; session.ImmediateData = ISCSIClient.OfferedImmediateData; session.MaxBurstLength = ISCSIClient.OfferedMaxBurstLength; session.FirstBurstLength = ISCSIClient.OfferedFirstBurstLength; session.DefaultTime2Wait = ISCSIClient.OfferedDefaultTime2Wait; session.DefaultTime2Retain = ISCSIClient.OfferedDefaultTime2Retain; session.MaxOutstandingR2T = ISCSIClient.OfferedMaxOutstandingR2T; session.DataPDUInOrder = ISCSIClient.OfferedDataPDUInOrder; session.DataSequenceInOrder = ISCSIClient.OfferedDataSequenceInOrder; session.ErrorRecoveryLevel = ISCSIClient.OfferedErrorRecoveryLevel; string value = loginParameters.ValueOf("MaxRecvDataSegmentLength"); if (value != null) { connection.TargetMaxRecvDataSegmentLength = Convert.ToInt32(value); } value = loginParameters.ValueOf("InitialR2T"); if (value != null) { session.InitialR2T = (value == "Yes") ? true : false; } value = loginParameters.ValueOf("ImmediateData"); if (value != null) { session.ImmediateData = (value == "Yes") ? true : false; } value = loginParameters.ValueOf("MaxBurstLength"); if (value != null) { session.MaxBurstLength = Convert.ToInt32(value); } value = loginParameters.ValueOf("FirstBurstLength"); if (value != null) { session.FirstBurstLength = Convert.ToInt32(value); } value = loginParameters.ValueOf("DefaultTime2Wait"); if (value != null) { session.DefaultTime2Wait = Convert.ToInt32(value); } value = loginParameters.ValueOf("DefaultTime2Retain"); if (value != null) { session.DefaultTime2Retain = Convert.ToInt32(value); } value = loginParameters.ValueOf("MaxOutstandingR2T"); if (value != null) { session.MaxOutstandingR2T = Convert.ToInt32(value); } value = loginParameters.ValueOf("DataPDUInOrder"); if (value != null) { session.DataPDUInOrder = (value == "Yes") ? true : false; } value = loginParameters.ValueOf("DataSequenceInOrder"); if (value != null) { session.DataSequenceInOrder = (value == "Yes") ? true : false; } value = loginParameters.ValueOf("ErrorRecoveryLevel"); if (value != null) { session.ErrorRecoveryLevel = Convert.ToInt32(value); } }
public static void SetCommand(string[] args) { if (args.Length == 2) { KeyValuePairList <string, string> parameters = ParseParameters(args, 1); if (!VerifyParameters(parameters, "debug", "commandqueue", "MaxRecvDataSegmentLength".ToLower(), "MaxBurstLength".ToLower(), "FirstBurstLength".ToLower())) { Console.WriteLine("Invalid parameter."); return; } if (parameters.ContainsKey("debug")) { m_debug = true; } if (parameters.ContainsKey("CommandQueue".ToLower())) { int requestedCommandQueueSize = Conversion.ToInt32(parameters.ValueOf("commandqueue"), 0); if (requestedCommandQueueSize < 0) { Console.WriteLine("Invalid queue size (must be non-negative)."); return; } SessionParameters.DefaultCommandQueueSize = (uint)requestedCommandQueueSize; } if (parameters.ContainsKey("MaxRecvDataSegmentLength".ToLower())) { int requestedMaxRecvDataSegmentLength = Conversion.ToInt32(parameters.ValueOf("MaxRecvDataSegmentLength".ToLower()), 0); if (requestedMaxRecvDataSegmentLength <= 0) { Console.WriteLine("Invalid length (must be positive)."); return; } ConnectionParameters.DeclaredMaxRecvDataSegmentLength = requestedMaxRecvDataSegmentLength; Console.WriteLine("MaxRecvDataSegmentLength has been set to " + ISCSIServer.OfferedMaxBurstLength); } if (parameters.ContainsKey("MaxBurstLength".ToLower())) { int requestedMaxBurstLength = Conversion.ToInt32(parameters.ValueOf("MaxBurstLength".ToLower()), 0); if (requestedMaxBurstLength <= 0) { Console.WriteLine("Invalid length (must be positive)."); return; } ISCSIServer.OfferedMaxBurstLength = requestedMaxBurstLength; Console.WriteLine("Offered MaxBurstLength has been set to " + ISCSIServer.OfferedMaxBurstLength); if (ISCSIServer.OfferedMaxBurstLength < ISCSIServer.OfferedFirstBurstLength) { // FirstBurstLength MUST NOT exceed MaxBurstLength ISCSIServer.OfferedFirstBurstLength = ISCSIServer.OfferedMaxBurstLength; Console.WriteLine("Offered FirstBurstLength has been set to " + ISCSIServer.OfferedFirstBurstLength); } } if (parameters.ContainsKey("FirstBurstLength".ToLower())) { int requestedFirstBurstLength = Conversion.ToInt32(parameters.ValueOf("FirstBurstLength".ToLower()), 0); if (requestedFirstBurstLength <= 0) { Console.WriteLine("Invalid length (must be positive)."); return; } ISCSIServer.OfferedFirstBurstLength = requestedFirstBurstLength; Console.WriteLine("Offered FirstBurstLength has been set to " + ISCSIServer.OfferedFirstBurstLength); if (ISCSIServer.OfferedMaxBurstLength < ISCSIServer.OfferedFirstBurstLength) { // FirstBurstLength MUST NOT exceed MaxBurstLength ISCSIServer.OfferedMaxBurstLength = ISCSIServer.OfferedFirstBurstLength; Console.WriteLine("Offered MaxBurstLength has been set to " + ISCSIServer.OfferedMaxBurstLength); } } } else if (args.Length > 2) { Console.WriteLine("Too many arguments."); HelpSet(); } else { HelpSet(); } }