Changeset 34634 in vbox for trunk/src/VBox/Frontends/VBoxManage
- Timestamp:
- Dec 2, 2010 5:21:40 PM (14 years ago)
- Location:
- trunk/src/VBox/Frontends/VBoxManage
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.cpp
r34587 r34634 399 399 { "clonehd", USAGE_CLONEHD, handleCloneHardDisk }, 400 400 { "clonevdi", USAGE_CLONEHD, handleCloneHardDisk }, /* backward compatibility */ 401 { "addiscsidisk", USAGE_ADDISCSIDISK, handleAddiSCSIDisk },402 401 { "createvm", USAGE_CREATEVM, handleCreateVM }, 403 402 { "modifyvm", USAGE_MODIFYVM, handleModifyVM }, -
trunk/src/VBox/Frontends/VBoxManage/VBoxManage.h
r34587 r34634 54 54 #define USAGE_MODIFYHD RT_BIT_64(14) 55 55 #define USAGE_CLONEHD RT_BIT_64(15) 56 #define USAGE_ADDISCSIDISK RT_BIT_64(16)57 56 #define USAGE_CREATEHOSTIF RT_BIT_64(17) 58 57 #define USAGE_REMOVEHOSTIF RT_BIT_64(18) … … 218 217 int handleCloneHardDisk(HandlerArg *a); 219 218 RTEXITCODE handleConvertFromRaw(int argc, char *argv[]); 220 int handleAddiSCSIDisk(HandlerArg *a);221 219 int handleShowHardDiskInfo(HandlerArg *a); 222 220 int handleCloseMedium(HandlerArg *a); 221 int parseDiskType(const char *psz, MediumType_T *pDiskType); 223 222 224 223 /* VBoxManageStorageController.cpp */ -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp
r33764 r34634 97 97 } 98 98 99 staticint parseDiskType(const char *psz, MediumType_T *pDiskType)99 int parseDiskType(const char *psz, MediumType_T *pDiskType) 100 100 { 101 101 int rc = VINF_SUCCESS; … … 158 158 { "--variant", 'm', RTGETOPT_REQ_STRING }, 159 159 { "-variant", 'm', RTGETOPT_REQ_STRING }, // deprecated 160 { "--type", 't', RTGETOPT_REQ_STRING },161 { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated162 { "--comment", 'c', RTGETOPT_REQ_STRING },163 { "-comment", 'c', RTGETOPT_REQ_STRING }, // deprecated164 { "--remember", 'r', RTGETOPT_REQ_NOTHING },165 { "-remember", 'r', RTGETOPT_REQ_NOTHING }, // deprecated166 { "--register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated (unofficial)167 { "-register", 'r', RTGETOPT_REQ_NOTHING }, // deprecated168 160 }; 169 161 … … 176 168 Bstr format = "VDI"; 177 169 MediumVariant_T DiskVariant = MediumVariant_Standard; 178 Bstr comment;179 bool fRemember = false;180 MediumType_T DiskType = MediumType_Normal;181 170 182 171 int c; … … 218 207 if (RT_FAILURE(vrc)) 219 208 return errorArgument("Invalid hard disk variant '%s'", ValueUnion.psz); 220 break;221 222 case 'c': // --comment223 comment = ValueUnion.psz;224 break;225 226 case 'r': // --remember227 fRemember = true;228 break;229 230 case 't': // --type231 vrc = parseDiskType(ValueUnion.psz, &DiskType);232 if ( RT_FAILURE(vrc)233 || ( DiskType != MediumType_Normal234 && DiskType != MediumType_Writethrough235 && DiskType != MediumType_Shareable))236 return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);237 209 break; 238 210 … … 281 253 if (SUCCEEDED(rc) && hardDisk) 282 254 { 283 /* we will close the hard disk after the storage has been successfully284 * created unless fRemember is set */285 bool doClose = false;286 287 if (!comment.isEmpty())288 {289 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment.raw()));290 }291 292 255 ComPtr<IProgress> progress; 293 256 CHECK_ERROR(hardDisk, CreateBaseStorage(size, DiskVariant, progress.asOutParam())); … … 305 268 else 306 269 { 307 doClose = !fRemember;308 309 270 Bstr uuid; 310 271 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam())); 311 312 if ( DiskType == MediumType_Writethrough313 || DiskType == MediumType_Shareable)314 {315 CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));316 }317 318 272 RTPrintf("Disk image created. UUID: %s\n", Utf8Str(uuid).c_str()); 319 273 } 320 274 } 321 if (doClose) 322 { 323 CHECK_ERROR(hardDisk, Close()); 324 } 275 CHECK_ERROR(hardDisk, Close()); 325 276 } 326 277 return SUCCEEDED(rc) ? 0 : 1; … … 955 906 } 956 907 957 static const RTGETOPTDEF g_aAddiSCSIDiskOptions[] =958 {959 { "--server", 's', RTGETOPT_REQ_STRING },960 { "-server", 's', RTGETOPT_REQ_STRING }, // deprecated961 { "--target", 'T', RTGETOPT_REQ_STRING },962 { "-target", 'T', RTGETOPT_REQ_STRING }, // deprecated963 { "--port", 'p', RTGETOPT_REQ_STRING },964 { "-port", 'p', RTGETOPT_REQ_STRING }, // deprecated965 { "--lun", 'l', RTGETOPT_REQ_STRING },966 { "-lun", 'l', RTGETOPT_REQ_STRING }, // deprecated967 { "--encodedlun", 'L', RTGETOPT_REQ_STRING },968 { "-encodedlun", 'L', RTGETOPT_REQ_STRING }, // deprecated969 { "--username", 'u', RTGETOPT_REQ_STRING },970 { "-username", 'u', RTGETOPT_REQ_STRING }, // deprecated971 { "--password", 'P', RTGETOPT_REQ_STRING },972 { "-password", 'P', RTGETOPT_REQ_STRING }, // deprecated973 { "--type", 't', RTGETOPT_REQ_STRING },974 { "-type", 't', RTGETOPT_REQ_STRING }, // deprecated975 { "--intnet", 'I', RTGETOPT_REQ_NOTHING },976 { "-intnet", 'I', RTGETOPT_REQ_NOTHING }, // deprecated977 };978 979 int handleAddiSCSIDisk(HandlerArg *a)980 {981 HRESULT rc;982 int vrc;983 Bstr server;984 Bstr target;985 Bstr port;986 Bstr lun;987 Bstr username;988 Bstr password;989 Bstr comment;990 bool fIntNet = false;991 MediumType_T DiskType = MediumType_Normal;992 993 int c;994 RTGETOPTUNION ValueUnion;995 RTGETOPTSTATE GetState;996 // start at 0 because main() has hacked both the argc and argv given to us997 RTGetOptInit(&GetState, a->argc, a->argv, g_aAddiSCSIDiskOptions, RT_ELEMENTS(g_aAddiSCSIDiskOptions),998 0, RTGETOPTINIT_FLAGS_NO_STD_OPTS);999 while ((c = RTGetOpt(&GetState, &ValueUnion)))1000 {1001 switch (c)1002 {1003 case 's': // --server1004 server = ValueUnion.psz;1005 break;1006 1007 case 'T': // --target1008 target = ValueUnion.psz;1009 break;1010 1011 case 'p': // --port1012 port = ValueUnion.psz;1013 break;1014 1015 case 'l': // --lun1016 lun = ValueUnion.psz;1017 break;1018 1019 case 'L': // --encodedlun1020 lun = BstrFmt("enc%s", ValueUnion.psz);1021 break;1022 1023 case 'u': // --username1024 username = ValueUnion.psz;1025 break;1026 1027 case 'P': // --password1028 password = ValueUnion.psz;1029 break;1030 1031 case 't': // --type1032 vrc = parseDiskType(ValueUnion.psz, &DiskType);1033 if (RT_FAILURE(vrc))1034 return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz);1035 break;1036 1037 case 'I': // --intnet1038 fIntNet = true;1039 break;1040 1041 case VINF_GETOPT_NOT_OPTION:1042 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", ValueUnion.psz);1043 1044 default:1045 if (c > 0)1046 {1047 if (RT_C_IS_PRINT(c))1048 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid option -%c", c);1049 else1050 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid option case %i", c);1051 }1052 else if (c == VERR_GETOPT_UNKNOWN_OPTION)1053 return errorSyntax(USAGE_ADDISCSIDISK, "unknown option: %s\n", ValueUnion.psz);1054 else if (ValueUnion.pDef)1055 return errorSyntax(USAGE_ADDISCSIDISK, "%s: %Rrs", ValueUnion.pDef->pszLong, c);1056 else1057 return errorSyntax(USAGE_ADDISCSIDISK, "error: %Rrs", c);1058 }1059 }1060 1061 /* check for required options */1062 if (server.isEmpty() || target.isEmpty())1063 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters --server and --target are required");1064 1065 do1066 {1067 ComPtr<IMedium> hardDisk;1068 /** @todo move the location stuff to Main, which can use pfnComposeName1069 * from the disk backends to construct the location properly. Also do1070 * not use slashes to separate the parts, as otherwise only the last1071 * element containing information will be shown. */1072 if (lun.isEmpty() || lun == "0" || lun == "enc0")1073 {1074 CHECK_ERROR_BREAK(a->virtualBox, CreateHardDisk(Bstr("iSCSI").raw(),1075 BstrFmt("%ls|%ls",1076 server.raw(),1077 target.raw()).raw(),1078 hardDisk.asOutParam()));1079 }1080 else1081 {1082 CHECK_ERROR_BREAK(a->virtualBox, CreateHardDisk(Bstr("iSCSI").raw(),1083 BstrFmt("%ls|%ls|%ls",1084 server.raw(),1085 target.raw(),1086 lun.raw()).raw(),1087 hardDisk.asOutParam()));1088 }1089 if (FAILED(rc)) break;1090 1091 if (!port.isEmpty())1092 server = BstrFmt("%ls:%ls", server.raw(), port.raw());1093 1094 com::SafeArray <BSTR> names;1095 com::SafeArray <BSTR> values;1096 1097 Bstr("TargetAddress").detachTo(names.appendedRaw());1098 server.detachTo(values.appendedRaw());1099 Bstr("TargetName").detachTo(names.appendedRaw());1100 target.detachTo(values.appendedRaw());1101 1102 if (!lun.isEmpty())1103 {1104 Bstr("LUN").detachTo(names.appendedRaw());1105 lun.detachTo(values.appendedRaw());1106 }1107 if (!username.isEmpty())1108 {1109 Bstr("InitiatorUsername").detachTo(names.appendedRaw());1110 username.detachTo(values.appendedRaw());1111 }1112 if (!password.isEmpty())1113 {1114 Bstr("InitiatorSecret").detachTo(names.appendedRaw());1115 password.detachTo(values.appendedRaw());1116 }1117 1118 /// @todo add --initiator option - until that happens rely on the1119 // defaults of the iSCSI initiator code. Setting it to a constant1120 // value does more harm than good, as the initiator name is supposed1121 // to identify a particular initiator uniquely.1122 // Bstr("InitiatorName").detachTo(names.appendedRaw());1123 // Bstr("iqn.2008-04.com.sun.virtualbox.initiator").detachTo(values.appendedRaw());1124 1125 /// @todo add --targetName and --targetPassword options1126 1127 if (fIntNet)1128 {1129 Bstr("HostIPStack").detachTo(names.appendedRaw());1130 Bstr("0").detachTo(values.appendedRaw());1131 }1132 1133 CHECK_ERROR_BREAK(hardDisk, SetProperties(ComSafeArrayAsInParam(names),1134 ComSafeArrayAsInParam(values)));1135 1136 if (DiskType != MediumType_Normal)1137 {1138 CHECK_ERROR(hardDisk, COMSETTER(Type)(DiskType));1139 }1140 1141 Bstr guid;1142 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));1143 RTPrintf("iSCSI disk created. UUID: %s\n", Utf8Str(guid).c_str());1144 }1145 while (0);1146 1147 return SUCCEEDED(rc) ? 0 : 1;1148 }1149 1150 908 static const RTGETOPTDEF g_aShowHardDiskInfoOptions[] = 1151 909 { -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r34587 r34634 97 97 98 98 if (u64Cmd == USAGE_ALL) 99 {100 99 RTStrmPrintf(pStrm, 101 100 "VBoxManage [-v|--version] print version number and exit\n" 102 101 "VBoxManage [-q|--nologo] ... suppress the logo\n" 103 102 "\n"); 104 }105 103 106 104 if (u64Cmd & USAGE_LIST) 107 {108 105 RTStrmPrintf(pStrm, 109 106 "VBoxManage list [--long|-l] vms|runningvms|ostypes|hostdvds|hostfloppies|\n" … … 117 114 " extpacks\n" 118 115 "\n"); 119 }120 116 121 117 if (u64Cmd & USAGE_SHOWVMINFO) 122 {123 118 RTStrmPrintf(pStrm, 124 119 "VBoxManage showvminfo <uuid>|<name> [--details] [--statistics]\n" … … 126 121 "VBoxManage showvminfo <uuid>|<name> --log <idx>\n" 127 122 "\n"); 128 }129 123 130 124 if (u64Cmd & USAGE_REGISTERVM) 131 {132 125 RTStrmPrintf(pStrm, 133 126 "VBoxManage registervm <filename>\n" 134 127 "\n"); 135 }136 128 137 129 if (u64Cmd & USAGE_UNREGISTERVM) 138 {139 130 RTStrmPrintf(pStrm, 140 131 "VBoxManage unregistervm <uuid>|<name> [--delete]\n" 141 132 "\n"); 142 }143 133 144 134 if (u64Cmd & USAGE_CREATEVM) 145 {146 135 RTStrmPrintf(pStrm, 147 136 "VBoxManage createvm --name <name>\n" … … 151 140 " [--uuid <uuid>]\n" 152 141 "\n"); 153 }154 142 155 143 if (u64Cmd & USAGE_MODIFYVM) … … 337 325 338 326 if (u64Cmd & USAGE_IMPORTAPPLIANCE) 339 {340 327 RTStrmPrintf(pStrm, 341 328 "VBoxManage import <ovf/ova> [--dry-run|-n] [more options]\n" 342 329 " (run with -n to have options displayed\n" 343 330 " for a particular OVF)\n\n"); 344 }345 331 346 332 if (u64Cmd & USAGE_EXPORTAPPLIANCE) 347 {348 333 RTStrmPrintf(pStrm, 349 334 "VBoxManage export <machines> --output|-o <ovf/ova>\n" … … 359 344 " [--eulafile <filename>]\n" 360 345 "\n"); 361 }362 346 363 347 if (u64Cmd & USAGE_STARTVM) … … 417 401 418 402 if (u64Cmd & USAGE_DISCARDSTATE) 419 {420 403 RTStrmPrintf(pStrm, 421 404 "VBoxManage discardstate <uuid>|<name>\n" 422 405 "\n"); 423 }424 406 425 407 if (u64Cmd & USAGE_ADOPTSTATE) 426 {427 408 RTStrmPrintf(pStrm, 428 409 "VBoxManage adoptstate <uuid>|<name> <state_file>\n" 429 410 "\n"); 430 }431 411 432 412 if (u64Cmd & USAGE_SNAPSHOT) 433 {434 413 RTStrmPrintf(pStrm, 435 414 "VBoxManage snapshot <uuid>|<name>\n" … … 443 422 " showvminfo <uuid>|<name>\n" 444 423 "\n"); 445 }446 424 447 425 if (u64Cmd & USAGE_CLOSEMEDIUM) 448 {449 426 RTStrmPrintf(pStrm, 450 427 "VBoxManage closemedium disk|dvd|floppy <uuid>|<filename>\n" 451 428 " [--delete]\n" 452 429 "\n"); 453 }454 430 455 431 if (u64Cmd & USAGE_STORAGEATTACH) 456 {457 432 RTStrmPrintf(pStrm, 458 433 "VBoxManage storageattach <uuid|vmname>\n" … … 462 437 " [--type dvddrive|hdd|fdd]\n" 463 438 " [--medium none|emptydrive|\n" 464 " <uuid>|<filename>|host:<drive>]\n" 439 " <uuid>|<filename>|host:<drive>|iscsi]\n" 440 " [--mtype normal|writethrough|immutable|shareable]\n" 465 441 " [--passthrough on|off]\n" 466 442 " [--bandwidthgroup <name>]\n" 467 443 " [--forceunmount]\n" 468 "\n"); 469 } 444 " [--server <name>|<ip>]\n" 445 " [--target <target>]\n" 446 " [--port <port>]\n" 447 " [--lun <lun>]\n" 448 " [--encodedlun <lun>]\n" 449 " [--username <username>]\n" 450 " [--password <password>]\n" 451 " [--intnet]\n" 452 "\n"); 470 453 471 454 if (u64Cmd & USAGE_STORAGECONTROLLER) 472 {473 455 RTStrmPrintf(pStrm, 474 456 "VBoxManage storagectl <uuid|vmname>\n" … … 483 465 " [--remove]\n" 484 466 "\n"); 485 }486 467 487 468 if (u64Cmd & USAGE_BANDWIDTHCONTROL) 488 {489 469 RTStrmPrintf(pStrm, 490 470 "VBoxManage bandwidthctl <uuid|vmname>\n" … … 494 474 " [--delete]\n" 495 475 "\n"); 496 }497 476 498 477 if (u64Cmd & USAGE_SHOWHDINFO) 499 {500 478 RTStrmPrintf(pStrm, 501 479 "VBoxManage showhdinfo <uuid>|<filename>\n" 502 480 "\n"); 503 }504 481 505 482 if (u64Cmd & USAGE_CREATEHD) 506 {507 483 RTStrmPrintf(pStrm, 508 484 "VBoxManage createhd --filename <filename>\n" … … 510 486 " [--format VDI|VMDK|VHD] (default: VDI)\n" 511 487 " [--variant Standard,Fixed,Split2G,Stream,ESX]\n" 512 " [--type normal|writethrough|\n" 513 " shareable] (default: normal)\n" 514 " [--comment <comment>]\n" 515 " [--remember]\n" 516 "\n"); 517 } 488 "\n"); 518 489 519 490 if (u64Cmd & USAGE_MODIFYHD) 520 {521 491 RTStrmPrintf(pStrm, 522 492 "VBoxManage modifyhd <uuid>|<filename>\n" … … 526 496 " [--resize <megabytes>]\n" 527 497 "\n"); 528 }529 498 530 499 if (u64Cmd & USAGE_CLONEHD) 531 {532 500 RTStrmPrintf(pStrm, 533 501 "VBoxManage clonehd <uuid>|<filename> <outputfile>\n" … … 537 505 " [--remember] [--existing]\n" 538 506 "\n"); 539 }540 507 541 508 if (u64Cmd & USAGE_CONVERTFROMRAW) 542 {543 509 RTStrmPrintf(pStrm, 544 510 "VBoxManage convertfromraw <filename> <outputfile>\n" … … 551 517 #endif 552 518 "\n"); 553 }554 555 if (u64Cmd & USAGE_ADDISCSIDISK)556 {557 RTStrmPrintf(pStrm,558 "VBoxManage addiscsidisk --server <name>|<ip>\n"559 " --target <target>\n"560 " [--port <port>]\n"561 " [--lun <lun>]\n"562 " [--encodedlun <lun>]\n"563 " [--username <username>]\n"564 " [--password <password>]\n"565 " [--type normal|writethrough|immutable|shareable]\n"566 " [--intnet]\n"567 "\n");568 }569 519 570 520 if (u64Cmd & USAGE_GETEXTRADATA) 571 {572 521 RTStrmPrintf(pStrm, 573 522 "VBoxManage getextradata global|<uuid>|<name>\n" 574 523 " <key>|enumerate\n" 575 524 "\n"); 576 }577 525 578 526 if (u64Cmd & USAGE_SETEXTRADATA) 579 {580 527 RTStrmPrintf(pStrm, 581 528 "VBoxManage setextradata global|<uuid>|<name>\n" … … 583 530 " [<value>] (no value deletes key)\n" 584 531 "\n"); 585 }586 532 587 533 if (u64Cmd & USAGE_SETPROPERTY) 588 {589 534 RTStrmPrintf(pStrm, 590 535 "VBoxManage setproperty machinefolder default|<folder> |\n" … … 594 539 " loghistorycount <value>\n" 595 540 "\n"); 596 }597 541 598 542 if (u64Cmd & USAGE_USBFILTER_ADD) 599 {600 543 RTStrmPrintf(pStrm, 601 544 "VBoxManage usbfilter add <index,0-N>\n" … … 613 556 " [--maskedinterfaces <XXXXXXXX>]\n" 614 557 "\n"); 615 }616 558 617 559 if (u64Cmd & USAGE_USBFILTER_MODIFY) 618 {619 560 RTStrmPrintf(pStrm, 620 561 "VBoxManage usbfilter modify <index,0-N>\n" … … 632 573 " [--maskedinterfaces <XXXXXXXX>]\n" 633 574 "\n"); 634 }635 575 636 576 if (u64Cmd & USAGE_USBFILTER_REMOVE) 637 {638 577 RTStrmPrintf(pStrm, 639 578 "VBoxManage usbfilter remove <index,0-N>\n" 640 579 " --target <uuid>|<name>|global\n" 641 580 "\n"); 642 }643 581 644 582 if (u64Cmd & USAGE_SHAREDFOLDER_ADD) 645 {646 583 RTStrmPrintf(pStrm, 647 584 "VBoxManage sharedfolder add <vmname>|<uuid>\n" … … 649 586 " [--transient] [--readonly] [--automount]\n" 650 587 "\n"); 651 }652 588 653 589 if (u64Cmd & USAGE_SHAREDFOLDER_REMOVE) 654 {655 590 RTStrmPrintf(pStrm, 656 591 "VBoxManage sharedfolder remove <vmname>|<uuid>\n" 657 592 " --name <name> [--transient]\n" 658 593 "\n"); 659 }660 594 661 595 if (u64Cmd & USAGE_VM_STATISTICS) 662 {663 596 RTStrmPrintf(pStrm, 664 597 "VBoxManage vmstatistics <vmname>|<uuid> [--reset]\n" 665 598 " [--pattern <pattern>] [--descriptions]\n" 666 599 "\n"); 667 }668 600 669 601 #ifdef VBOX_WITH_GUEST_PROPS … … 678 610 679 611 if (u64Cmd & USAGE_METRICS) 680 {681 612 RTStrmPrintf(pStrm, 682 613 "VBoxManage metrics list [*|host|<vmname> [<metric_list>]]\n" … … 701 632 " [*|host|<vmname> [<metric_list>]]\n" 702 633 "\n"); 703 } 634 704 635 #if defined(VBOX_WITH_NETFLT) 705 636 if (u64Cmd & USAGE_HOSTONLYIFS) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageStorageController.cpp
r34587 r34634 45 45 static const RTGETOPTDEF g_aStorageAttachOptions[] = 46 46 { 47 { "--storagectl", 's', RTGETOPT_REQ_STRING }, 48 { "--port", 'p', RTGETOPT_REQ_UINT32 }, 49 { "--device", 'd', RTGETOPT_REQ_UINT32 }, 50 { "--medium", 'm', RTGETOPT_REQ_STRING }, 51 { "--type", 't', RTGETOPT_REQ_STRING }, 52 { "--passthrough", 'h', RTGETOPT_REQ_STRING }, 53 { "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING }, 54 { "--forceunmount", 'f', RTGETOPT_REQ_NOTHING }, 47 { "--storagectl", 's', RTGETOPT_REQ_STRING }, 48 { "--port", 'p', RTGETOPT_REQ_UINT32 }, 49 { "--device", 'd', RTGETOPT_REQ_UINT32 }, 50 { "--type", 't', RTGETOPT_REQ_STRING }, 51 { "--medium", 'm', RTGETOPT_REQ_STRING }, 52 { "--mtype", 'M', RTGETOPT_REQ_STRING }, 53 { "--passthrough", 'h', RTGETOPT_REQ_STRING }, 54 { "--bandwidthgroup", 'b', RTGETOPT_REQ_STRING }, 55 { "--forceunmount", 'f', RTGETOPT_REQ_NOTHING }, 56 { "--comment", 'C', RTGETOPT_REQ_STRING }, 57 // iSCSI options 58 { "--server", 'S', RTGETOPT_REQ_STRING }, 59 { "--target", 'T', RTGETOPT_REQ_STRING }, 60 { "--port", 'P', RTGETOPT_REQ_STRING }, 61 { "--lun", 'L', RTGETOPT_REQ_STRING }, 62 { "--encodedlun", 'E', RTGETOPT_REQ_STRING }, 63 { "--username", 'U', RTGETOPT_REQ_STRING }, 64 { "--password", 'W', RTGETOPT_REQ_STRING }, 65 { "--intnet", 'I', RTGETOPT_REQ_NOTHING }, 55 66 }; 56 67 … … 62 73 ULONG device = ~0U; 63 74 bool fForceUnmount = false; 75 MediumType_T mediumType = MediumType_Normal; 76 Bstr bstrComment; 64 77 const char *pszCtl = NULL; 65 const char *pszType = NULL;78 DeviceType_T devTypeRequested = DeviceType_Null; 66 79 const char *pszMedium = NULL; 67 80 const char *pszPassThrough = NULL; 68 81 const char *pszBandwidthGroup = NULL; 82 // iSCSI options 83 Bstr bstrServer; 84 Bstr bstrTarget; 85 Bstr bstrPort; 86 Bstr bstrLun; 87 Bstr bstrUsername; 88 Bstr bstrPassword; 89 bool fIntNet = false; 90 69 91 RTGETOPTUNION ValueUnion; 70 92 RTGETOPTSTATE GetState; … … 73 95 ComPtr<ISystemProperties> systemProperties; 74 96 75 if (a->argc < 9)76 return errorSyntax(USAGE_STORAGEATTACH, "Too few parameters");77 else if (a->argc > 13)78 return errorSyntax(USAGE_STORAGEATTACH, "Too many parameters");79 80 97 RTGetOptInit(&GetState, a->argc, a->argv, g_aStorageAttachOptions, 81 98 RT_ELEMENTS(g_aStorageAttachOptions), 1, RTGETOPTINIT_FLAGS_NO_STD_OPTS); … … 107 124 } 108 125 109 case 'm': // medium <none|emptydrive|uuid|filename|host:<drive> >126 case 'm': // medium <none|emptydrive|uuid|filename|host:<drive>|iSCSI> 110 127 { 111 128 if (ValueUnion.psz) … … 119 136 { 120 137 if (ValueUnion.psz) 121 pszType = ValueUnion.psz; 138 { 139 if (!RTStrICmp(ValueUnion.psz, "hdd")) 140 devTypeRequested = DeviceType_HardDisk; 141 else if (!RTStrICmp(ValueUnion.psz, "fdd")) 142 devTypeRequested = DeviceType_Floppy; 143 else if (!RTStrICmp(ValueUnion.psz, "dvddrive")) 144 devTypeRequested = DeviceType_DVD; 145 else 146 return errorArgument("Invalid --type argument '%s'", ValueUnion.psz); 147 } 122 148 else 123 149 rc = E_FAIL; … … 148 174 break; 149 175 } 176 177 case 'C': 178 if (ValueUnion.psz) 179 bstrComment = ValueUnion.psz; 180 else 181 rc = E_FAIL; 182 break; 183 184 case 'S': // --server 185 bstrServer = ValueUnion.psz; 186 break; 187 188 case 'T': // --target 189 bstrTarget = ValueUnion.psz; 190 break; 191 192 case 'P': // --port 193 bstrPort = ValueUnion.psz; 194 break; 195 196 case 'L': // --lun 197 bstrLun = ValueUnion.psz; 198 break; 199 200 case 'E': // --encodedlun 201 bstrLun = BstrFmt("enc%s", ValueUnion.psz); 202 break; 203 204 case 'U': // --username 205 bstrUsername = ValueUnion.psz; 206 break; 207 208 case 'W': // --password 209 bstrPassword = ValueUnion.psz; 210 break; 211 212 case 'M': // --type 213 { 214 int vrc = parseDiskType(ValueUnion.psz, &mediumType); 215 if (RT_FAILURE(vrc)) 216 return errorArgument("Invalid hard disk type '%s'", ValueUnion.psz); 217 break; 218 } 219 220 case 'I': // --intnet 221 fIntNet = true; 222 break; 150 223 151 224 default: … … 171 244 CHECK_ERROR_RET(a->virtualBox, COMGETTER(SystemProperties)(systemProperties.asOutParam()), 1); 172 245 173 / * try to find the given machine */246 // find the machine, lock it, get the mutable session machine 174 247 CHECK_ERROR_RET(a->virtualBox, FindMachine(Bstr(a->argv[0]).raw(), 175 248 machine.asOutParam()), 1); 176 177 /* open a session for the VM (new or shared) */178 249 CHECK_ERROR_RET(machine, LockMachine(a->session, LockType_Shared), 1); 179 250 SessionType_T st; 180 251 CHECK_ERROR_RET(a->session, COMGETTER(Type)(&st), 1); 181 bool fRunTime = (st == SessionType_Shared);182 183 if (fRunTime && !RTStrICmp(pszType, "hdd"))252 a->session->COMGETTER(Machine)(machine.asOutParam()); 253 254 try 184 255 { 185 errorArgument("Hard disk drives cannot be changed while the VM is running\n"); 186 goto leave; 187 } 188 189 if (fRunTime && !RTStrICmp(pszMedium, "none")) 190 { 191 errorArgument("Drives cannot be removed while the VM is running\n"); 192 goto leave; 193 } 194 195 if (fRunTime && pszPassThrough) 196 { 197 errorArgument("Drive passthrough state can't be changed while the VM is running\n"); 198 goto leave; 199 } 200 201 if (fRunTime && pszBandwidthGroup) 202 { 203 errorArgument("Bandwidth group can't be changed while the VM is running\n"); 204 goto leave; 205 } 206 207 /* get the mutable session machine */ 208 a->session->COMGETTER(Machine)(machine.asOutParam()); 209 210 /* check if the storage controller is present */ 211 rc = machine->GetStorageControllerByName(Bstr(pszCtl).raw(), 212 storageCtl.asOutParam()); 213 if (FAILED(rc)) 214 { 215 errorSyntax(USAGE_STORAGEATTACH, "Couldn't find the controller with the name: '%s'\n", pszCtl); 216 goto leave; 217 } 218 219 /* for sata controller check if the port count is big enough 220 * to accommodate the current port which is being assigned 221 * else just increase the port count 222 */ 223 { 224 ULONG ulPortCount = 0; 225 ULONG ulMaxPortCount = 0; 226 227 CHECK_ERROR(storageCtl, COMGETTER(MaxPortCount)(&ulMaxPortCount)); 228 CHECK_ERROR(storageCtl, COMGETTER(PortCount)(&ulPortCount)); 229 230 if ( (ulPortCount != ulMaxPortCount) 231 && (port >= ulPortCount) 232 && (port < ulMaxPortCount)) 233 CHECK_ERROR(storageCtl, COMSETTER(PortCount)(port + 1)); 234 } 235 236 if (!RTStrICmp(pszMedium, "none")) 237 { 238 CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl).raw(), port, device)); 239 } 240 else if (!RTStrICmp(pszMedium, "emptydrive")) 241 { 256 bool fRunTime = (st == SessionType_Shared); 242 257 if (fRunTime) 243 258 { 244 ComPtr<IMediumAttachment> mediumAttachment; 245 DeviceType_T deviceType = DeviceType_Null; 246 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, device, 247 mediumAttachment.asOutParam()); 248 if (SUCCEEDED(rc)) 249 { 250 mediumAttachment->COMGETTER(Type)(&deviceType); 251 252 if ( (deviceType == DeviceType_DVD) 253 || (deviceType == DeviceType_Floppy)) 254 { 255 /* just unmount the floppy/dvd */ 256 CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(), 257 port, 258 device, 259 NULL, 260 fForceUnmount)); 261 } 262 } 263 264 if ( FAILED(rc) 265 || !( deviceType == DeviceType_DVD 266 || deviceType == DeviceType_Floppy)) 267 { 268 errorArgument("No DVD/Floppy Drive attached to the controller '%s'" 269 "at the port: %u, device: %u", pszCtl, port, device); 270 goto leave; 271 } 272 273 } 259 if (devTypeRequested == DeviceType_HardDisk) 260 throw Utf8Str("Hard disk drives cannot be changed while the VM is running\n"); 261 else if (!RTStrICmp(pszMedium, "none")) 262 throw Utf8Str("Drives cannot be removed while the VM is running\n"); 263 else if (pszPassThrough) 264 throw Utf8Str("Drive passthrough state cannot be changed while the VM is running\n"); 265 else if (pszBandwidthGroup) 266 throw Utf8Str("Bandwidth group cannot be changed while the VM is running\n"); 267 } 268 269 /* check if the storage controller is present */ 270 rc = machine->GetStorageControllerByName(Bstr(pszCtl).raw(), 271 storageCtl.asOutParam()); 272 if (FAILED(rc)) 273 throw Utf8StrFmt("Could not find a controller named '%s'\n", pszCtl); 274 275 /* for sata controller check if the port count is big enough 276 * to accommodate the current port which is being assigned 277 * else just increase the port count 278 */ 279 { 280 ULONG ulPortCount = 0; 281 ULONG ulMaxPortCount = 0; 282 283 CHECK_ERROR(storageCtl, COMGETTER(MaxPortCount)(&ulMaxPortCount)); 284 CHECK_ERROR(storageCtl, COMGETTER(PortCount)(&ulPortCount)); 285 286 if ( (ulPortCount != ulMaxPortCount) 287 && (port >= ulPortCount) 288 && (port < ulMaxPortCount)) 289 CHECK_ERROR(storageCtl, COMSETTER(PortCount)(port + 1)); 290 } 291 292 StorageControllerType_T ctlType = StorageControllerType_Null; 293 CHECK_ERROR(storageCtl, COMGETTER(ControllerType)(&ctlType)); 294 295 if (!RTStrICmp(pszMedium, "none")) 296 { 297 CHECK_ERROR(machine, DetachDevice(Bstr(pszCtl).raw(), port, device)); 298 } 299 else if (!RTStrICmp(pszMedium, "emptydrive")) 300 { 301 if (fRunTime) 302 { 303 ComPtr<IMediumAttachment> mediumAttachment; 304 DeviceType_T deviceType = DeviceType_Null; 305 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, device, 306 mediumAttachment.asOutParam()); 307 if (SUCCEEDED(rc)) 308 { 309 mediumAttachment->COMGETTER(Type)(&deviceType); 310 311 if ( (deviceType == DeviceType_DVD) 312 || (deviceType == DeviceType_Floppy)) 313 { 314 /* just unmount the floppy/dvd */ 315 CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(), 316 port, 317 device, 318 NULL, 319 fForceUnmount)); 320 } 321 } 322 323 if ( FAILED(rc) 324 || !( deviceType == DeviceType_DVD 325 || deviceType == DeviceType_Floppy) 326 ) 327 throw Utf8StrFmt("No DVD/Floppy Drive attached to the controller '%s'" 328 "at the port: %u, device: %u", pszCtl, port, device); 329 330 } 331 else 332 { 333 StorageBus_T storageBus = StorageBus_Null; 334 DeviceType_T deviceType = DeviceType_Null; 335 com::SafeArray <DeviceType_T> saDeviceTypes; 336 ULONG driveCheck = 0; 337 338 /* check if the device type is supported by the controller */ 339 CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus)); 340 CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes))); 341 for (size_t i = 0; i < saDeviceTypes.size(); ++ i) 342 { 343 if ( (saDeviceTypes[i] == DeviceType_DVD) 344 || (saDeviceTypes[i] == DeviceType_Floppy)) 345 driveCheck++; 346 } 347 348 if (!driveCheck) 349 throw Utf8StrFmt("The attachment is not supported by the storage controller '%s'", pszCtl); 350 351 if (storageBus == StorageBus_Floppy) 352 deviceType = DeviceType_Floppy; 353 else 354 deviceType = DeviceType_DVD; 355 356 /* attach a empty floppy/dvd drive after removing previous attachment */ 357 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 358 CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, device, 359 deviceType, NULL)); 360 } 361 } // end if (!RTStrICmp(pszMedium, "emptydrive")) 274 362 else 275 363 { 276 StorageBus_T storageBus = StorageBus_Null; 277 DeviceType_T deviceType = DeviceType_Null; 278 com::SafeArray <DeviceType_T> saDeviceTypes; 279 ULONG driveCheck = 0; 364 ComPtr<IMedium> pMedium2Mount; 365 366 // not "none", not "emptydrive": then it must be a UUID or filename or hostdrive or iSCSI; 367 // for all these we first need to know the type of drive we're attaching to 368 { 369 /* 370 * try to determine the type of the drive from the 371 * storage controller chipset, the attachment and 372 * the medium being attached 373 */ 374 if (ctlType == StorageControllerType_I82078) // floppy controller 375 devTypeRequested = DeviceType_Floppy; 376 else 377 { 378 /* 379 * for SATA/SCSI/IDE it is hard to tell if it is a harddisk or 380 * a dvd being attached so lets check if the medium attachment 381 * and the medium, both are of same type. if yes then we are 382 * sure of its type and don't need the user to enter it manually 383 * else ask the user for the type. 384 */ 385 ComPtr<IMediumAttachment> mediumAttachment; 386 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, 387 device, 388 mediumAttachment.asOutParam()); 389 if (SUCCEEDED(rc)) 390 { 391 DeviceType_T deviceType; 392 mediumAttachment->COMGETTER(Type)(&deviceType); 393 394 ComPtr<IMedium> pExistingMedium; 395 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 396 deviceType, 397 pExistingMedium.asOutParam()); 398 if (pExistingMedium) 399 { 400 if ( (deviceType == DeviceType_DVD) 401 || (deviceType == DeviceType_HardDisk) 402 ) 403 devTypeRequested == deviceType; 404 } 405 } 406 } 407 /* for all other cases lets ask the user what type of drive it is */ 408 } 409 410 if (devTypeRequested == DeviceType_Null) // still the initializer value? 411 throw Utf8Str("Argument --type must be specified\n"); 280 412 281 413 /* check if the device type is supported by the controller */ 282 CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus)); 283 CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes))); 284 for (size_t i = 0; i < saDeviceTypes.size(); ++ i) 285 { 286 if ( (saDeviceTypes[i] == DeviceType_DVD) 287 || (saDeviceTypes[i] == DeviceType_Floppy)) 288 driveCheck++; 289 } 290 291 if (!driveCheck) 292 { 293 errorArgument("The Attachment is not supported by the Storage Controller: '%s'", pszCtl); 294 goto leave; 295 } 296 297 if (storageBus == StorageBus_Floppy) 298 deviceType = DeviceType_Floppy; 299 else 300 deviceType = DeviceType_DVD; 301 302 /* attach a empty floppy/dvd drive after removing previous attachment */ 303 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 304 CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, device, 305 deviceType, NULL)); 306 } 307 } 308 else 309 { 310 { 311 /* 312 * try to determine the type of the drive from the 313 * storage controller chipset, the attachment and 314 * the medium being attached 315 */ 316 StorageControllerType_T ctlType = StorageControllerType_Null; 317 CHECK_ERROR(storageCtl, COMGETTER(ControllerType)(&ctlType)); 318 if (ctlType == StorageControllerType_I82078) 319 { 320 /* 321 * floppy controller found so lets assume the medium 322 * given by the user is also a floppy image or floppy 323 * host drive 324 */ 325 pszType = "fdd"; 326 } 327 else 328 { 329 /* 330 * for SATA/SCSI/IDE it is hard to tell if it is a harddisk or 331 * a dvd being attached so lets check if the medium attachment 332 * and the medium, both are of same type. if yes then we are 333 * sure of its type and don't need the user to enter it manually 334 * else ask the user for the type. 335 */ 336 ComPtr<IMediumAttachment> mediumAttachement; 337 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, 338 device, 339 mediumAttachement.asOutParam()); 414 { 415 StorageBus_T storageBus = StorageBus_Null; 416 com::SafeArray <DeviceType_T> saDeviceTypes; 417 418 CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus)); 419 CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes))); 340 420 if (SUCCEEDED(rc)) 341 421 { 342 DeviceType_T deviceType; 343 mediumAttachement->COMGETTER(Type)(&deviceType); 344 345 if (deviceType == DeviceType_DVD) 346 { 347 ComPtr<IMedium> dvdMedium; 348 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 349 DeviceType_DVD, 350 dvdMedium.asOutParam()); 351 if (dvdMedium) 352 /* 353 * ok so the medium and attachment both are DVD's so it is 354 * safe to assume that we are dealing with a DVD here 355 */ 356 pszType = "dvddrive"; 357 } 358 else if (deviceType == DeviceType_HardDisk) 359 { 360 ComPtr<IMedium> hardDisk; 361 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 362 DeviceType_HardDisk, 363 hardDisk.asOutParam()); 364 if (hardDisk) 365 /* 366 * ok so the medium and attachment both are hdd's so it is 367 * safe to assume that we are dealing with a hdd here 368 */ 369 pszType = "hdd"; 370 } 371 } 372 } 373 /* for all other cases lets ask the user what type of drive it is */ 374 } 375 376 if (!pszType) 377 { 378 errorSyntax(USAGE_STORAGEATTACH, "Argument --type not specified\n"); 379 goto leave; 380 } 381 382 /* check if the device type is supported by the controller */ 383 { 384 StorageBus_T storageBus = StorageBus_Null; 385 com::SafeArray <DeviceType_T> saDeviceTypes; 386 387 CHECK_ERROR(storageCtl, COMGETTER(Bus)(&storageBus)); 388 CHECK_ERROR(systemProperties, GetDeviceTypesForStorageBus(storageBus, ComSafeArrayAsOutParam(saDeviceTypes))); 389 if (SUCCEEDED(rc)) 390 { 391 ULONG driveCheck = 0; 392 for (size_t i = 0; i < saDeviceTypes.size(); ++ i) 393 { 394 if ( !RTStrICmp(pszType, "dvddrive") 395 && (saDeviceTypes[i] == DeviceType_DVD)) 396 driveCheck++; 397 398 if ( !RTStrICmp(pszType, "hdd") 399 && (saDeviceTypes[i] == DeviceType_HardDisk)) 400 driveCheck++; 401 402 if ( !RTStrICmp(pszType, "fdd") 403 && (saDeviceTypes[i] == DeviceType_Floppy)) 404 driveCheck++; 405 } 406 if (!driveCheck) 407 { 408 errorArgument("The Attachment is not supported by the Storage Controller: '%s'", pszCtl); 422 ULONG driveCheck = 0; 423 for (size_t i = 0; i < saDeviceTypes.size(); ++ i) 424 if (saDeviceTypes[i] == devTypeRequested) 425 driveCheck++; 426 if (!driveCheck) 427 throw Utf8StrFmt("The given attachment is not supported by the storage controller '%s'", pszCtl); 428 } 429 else 409 430 goto leave; 410 } 411 } 412 else 413 goto leave; 414 } 415 416 if (!RTStrICmp(pszType, "dvddrive")) 417 { 418 ComPtr<IMedium> dvdMedium; 419 420 if (!fRunTime) 421 { 422 ComPtr<IMediumAttachment> mediumAttachement; 423 424 /* check if there is a dvd drive at the given location, if not attach one */ 425 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, 426 device, 427 mediumAttachement.asOutParam()); 428 if (SUCCEEDED(rc)) 429 { 430 DeviceType_T deviceType; 431 mediumAttachement->COMGETTER(Type)(&deviceType); 432 433 if (deviceType != DeviceType_DVD) 434 { 435 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 436 rc = machine->AttachDevice(Bstr(pszCtl).raw(), port, 437 device, DeviceType_DVD, NULL); 438 } 439 } 440 else 441 { 442 rc = machine->AttachDevice(Bstr(pszCtl).raw(), port, 443 device, DeviceType_DVD, NULL); 444 } 445 } 446 447 /* Attach/Detach the dvd medium now */ 448 do 449 { 450 /* host drive? */ 451 if (!RTStrNICmp(pszMedium, "host:", 5)) 452 { 453 ComPtr<IHost> host; 454 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam())); 431 } 432 433 // find the medium given 434 /* host drive? */ 435 if (!RTStrNICmp(pszMedium, "host:", 5)) 436 { 437 ComPtr<IHost> host; 438 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam())); 439 440 if (devTypeRequested == DeviceType_DVD) 441 { 455 442 rc = host->FindHostDVDDrive(Bstr(pszMedium + 5).raw(), 456 dvdMedium.asOutParam());457 if (! dvdMedium)443 pMedium2Mount.asOutParam()); 444 if (!pMedium2Mount) 458 445 { 459 446 /* 2nd try: try with the real name, important on Linux+libhal */ 460 447 char szPathReal[RTPATH_MAX]; 461 448 if (RT_FAILURE(RTPathReal(pszMedium + 5, szPathReal, sizeof(szPathReal)))) 449 throw Utf8StrFmt("Invalid host DVD drive name \"%s\"", pszMedium + 5); 450 rc = host->FindHostDVDDrive(Bstr(szPathReal).raw(), 451 pMedium2Mount.asOutParam()); 452 if (!pMedium2Mount) 453 throw Utf8StrFmt("Invalid host DVD drive name \"%s\"", pszMedium + 5); 454 } 455 } 456 else 457 { 458 // floppy 459 rc = host->FindHostFloppyDrive(Bstr(pszMedium + 5).raw(), 460 pMedium2Mount.asOutParam()); 461 if (!pMedium2Mount) 462 throw Utf8StrFmt("Invalid host floppy drive name \"%s\"", pszMedium + 5); 463 } 464 } 465 else if (!RTStrICmp(pszMedium, "iSCSI")) 466 { 467 /* check for required options */ 468 if (bstrServer.isEmpty() || bstrTarget.isEmpty()) 469 throw Utf8StrFmt("Parameters --server and --target are required for iSCSI media"); 470 471 /** @todo move the location stuff to Main, which can use pfnComposeName 472 * from the disk backends to construct the location properly. Also do 473 * not use slashes to separate the parts, as otherwise only the last 474 * element containing information will be shown. */ 475 Bstr bstrISCSIMedium; 476 if ( bstrLun.isEmpty() 477 || (bstrLun == "0") 478 || (bstrLun == "enc0") 479 ) 480 bstrISCSIMedium = BstrFmt("%ls|%ls", bstrServer.raw(), bstrTarget.raw()); 481 else 482 bstrISCSIMedium = BstrFmt("%ls|%ls|%ls", bstrServer.raw(), bstrTarget.raw(), bstrLun.raw()); 483 484 CHECK_ERROR(a->virtualBox, CreateHardDisk(Bstr("iSCSI").raw(), 485 bstrISCSIMedium.raw(), 486 pMedium2Mount.asOutParam())); 487 if (FAILED(rc)) goto leave; 488 if (!bstrPort.isEmpty()) 489 bstrServer = BstrFmt("%ls:%ls", bstrServer.raw(), bstrPort.raw()); 490 491 // set the other iSCSI parameters as properties 492 com::SafeArray <BSTR> names; 493 com::SafeArray <BSTR> values; 494 Bstr("TargetAddress").detachTo(names.appendedRaw()); 495 bstrServer.detachTo(values.appendedRaw()); 496 Bstr("TargetName").detachTo(names.appendedRaw()); 497 bstrTarget.detachTo(values.appendedRaw()); 498 499 if (!bstrLun.isEmpty()) 500 { 501 Bstr("LUN").detachTo(names.appendedRaw()); 502 bstrLun.detachTo(values.appendedRaw()); 503 } 504 if (!bstrUsername.isEmpty()) 505 { 506 Bstr("InitiatorUsername").detachTo(names.appendedRaw()); 507 bstrUsername.detachTo(values.appendedRaw()); 508 } 509 if (!bstrPassword.isEmpty()) 510 { 511 Bstr("InitiatorSecret").detachTo(names.appendedRaw()); 512 bstrPassword.detachTo(values.appendedRaw()); 513 } 514 515 /// @todo add --initiator option - until that happens rely on the 516 // defaults of the iSCSI initiator code. Setting it to a constant 517 // value does more harm than good, as the initiator name is supposed 518 // to identify a particular initiator uniquely. 519 // Bstr("InitiatorName").detachTo(names.appendedRaw()); 520 // Bstr("iqn.2008-04.com.sun.virtualbox.initiator").detachTo(values.appendedRaw()); 521 522 /// @todo add --targetName and --targetPassword options 523 524 if (fIntNet) 525 { 526 Bstr("HostIPStack").detachTo(names.appendedRaw()); 527 Bstr("0").detachTo(values.appendedRaw()); 528 } 529 530 CHECK_ERROR(pMedium2Mount, SetProperties(ComSafeArrayAsInParam(names), 531 ComSafeArrayAsInParam(values))); 532 if (FAILED(rc)) goto leave; 533 Bstr guid; 534 CHECK_ERROR(pMedium2Mount, COMGETTER(Id)(guid.asOutParam())); 535 if (FAILED(rc)) goto leave; 536 RTPrintf("iSCSI disk created. UUID: %s\n", Utf8Str(guid).c_str()); 537 } 538 else 539 { 540 Bstr bstrMedium(pszMedium); 541 if (bstrMedium.isEmpty()) 542 throw Utf8Str("Missing --medium argument"); 543 544 rc = a->virtualBox->FindMedium(bstrMedium.raw(), 545 devTypeRequested, 546 pMedium2Mount.asOutParam()); 547 if (FAILED(rc) || !pMedium2Mount) 548 { 549 /* not registered, do that on the fly */ 550 CHECK_ERROR(a->virtualBox, 551 OpenMedium(bstrMedium.raw(), 552 devTypeRequested, 553 AccessMode_ReadWrite, 554 pMedium2Mount.asOutParam())); 555 } 556 if (!pMedium2Mount) 557 throw Utf8StrFmt("Invalid UUID or filename \"%s\"", pszMedium); 558 } 559 560 switch (devTypeRequested) 561 { 562 case DeviceType_DVD: 563 case DeviceType_Floppy: 564 { 565 if (!fRunTime) 566 { 567 ComPtr<IMediumAttachment> mediumAttachment; 568 // check if there is a dvd/floppy drive at the given location, if not attach one first 569 rc = machine->GetMediumAttachment(Bstr(pszCtl).raw(), 570 port, 571 device, 572 mediumAttachment.asOutParam()); 573 if (SUCCEEDED(rc)) 462 574 { 463 errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5); 464 rc = E_FAIL; 465 break; 575 DeviceType_T deviceType; 576 mediumAttachment->COMGETTER(Type)(&deviceType); 577 if (deviceType != devTypeRequested) 578 { 579 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 580 rc = machine->AttachDevice(Bstr(pszCtl).raw(), 581 port, 582 device, 583 devTypeRequested, // DeviceType_DVD or DeviceType_Floppy 584 NULL); 585 } 466 586 } 467 rc = host->FindHostDVDDrive(Bstr(szPathReal).raw(), 468 dvdMedium.asOutParam()); 469 if (!dvdMedium) 587 else 470 588 { 471 errorArgument("Invalid host DVD drive name \"%s\"", pszMedium + 5); 472 rc = E_FAIL; 473 break; 589 rc = machine->AttachDevice(Bstr(pszCtl).raw(), 590 port, 591 device, 592 devTypeRequested, // DeviceType_DVD or DeviceType_Floppy 593 NULL); 474 594 } 475 595 } 476 } 477 else 478 { 479 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 480 DeviceType_DVD, 481 dvdMedium.asOutParam()); 482 if (FAILED(rc) || !dvdMedium) 596 597 if (pMedium2Mount) 483 598 { 484 /* not registered, do that on the fly */ 485 Bstr emptyUUID; 486 CHECK_ERROR(a->virtualBox, 487 OpenMedium(Bstr(pszMedium).raw(), 488 DeviceType_DVD, 489 AccessMode_ReadWrite, 490 dvdMedium.asOutParam())); 599 CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(), 600 port, 601 device, 602 pMedium2Mount, 603 fForceUnmount)); 491 604 } 492 if (!dvdMedium) 605 } // end DeviceType_DVD or DeviceType_Floppy: 606 break; 607 608 case DeviceType_HardDisk: 609 { 610 if (fRunTime) 611 throw Utf8Str("Hard disk attachments cannot be changed while the VM is running"); 612 613 // if there is anything attached at the given location, remove it 614 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 615 CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), 616 port, 617 device, 618 DeviceType_HardDisk, 619 pMedium2Mount)); 620 } 621 break; 622 } 623 624 // set medium type, if so desired 625 if (pMedium2Mount && mediumType != MediumType_Normal) 626 { 627 CHECK_ERROR(pMedium2Mount, COMSETTER(Type)(mediumType)); 628 } 629 630 if (!bstrComment.isEmpty()) 631 { 632 CHECK_ERROR(pMedium2Mount, COMSETTER(Description)(bstrComment.raw())); 633 } 634 } 635 636 if ( pszPassThrough 637 && (SUCCEEDED(rc))) 638 { 639 ComPtr<IMediumAttachment> mattach; 640 CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port, 641 device, mattach.asOutParam())); 642 643 if (SUCCEEDED(rc)) 644 { 645 if (!RTStrICmp(pszPassThrough, "on")) 646 { 647 CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(), 648 port, device, TRUE)); 649 } 650 else if (!RTStrICmp(pszPassThrough, "off")) 651 { 652 CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(), 653 port, device, FALSE)); 654 } 655 else 656 throw Utf8StrFmt("Invalid --passthrough argument '%s'", pszPassThrough); 657 } 658 else 659 throw Utf8StrFmt("Couldn't find the controller attachment for the controller '%s'\n", pszCtl); 660 } 661 662 if ( pszBandwidthGroup 663 && !fRunTime 664 && SUCCEEDED(rc)) 665 { 666 667 if (!RTStrICmp(pszBandwidthGroup, "none")) 668 { 669 /* Just remove the bandwidth gorup. */ 670 CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(), 671 port, device, NULL)); 672 } 673 else 674 { 675 ComPtr<IBandwidthControl> bwCtrl; 676 ComPtr<IBandwidthGroup> bwGroup; 677 678 CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam())); 679 680 if (SUCCEEDED(rc)) 681 { 682 CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(pszBandwidthGroup).raw(), bwGroup.asOutParam())); 683 if (SUCCEEDED(rc)) 493 684 { 494 errorArgument("Invalid UUID or filename \"%s\"", pszMedium); 495 rc = E_FAIL; 496 break; 685 CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(), 686 port, device, bwGroup)); 497 687 } 498 688 } 499 } while (0); 500 501 if (dvdMedium) 502 { 503 CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(), port, 504 device, dvdMedium, 505 fForceUnmount)); 506 } 507 } 508 else if ( !RTStrICmp(pszType, "hdd") 509 && !fRunTime) 510 { 511 ComPtr<IMediumAttachment> mediumAttachement; 512 513 /* if there is anything attached at the given location, remove it */ 514 machine->DetachDevice(Bstr(pszCtl).raw(), port, device); 515 516 /* first guess is that it's a UUID */ 517 ComPtr<IMedium> hardDisk; 518 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 519 DeviceType_HardDisk, 520 hardDisk.asOutParam()); 521 522 /* not successful? Then it must be a filename */ 523 if (!hardDisk) 524 { 525 /* open the new hard disk object */ 526 CHECK_ERROR(a->virtualBox, 527 OpenMedium(Bstr(pszMedium).raw(), 528 DeviceType_HardDisk, 529 AccessMode_ReadWrite, 530 hardDisk.asOutParam())); 531 } 532 533 if (hardDisk) 534 { 535 CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, 536 device, DeviceType_HardDisk, 537 hardDisk)); 538 } 539 else 540 { 541 errorArgument("Invalid UUID or filename \"%s\"", pszMedium); 542 rc = E_FAIL; 543 } 544 } 545 else if (!RTStrICmp(pszType, "fdd")) 546 { 547 Bstr uuid; 548 ComPtr<IMedium> floppyMedium; 549 ComPtr<IMediumAttachment> floppyAttachment; 550 machine->GetMediumAttachment(Bstr(pszCtl).raw(), port, device, 551 floppyAttachment.asOutParam()); 552 553 if ( !fRunTime 554 && !floppyAttachment) 555 CHECK_ERROR(machine, AttachDevice(Bstr(pszCtl).raw(), port, 556 device, DeviceType_Floppy, 557 NULL)); 558 559 /* host drive? */ 560 if (!RTStrNICmp(pszMedium, "host:", 5)) 561 { 562 ComPtr<IHost> host; 563 564 CHECK_ERROR(a->virtualBox, COMGETTER(Host)(host.asOutParam())); 565 rc = host->FindHostFloppyDrive(Bstr(pszMedium + 5).raw(), 566 floppyMedium.asOutParam()); 567 if (!floppyMedium) 568 { 569 errorArgument("Invalid host floppy drive name \"%s\"", pszMedium + 5); 570 rc = E_FAIL; 571 } 572 } 573 else 574 { 575 /* first assume it's a UUID */ 576 rc = a->virtualBox->FindMedium(Bstr(pszMedium).raw(), 577 DeviceType_Floppy, 578 floppyMedium.asOutParam()); 579 if (FAILED(rc) || !floppyMedium) 580 { 581 /* not registered, do that on the fly */ 582 Bstr emptyUUID; 583 CHECK_ERROR(a->virtualBox, 584 OpenMedium(Bstr(pszMedium).raw(), 585 DeviceType_Floppy, 586 AccessMode_ReadWrite, 587 floppyMedium.asOutParam())); 588 } 589 590 if (!floppyMedium) 591 { 592 errorArgument("Invalid UUID or filename \"%s\"", pszMedium); 593 rc = E_FAIL; 594 } 595 } 596 597 if (floppyMedium) 598 { 599 CHECK_ERROR(machine, MountMedium(Bstr(pszCtl).raw(), port, 600 device, 601 floppyMedium, 602 fForceUnmount)); 603 } 604 } 605 else 606 { 607 errorArgument("Invalid --type argument '%s'", pszType); 608 rc = E_FAIL; 609 } 689 } 690 } 691 692 /* commit changes */ 693 if (SUCCEEDED(rc)) 694 CHECK_ERROR(machine, SaveSettings()); 610 695 } 611 612 if ( pszPassThrough 613 && (SUCCEEDED(rc))) 696 catch (const Utf8Str &strError) 614 697 { 615 ComPtr<IMediumAttachment> mattach; 616 617 CHECK_ERROR(machine, GetMediumAttachment(Bstr(pszCtl).raw(), port, 618 device, mattach.asOutParam())); 619 620 if (SUCCEEDED(rc)) 621 { 622 if (!RTStrICmp(pszPassThrough, "on")) 623 { 624 CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(), 625 port, device, TRUE)); 626 } 627 else if (!RTStrICmp(pszPassThrough, "off")) 628 { 629 CHECK_ERROR(machine, PassthroughDevice(Bstr(pszCtl).raw(), 630 port, device, FALSE)); 631 } 632 else 633 { 634 errorArgument("Invalid --passthrough argument '%s'", pszPassThrough); 635 rc = E_FAIL; 636 } 637 } 638 else 639 { 640 errorArgument("Couldn't find the controller attachment for the controller '%s'\n", pszCtl); 641 rc = E_FAIL; 642 } 698 errorArgument("%s", strError.c_str()); 699 rc = E_FAIL; 643 700 } 644 701 645 if ( pszBandwidthGroup 646 && !fRunTime 647 && SUCCEEDED(rc)) 648 { 649 650 if (!RTStrICmp(pszBandwidthGroup, "none")) 651 { 652 /* Just remove the bandwidth gorup. */ 653 CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(), 654 port, device, NULL)); 655 } 656 else 657 { 658 ComPtr<IBandwidthControl> bwCtrl; 659 ComPtr<IBandwidthGroup> bwGroup; 660 661 CHECK_ERROR(machine, COMGETTER(BandwidthControl)(bwCtrl.asOutParam())); 662 663 if (SUCCEEDED(rc)) 664 { 665 CHECK_ERROR(bwCtrl, GetBandwidthGroup(Bstr(pszBandwidthGroup).raw(), bwGroup.asOutParam())); 666 if (SUCCEEDED(rc)) 667 { 668 CHECK_ERROR(machine, SetBandwidthGroupForDevice(Bstr(pszCtl).raw(), 669 port, device, bwGroup)); 670 } 671 } 672 } 673 } 674 675 /* commit changes */ 676 if (SUCCEEDED(rc)) 677 CHECK_ERROR(machine, SaveSettings()); 678 702 // machine must always be unlocked, even on errors 679 703 leave: 680 /* it's important to always close sessions */681 704 a->session->UnlockMachine(); 682 705
Note:
See TracChangeset
for help on using the changeset viewer.