summaryrefslogtreecommitdiff
path: root/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp')
-rw-r--r--src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp291
1 files changed, 212 insertions, 79 deletions
diff --git a/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
index ea8f2ec5c..9032da276 100644
--- a/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
+++ b/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
@@ -1,4 +1,4 @@
-/* $Id: VBoxManageStorageController.cpp $ */
+/* $Id: VBoxManageStorageController.cpp 37929 2011-07-13 18:34:49Z vboxsync $ */
/** @file
* VBoxManage - The storage controller related commands.
*/
@@ -51,13 +51,17 @@ static const RTGETOPTDEF g_aStorageAttachOptions[] =
{ "--medium", 'm', RTGETOPT_REQ_STRING },
{ "--mtype", 'M', RTGETOPT_REQ_STRING },
{ "--passthrough", 'h', RTGETOPT_REQ_STRING },
+ { "--tempeject", 'e', RTGETOPT_REQ_STRING },
+ { "--nonrotational", 'n', RTGETOPT_REQ_STRING },
{ "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING },
{ "--forceunmount", 'f', RTGETOPT_REQ_NOTHING },
{ "--comment", 'C', RTGETOPT_REQ_STRING },
+ { "--setuuid", 'q', RTGETOPT_REQ_STRING },
+ { "--setparentuuid", 'Q', RTGETOPT_REQ_STRING },
// iSCSI options
{ "--server", 'S', RTGETOPT_REQ_STRING },
{ "--target", 'T', RTGETOPT_REQ_STRING },
- { "--port", 'P', RTGETOPT_REQ_STRING },
+ { "--tport", 'P', RTGETOPT_REQ_STRING },
{ "--lun", 'L', RTGETOPT_REQ_STRING },
{ "--encodedlun", 'E', RTGETOPT_REQ_STRING },
{ "--username", 'U', RTGETOPT_REQ_STRING },
@@ -73,13 +77,19 @@ int handleStorageAttach(HandlerArg *a)
ULONG device = ~0U;
bool fForceUnmount = false;
bool fSetMediumType = false;
+ bool fSetNewUuid = false;
+ bool fSetNewParentUuid = false;
MediumType_T mediumType = MediumType_Normal;
Bstr bstrComment;
const char *pszCtl = NULL;
DeviceType_T devTypeRequested = DeviceType_Null;
const char *pszMedium = NULL;
const char *pszPassThrough = NULL;
+ const char *pszTempEject = NULL;
+ const char *pszNonRotational = NULL;
const char *pszBandwidthGroup = NULL;
+ Bstr bstrNewUuid;
+ Bstr bstrNewParentUuid;
// iSCSI options
Bstr bstrServer;
Bstr bstrTarget;
@@ -160,6 +170,24 @@ int handleStorageAttach(HandlerArg *a)
break;
}
+ case 'e': // tempeject <on|off>
+ {
+ if (ValueUnion.psz)
+ pszTempEject = ValueUnion.psz;
+ else
+ rc = E_FAIL;
+ break;
+ }
+
+ case 'n': // nonrotational <on|off>
+ {
+ if (ValueUnion.psz)
+ pszNonRotational = ValueUnion.psz;
+ else
+ rc = E_FAIL;
+ break;
+ }
+
case 'b': // bandwidthgroup <name>
{
if (ValueUnion.psz)
@@ -180,7 +208,27 @@ int handleStorageAttach(HandlerArg *a)
bstrComment = ValueUnion.psz;
else
rc = E_FAIL;
- break;
+ break;
+
+ case 'q':
+ if (ValueUnion.psz)
+ {
+ bstrNewUuid = ValueUnion.psz;
+ fSetNewUuid = true;
+ }
+ else
+ rc = E_FAIL;
+ break;
+
+ case 'Q':
+ if (ValueUnion.psz)
+ {
+ bstrNewParentUuid = ValueUnion.psz;
+ fSetNewParentUuid = true;
+ }
+ else
+ rc = E_FAIL;
+ break;
case 'S': // --server
bstrServer = ValueUnion.psz;
@@ -190,7 +238,7 @@ int handleStorageAttach(HandlerArg *a)
bstrTarget = ValueUnion.psz;
break;
- case 'P': // --port
+ case 'P': // --tport
bstrPort = ValueUnion.psz;
break;
@@ -237,10 +285,6 @@ int handleStorageAttach(HandlerArg *a)
if (!pszCtl)
return errorSyntax(USAGE_STORAGEATTACH, "Storage controller name not specified");
- if (port == ~0U)
- return errorSyntax(USAGE_STORAGEATTACH, "Port not specified");
- if (device == ~0U)
- return errorSyntax(USAGE_STORAGEATTACH, "Device not specified");
/* get the virtualbox system properties */
CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), 1);
@@ -256,13 +300,10 @@ int handleStorageAttach(HandlerArg *a)
try
{
bool fRunTime = (st == SessionType_Shared);
+
if (fRunTime)
{
- if (devTypeRequested == DeviceType_HardDisk)
- throw Utf8Str("Hard disk drives cannot be changed while the VM is running\n");
- else if (!RTStrICmp(pszMedium, "none"))
- throw Utf8Str("Drives cannot be removed while the VM is running\n");
- else if (pszPassThrough)
+ if (pszPassThrough)
throw Utf8Str("Drive passthrough state cannot be changed while the VM is running\n");
else if (pszBandwidthGroup)
throw Utf8Str("Bandwidth group cannot be changed while the VM is running\n");
@@ -274,6 +315,28 @@ int handleStorageAttach(HandlerArg *a)
if (FAILED(rc))
throw Utf8StrFmt("Could not find a controller named '%s'\n", pszCtl);
+ StorageBus_T storageBus = StorageBus_Null;
+ CHECK_ERROR_RET(storageCtl, COMGETTER(Bus)(&storageBus), 1);
+ ULONG maxPorts = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxPortCountForStorageBus(storageBus, &maxPorts), 1);
+ ULONG maxDevices = 0;
+ CHECK_ERROR_RET(systemProperties, GetMaxDevicesPerPortForStorageBus(storageBus, &maxDevices), 1);
+
+ if (port == ~0U)
+ {
+ if (maxPorts == 1)
+ port = 0;
+ else
+ return errorSyntax(USAGE_STORAGEATTACH, "Port not specified");
+ }
+ if (device == ~0U)
+ {
+ if (maxDevices == 1)
+ device = 0;
+ else
+ return errorSyntax(USAGE_STORAGEATTACH, "Device not specified");
+ }
+
/* for sata controller check if the port count is big enough
* to accommodate the current port which is being assigned
* else just increase the port count
@@ -332,13 +395,11 @@ int handleStorageAttach(HandlerArg *a)
}
else
{
- StorageBus_T storageBus = StorageBus_Null;
DeviceType_T deviceType = DeviceType_Null;
com::SafeArray <DeviceType_T> saDeviceTypes;
ULONG driveCheck = 0;
/* check if the device type is supported by the controller */
- CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
for (size_t i = 0; i < saDeviceTypes.size(); ++ i)
{
@@ -375,7 +436,7 @@ int handleStorageAttach(HandlerArg *a)
*/
if (ctlType == StorageControllerType_I82078) // floppy controller
devTypeRequested = DeviceType_Floppy;
- else if (pszMedium)
+ else
{
/*
* for SATA/SCSI/IDE it is hard to tell if it is a harddisk or
@@ -393,19 +454,23 @@ int handleStorageAttach(HandlerArg *a)
DeviceType_T deviceType;
mediumAttachment->COMGETTER(Type)(&deviceType);
- ComPtr<IMedium> pExistingMedium;
- rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
- pExistingMedium);
- if (SUCCEEDED(rc) && pExistingMedium)
+ if (pszMedium)
{
- if ( (deviceType == DeviceType_DVD)
- || (deviceType == DeviceType_HardDisk)
- )
- devTypeRequested = deviceType;
+ ComPtr<IMedium> pExistingMedium;
+ rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
+ pExistingMedium);
+ if (SUCCEEDED(rc) && pExistingMedium)
+ {
+ if ( (deviceType == DeviceType_DVD)
+ || (deviceType == DeviceType_HardDisk)
+ )
+ devTypeRequested = deviceType;
+ }
}
+ else
+ devTypeRequested = deviceType;
}
}
- /* for all other cases lets ask the user what type of drive it is */
}
if (devTypeRequested == DeviceType_Null) // still the initializer value?
@@ -413,10 +478,8 @@ int handleStorageAttach(HandlerArg *a)
/* check if the device type is supported by the controller */
{
- StorageBus_T storageBus = StorageBus_Null;
com::SafeArray <DeviceType_T> saDeviceTypes;
- CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus));
CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
if (SUCCEEDED(rc))
{
@@ -538,14 +601,32 @@ int handleStorageAttach(HandlerArg *a)
}
else
{
- Bstr bstrMedium(pszMedium);
- if (bstrMedium.isEmpty())
- throw Utf8Str("Missing --medium argument");
-
- rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
- pMedium2Mount, NULL);
- if (FAILED(rc) || !pMedium2Mount)
- throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+ if (!pszMedium)
+ {
+ ComPtr<IMediumAttachment> mediumAttachment;
+ rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device,
+ mediumAttachment.asOutParam());
+ if (FAILED(rc))
+ throw Utf8Str("Missing --medium argument");
+ }
+ else
+ {
+ Bstr bstrMedium(pszMedium);
+ rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
+ pMedium2Mount, fSetNewUuid, NULL);
+ if (FAILED(rc) || !pMedium2Mount)
+ throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
+ }
+ }
+
+ // set medium/parent medium UUID, if so desired
+ if (pMedium2Mount && (fSetNewUuid || fSetNewParentUuid))
+ {
+ CHECK_ERROR(pMedium2Mount, SetIDs(fSetNewUuid, bstrNewUuid.raw(),
+ fSetNewParentUuid, bstrNewParentUuid.raw()));
+ if (FAILED(rc))
+ throw Utf8Str("Failed to set the medium/parent medium UUID");
}
// set medium type, if so desired
@@ -561,26 +642,37 @@ int handleStorageAttach(HandlerArg *a)
CHECK_ERROR(pMedium2Mount, COMSETTER(Description)(bstrComment.raw()));
}
- switch (devTypeRequested)
+ if (pszMedium)
{
- case DeviceType_DVD:
- case DeviceType_Floppy:
+ switch (devTypeRequested)
{
- if (!fRunTime)
+ case DeviceType_DVD:
+ case DeviceType_Floppy:
{
- ComPtr<IMediumAttachment> mediumAttachment;
- // check if there is a dvd/floppy drive at the given location, if not attach one first
- rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
- port,
- device,
- mediumAttachment.asOutParam());
- if (SUCCEEDED(rc))
+ if (!fRunTime)
{
- DeviceType_T deviceType;
- mediumAttachment->COMGETTER(Type)(&deviceType);
- if (deviceType != devTypeRequested)
+ ComPtr<IMediumAttachment> mediumAttachment;
+ // check if there is a dvd/floppy drive at the given location, if not attach one first
+ rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
+ port,
+ device,
+ mediumAttachment.asOutParam());
+ if (SUCCEEDED(rc))
+ {
+ DeviceType_T deviceType;
+ mediumAttachment->COMGETTER(Type)(&deviceType);
+ if (deviceType != devTypeRequested)
+ {
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ rc = machine->AttachDevice(Bstr(pszCtl).raw(),
+ port,
+ device,
+ devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
+ NULL);
+ }
+ }
+ else
{
- machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
rc = machine->AttachDevice(Bstr(pszCtl).raw(),
port,
device,
@@ -588,41 +680,30 @@ int handleStorageAttach(HandlerArg *a)
NULL);
}
}
- else
+
+ if (pMedium2Mount)
{
- rc = machine->AttachDevice(Bstr(pszCtl).raw(),
- port,
- device,
- devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
- NULL);
+ CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
+ port,
+ device,
+ pMedium2Mount,
+ fForceUnmount));
}
- }
+ } // end DeviceType_DVD or DeviceType_Floppy:
+ break;
- if (pMedium2Mount)
+ case DeviceType_HardDisk:
{
- CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
- port,
- device,
- pMedium2Mount,
- fForceUnmount));
+ // if there is anything attached at the given location, remove it
+ machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
+ CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
+ port,
+ device,
+ DeviceType_HardDisk,
+ pMedium2Mount));
}
- } // end DeviceType_DVD or DeviceType_Floppy:
- break;
-
- case DeviceType_HardDisk:
- {
- if (fRunTime)
- throw Utf8Str("Hard disk attachments cannot be changed while the VM is running");
-
- // if there is anything attached at the given location, remove it
- machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
- CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
- port,
- device,
- DeviceType_HardDisk,
- pMedium2Mount));
+ break;
}
- break;
}
}
@@ -652,6 +733,58 @@ int handleStorageAttach(HandlerArg *a)
throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
}
+ if ( pszTempEject
+ && (SUCCEEDED(rc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(rc))
+ {
+ if (!RTStrICmp(pszTempEject, "on"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszTempEject, "off"))
+ {
+ CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt("Invalid --tempeject argument '%s'", pszTempEject);
+ }
+ else
+ throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
+ }
+
+ if ( pszNonRotational
+ && (SUCCEEDED(rc)))
+ {
+ ComPtr<IMediumAttachment> mattach;
+ CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
+ device, mattach.asOutParam()));
+
+ if (SUCCEEDED(rc))
+ {
+ if (!RTStrICmp(pszNonRotational, "on"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, TRUE));
+ }
+ else if (!RTStrICmp(pszNonRotational, "off"))
+ {
+ CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
+ port, device, FALSE));
+ }
+ else
+ throw Utf8StrFmt("Invalid --nonrotational argument '%s'", pszNonRotational);
+ }
+ else
+ throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
+ }
+
if ( pszBandwidthGroup
&& !fRunTime
&& SUCCEEDED(rc))