VBoxManageStorageController.cpp revision 93771df67d4047d8b965665899b6a5bdf06ae277
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * VBoxManage - The storage controller related commands.
77bbd3327e8130eb01de6c1c1d1ef54e0ab48be8vboxsync * Copyright (C) 2006-2011 Oracle Corporation
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * available from http://www.virtualbox.org. This file is free software;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * you can redistribute it and/or modify it under the terms of the GNU
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * General Public License (GPL) as published by the Free Software
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync/*******************************************************************************
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync* Header Files *
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync*******************************************************************************/
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsyncusing namespace com;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync///////////////////////////////////////////////////////////////////////////////
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsyncstatic const RTGETOPTDEF g_aStorageAttachOptions[] =
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // iSCSI options
710a6316a22868b04400caf79719f96c18163cd3vboxsync int c = VERR_INTERNAL_ERROR; /* initialized to shut up gcc */
80e46f984efd827517661c0e081a36014ca41af8vboxsync bool fSetNewUuid = false;
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // iSCSI options
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync bool fIntNet = false;
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync RTGetOptInit(&GetState, a->argc, a->argv, g_aStorageAttachOptions,
fb1975a6972d89de9e515bed0248db93f04ec9d8vboxsync RT_ELEMENTS(g_aStorageAttachOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync case 'm': // medium <none|emptydrive|uuid|filename|host:<drive>|iSCSI>
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync return errorArgument("Invalid --type argument '%s'", ValueUnion.psz);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync int vrc = parseDiskType(ValueUnion.psz, &mediumType);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);
e073b07dcb5c9827f0530a9bfa2643356c5656dbvboxsync return errorSyntax(USAGE_STORAGEATTACH, "Storage controller name not specified");
ba05e6aeed3cd14961a36e0162c29a267b66d7f7vboxsync /* get the virtualbox system properties */
ba05e6aeed3cd14961a36e0162c29a267b66d7f7vboxsync CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), 1);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // find the machine, lock it, get the mutable session machine
508452243fd3328f7b9e0405d39fb9dc004e31b8vboxsync CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
f409459bdd4c15cdb8d7fb6c6d54338cce9ac814vboxsync CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1);
f409459bdd4c15cdb8d7fb6c6d54338cce9ac814vboxsync CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8Str("Drive passthrough state cannot be changed while the VM is running\n");
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8Str("Bandwidth group cannot be changed while the VM is running\n");
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* check if the storage controller is present */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync rc = machine->GetStorageControllerByName(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Could not find a controller named '%s'\n", pszCtl);
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync CHECK_ERROR_RET(storageCtl, COMGETTER(Bus)(&storageBus), 1);
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync CHECK_ERROR_RET(systemProperties, GetMaxPortCountForStorageBus(storageBus, &maxPorts), 1);
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync CHECK_ERROR_RET(systemProperties, GetMaxDevicesPerPortForStorageBus(storageBus, &maxDevices), 1);
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync if (port == ~0U)
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Port not specified");
174f11bbd5c277153742aa5e6c3bd640bf379547vboxsync return errorSyntax(USAGE_STORAGEATTACH, "Device not specified");
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* for sata controller check if the port count is big enough
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * to accommodate the current port which is being assigned
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * else just increase the port count
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(storageCtl, COMGETTER(MaxPortCount)(&ulMaxPortCount));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(storageCtl, COMGETTER(PortCount)(&ulPortCount));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(storageCtl, COMSETTER(PortCount)(port + 1));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync StorageControllerType_T ctlType = StorageControllerType_Null;
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(storageCtl, COMGETTER(ControllerType)(&ctlType));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl).raw(), port, device));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, device,
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* just unmount the floppy/dvd */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
9113fcf881235e2b3df9ce4760b299c929ac3a62vboxsync * Try to attach an empty DVD drive as a hotplug operation.
9113fcf881235e2b3df9ce4760b299c929ac3a62vboxsync * Main will complain if the controller doesn't support hotplugging.
9113fcf881235e2b3df9ce4760b299c929ac3a62vboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, device,
9113fcf881235e2b3df9ce4760b299c929ac3a62vboxsync deviceType = DeviceType_DVD; /* To avoid the error message below. */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("No DVD/Floppy Drive attached to the controller '%s'"
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync "at the port: %u, device: %u", pszCtl, port, device);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* check if the device type is supported by the controller */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("The attachment is not supported by the storage controller '%s'", pszCtl);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* attach a empty floppy/dvd drive after removing previous attachment */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, device,
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync } // end if (!RTStrICmp(pszMedium, "emptydrive"))
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // not "none", not "emptydrive": then it must be a UUID or filename or hostdrive or iSCSI;
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // for all these we first need to know the type of drive we're attaching to
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * try to determine the type of the drive from the
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * storage controller chipset, the attachment and
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * the medium being attached
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync if (ctlType == StorageControllerType_I82078) // floppy controller
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * for SATA/SCSI/IDE it is hard to tell if it is a harddisk or
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * a dvd being attached so lets check if the medium attachment
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * and the medium, both are of same type. if yes then we are
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * sure of its type and don't need the user to enter it manually
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * else ask the user for the type.
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync rc = findMedium(a, pszMedium, deviceType, true /* fSilent */,
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync if (devTypeRequested == DeviceType_Null) // still the initializer value?
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8Str("Argument --type must be specified\n");
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* check if the device type is supported by the controller */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes)));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("The given attachment is not supported by the storage controller '%s'", pszCtl);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // find the medium given
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* host drive? */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam()));
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync rc = host->FindHostDVDDrive(Bstr(pszMedium + 5).raw(),
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* 2nd try: try with the real name, important on Linux+libhal */
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync if (RT_FAILURE(RTPathReal(pszMedium + 5, szPathReal, sizeof(szPathReal))))
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Invalid host DVD drive name \"%s\"", pszMedium + 5);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync rc = host->FindHostDVDDrive(Bstr(szPathReal).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Invalid host DVD drive name \"%s\"", pszMedium + 5);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync rc = host->FindHostFloppyDrive(Bstr(pszMedium + 5).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Invalid host floppy drive name \"%s\"", pszMedium + 5);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* check for required options */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Parameters --server and --target are required for iSCSI media");
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /** @todo move the location stuff to Main, which can use pfnComposeName
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * from the disk backends to construct the location properly. Also do
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * not use slashes to separate the parts, as otherwise only the last
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync * element containing information will be shown. */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync bstrISCSIMedium = BstrFmt("%ls|%ls", bstrServer.raw(), bstrTarget.raw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync bstrISCSIMedium = BstrFmt("%ls|%ls|%ls", bstrServer.raw(), bstrTarget.raw(), bstrLun.raw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(a->virtualBox, CreateHardDisk(Bstr("iSCSI").raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync bstrServer = BstrFmt("%ls:%ls", bstrServer.raw(), bstrPort.raw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // set the other iSCSI parameters as properties
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync Bstr("TargetAddress").detachTo(names.appendedRaw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync Bstr("InitiatorUsername").detachTo(names.appendedRaw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync Bstr("InitiatorSecret").detachTo(names.appendedRaw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /// @todo add --initiator option - until that happens rely on the
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // defaults of the iSCSI initiator code. Setting it to a constant
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // value does more harm than good, as the initiator name is supposed
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // to identify a particular initiator uniquely.
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // Bstr("InitiatorName").detachTo(names.appendedRaw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // Bstr("iqn.2008-04.com.sun.virtualbox.initiator").detachTo(values.appendedRaw());
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /// @todo add --targetName and --targetPassword options
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(pMedium2Mount, SetProperties(ComSafeArrayAsInParam(names),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(pMedium2Mount, COMGETTER(Id)(guid.asOutParam()));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync RTPrintf("iSCSI disk created. UUID: %s\n", Utf8Str(guid).c_str());
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port,
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync rc = findOrOpenMedium(a, pszMedium, devTypeRequested,
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium);
80e46f984efd827517661c0e081a36014ca41af8vboxsync // set medium/parent medium UUID, if so desired
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync if (pMedium2Mount && (fSetNewUuid || fSetNewParentUuid))
80e46f984efd827517661c0e081a36014ca41af8vboxsync CHECK_ERROR(pMedium2Mount, SetIDs(fSetNewUuid, bstrNewUuid.raw(),
80e46f984efd827517661c0e081a36014ca41af8vboxsync throw Utf8Str("Failed to set the medium/parent medium UUID");
3221176430afca4d1be145b04bf50163fab4fdb1vboxsync // set medium type, if so desired
3221176430afca4d1be145b04bf50163fab4fdb1vboxsync CHECK_ERROR(pMedium2Mount, COMSETTER(Type)(mediumType));
3221176430afca4d1be145b04bf50163fab4fdb1vboxsync CHECK_ERROR(pMedium2Mount, COMSETTER(Description)(bstrComment.raw()));
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync // check if there is a dvd/floppy drive at the given location, if not attach one first
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(),
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync devTypeRequested, // DeviceType_DVD or DeviceType_Floppy
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(),
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync } // end DeviceType_DVD or DeviceType_Floppy:
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync // if there is anything attached at the given location, remove it
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync machine->DetachDevice(Bstr(pszCtl).raw(), port, device);
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Invalid --passthrough argument '%s'", pszPassThrough);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
1e9377d042fa2ea3e2cd78805678f23f64db55f6vboxsync CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
1e9377d042fa2ea3e2cd78805678f23f64db55f6vboxsync CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
1e9377d042fa2ea3e2cd78805678f23f64db55f6vboxsync CHECK_ERROR(machine, TemporaryEjectDevice(Bstr(pszCtl).raw(),
1e9377d042fa2ea3e2cd78805678f23f64db55f6vboxsync throw Utf8StrFmt("Invalid --tempeject argument '%s'", pszTempEject);
1e9377d042fa2ea3e2cd78805678f23f64db55f6vboxsync throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync CHECK_ERROR(machine, NonRotationalDevice(Bstr(pszCtl).raw(),
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync throw Utf8StrFmt("Invalid --nonrotational argument '%s'", pszNonRotational);
051eba4436f9c682f7873390fb327e8eceb9e0efvboxsync throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
6febf3149010855617e4a37e2c49f93d68930d44vboxsync CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port,
dfb2e698385f22ba39053f27fe2711e463acd3a1vboxsync CHECK_ERROR(machine, SetAutoDiscardForDevice(Bstr(pszCtl).raw(),
dfb2e698385f22ba39053f27fe2711e463acd3a1vboxsync CHECK_ERROR(machine, SetAutoDiscardForDevice(Bstr(pszCtl).raw(),
6febf3149010855617e4a37e2c49f93d68930d44vboxsync throw Utf8StrFmt("Invalid --nonrotational argument '%s'", pszNonRotational);
6febf3149010855617e4a37e2c49f93d68930d44vboxsync throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl);
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* Just remove the bandwidth gorup. */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam()));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(pszBandwidthGroup).raw(), bwGroup.asOutParam()));
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(),
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync /* commit changes */
aeb9498c4d9854ed42b271541d34c7bad97b4c77vboxsync // machine must always be unlocked, even on errors
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsyncstatic const RTGETOPTDEF g_aStorageControllerOptions[] =
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync { "--sataideemulation", 'e', RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync bool fRemoveCtl = false;
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync return errorSyntax(USAGE_STORAGECONTROLLER, "Too few parameters");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync RTGetOptInit (&GetState, a->argc, a->argv, g_aStorageControllerOptions,
fb1975a6972d89de9e515bed0248db93f04ec9d8vboxsync RT_ELEMENTS(g_aStorageControllerOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync case 'a': // controller bus type <ide/sata/scsi/floppy>
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync case 'c': // controller <lsilogic/buslogic/intelahci/piix3/piix4/ich6/i82078>
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorGetOpt(USAGE_STORAGECONTROLLER, c, &ValueUnion);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* try to find the given machine */
508452243fd3328f7b9e0405d39fb9dc004e31b8vboxsync CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(),
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* open a session for the VM */
f409459bdd4c15cdb8d7fb6c6d54338cce9ac814vboxsync CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Write), 1);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* get the mutable session machine */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync a->session->COMGETTER(Machine)(machine.asOutParam());
a425b5e790c27d6a1a2cf738802e9034f0764a00vboxsync /* it's important to always close sessions */
e073b07dcb5c9827f0530a9bfa2643356c5656dbvboxsync errorSyntax(USAGE_STORAGECONTROLLER, "Storage controller name not specified\n");
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync com::SafeIfaceArray<IMediumAttachment> mediumAttachments;
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync GetMediumAttachmentsOfController(Bstr(pszCtl).raw(),
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync for (size_t i = 0; i < mediumAttachments.size(); ++ i)
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync ComPtr<IMediumAttachment> mediumAttach = mediumAttachments[i];
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(mediumAttach, COMGETTER(Device)(&device));
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl).raw(), port, device));
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, RemoveStorageController(Bstr(pszCtl).raw()));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Can't detach the devices connected to '%s' Controller\n"
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, AddStorageController(Bstr(pszCtl).raw(),
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Invalid --add argument '%s'", pszBusType);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogic));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_BusLogic));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_IntelAhci));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX3));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_PIIX4));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_ICH6));
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_I82078));
b306a397b157898e6f769f640b0dfdffbf8beec7vboxsync CHECK_ERROR(ctl, COMSETTER(ControllerType)(StorageControllerType_LsiLogicSas));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Invalid --type argument '%s'", pszCtlType);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, COMSETTER(PortCount)(sataportcount));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync if ( (sataidedev != ~0U)
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
1dc37bff2fb26897f5892d8330fe2bc0c9859aecvboxsync CHECK_ERROR(ctl, SetIDEEmulationPort(satabootdev, sataidedev));
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
1207f59aa62006952dbb0bf7700decf34d8caeb2vboxsync CHECK_ERROR(machine, GetStorageControllerByName(Bstr(pszCtl).raw(),
39fa431e2dbe885a37b126ccd293f8e8255812a6vboxsync CHECK_ERROR(ctl, COMSETTER(UseHostIOCache)(FALSE));
39fa431e2dbe885a37b126ccd293f8e8255812a6vboxsync errorArgument("Invalid --hostiocache argument '%s'", pszHostIOCache);
39fa431e2dbe885a37b126ccd293f8e8255812a6vboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bf88068260ded16af90b7da4867240fbdd9c8017vboxsync CHECK_ERROR(machine, SetStorageControllerBootable(Bstr(pszCtl).raw(), TRUE));
bf88068260ded16af90b7da4867240fbdd9c8017vboxsync CHECK_ERROR(machine, SetStorageControllerBootable(Bstr(pszCtl).raw(), FALSE));
77bbd3327e8130eb01de6c1c1d1ef54e0ab48be8vboxsync errorArgument("Invalid --bootable argument '%s'", pszBootable);
bf88068260ded16af90b7da4867240fbdd9c8017vboxsync errorArgument("Couldn't find the controller with the name: '%s'\n", pszCtl);
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* commit changes */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync /* it's important to always close sessions */
bddad5eeab93a98d4ea571ccdf016531bb4318advboxsync#endif /* !VBOX_ONLY_DOCS */