VirtualBox

source: vbox/trunk/src/VBox/Frontends/VBoxManage/VBoxManageDisk.cpp@ 15492

Last change on this file since 15492 was 15492, checked in by vboxsync, 16 years ago

VBoxManage: split off various disk handling commands.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.5 KB
Line 
1/* $Id: VBoxManageDisk.cpp 15492 2008-12-15 10:36:07Z vboxsync $ */
2/** @file
3 * VBoxManage - The disk delated commands.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef VBOX_ONLY_DOCS
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#include <VBox/com/com.h>
28#include <VBox/com/array.h>
29#include <VBox/com/ErrorInfo.h>
30#include <VBox/com/VirtualBox.h>
31
32#include <iprt/asm.h>
33#include <iprt/file.h>
34#include <iprt/stream.h>
35#include <iprt/string.h>
36#include <VBox/log.h>
37#include <VBox/VBoxHDD-new.h>
38
39#include "VBoxManage.h"
40using namespace com;
41
42
43// funcs
44///////////////////////////////////////////////////////////////////////////////
45
46
47static DECLCALLBACK(void) handleVDError(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
48{
49 RTPrintf("ERROR: ");
50 RTPrintfV(pszFormat, va);
51 RTPrintf("\n");
52 RTPrintf("Error code %Rrc at %s(%u) in function %s\n", rc, RT_SRC_POS_ARGS);
53}
54
55
56int handleCreateHardDisk(int argc, char *argv[],
57 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
58{
59 HRESULT rc;
60 Bstr filename;
61 uint64_t sizeMB = 0;
62 Bstr format = "VDI";
63 bool fStatic = false;
64 Bstr comment;
65 bool fRegister = false;
66 const char *type = "normal";
67
68 /* let's have a closer look at the arguments */
69 for (int i = 0; i < argc; i++)
70 {
71 if (strcmp(argv[i], "-filename") == 0)
72 {
73 if (argc <= i + 1)
74 return errorArgument("Missing argument to '%s'", argv[i]);
75 i++;
76 filename = argv[i];
77 }
78 else if (strcmp(argv[i], "-size") == 0)
79 {
80 if (argc <= i + 1)
81 return errorArgument("Missing argument to '%s'", argv[i]);
82 i++;
83 sizeMB = RTStrToUInt64(argv[i]);
84 }
85 else if (strcmp(argv[i], "-format") == 0)
86 {
87 if (argc <= i + 1)
88 return errorArgument("Missing argument to '%s'", argv[i]);
89 i++;
90 format = argv[i];
91 }
92 else if (strcmp(argv[i], "-static") == 0)
93 {
94 fStatic = true;
95 }
96 else if (strcmp(argv[i], "-comment") == 0)
97 {
98 if (argc <= i + 1)
99 return errorArgument("Missing argument to '%s'", argv[i]);
100 i++;
101 comment = argv[i];
102 }
103 else if (strcmp(argv[i], "-register") == 0)
104 {
105 fRegister = true;
106 }
107 else if (strcmp(argv[i], "-type") == 0)
108 {
109 if (argc <= i + 1)
110 return errorArgument("Missing argument to '%s'", argv[i]);
111 i++;
112 type = argv[i];
113 }
114 else
115 return errorSyntax(USAGE_CREATEHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
116 }
117 /* check the outcome */
118 if (!filename || (sizeMB == 0))
119 return errorSyntax(USAGE_CREATEHD, "Parameters -filename and -size are required");
120
121 if (strcmp(type, "normal") && strcmp(type, "writethrough"))
122 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
123
124 ComPtr<IHardDisk2> hardDisk;
125 CHECK_ERROR(virtualBox, CreateHardDisk2(format, filename, hardDisk.asOutParam()));
126 if (SUCCEEDED(rc) && hardDisk)
127 {
128 /* we will close the hard disk after the storage has been successfully
129 * created unless fRegister is set */
130 bool doClose = false;
131
132 CHECK_ERROR(hardDisk,COMSETTER(Description)(comment));
133 ComPtr<IProgress> progress;
134 if (fStatic)
135 {
136 CHECK_ERROR(hardDisk, CreateFixedStorage(sizeMB, progress.asOutParam()));
137 }
138 else
139 {
140 CHECK_ERROR(hardDisk, CreateDynamicStorage(sizeMB, progress.asOutParam()));
141 }
142 if (SUCCEEDED(rc) && progress)
143 {
144 if (fStatic)
145 showProgress(progress);
146 else
147 CHECK_ERROR(progress, WaitForCompletion(-1));
148 if (SUCCEEDED(rc))
149 {
150 progress->COMGETTER(ResultCode)(&rc);
151 if (FAILED(rc))
152 {
153 com::ProgressErrorInfo info(progress);
154 if (info.isBasicAvailable())
155 RTPrintf("Error: failed to create hard disk. Error message: %lS\n", info.getText().raw());
156 else
157 RTPrintf("Error: failed to create hard disk. No error message available!\n");
158 }
159 else
160 {
161 doClose = !fRegister;
162
163 Guid uuid;
164 CHECK_ERROR(hardDisk, COMGETTER(Id)(uuid.asOutParam()));
165
166 if (strcmp(type, "normal") == 0)
167 {
168 /* nothing required, default */
169 }
170 else if (strcmp(type, "writethrough") == 0)
171 {
172 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
173 }
174
175 RTPrintf("Disk image created. UUID: %s\n", uuid.toString().raw());
176 }
177 }
178 }
179 if (doClose)
180 {
181 CHECK_ERROR(hardDisk, Close());
182 }
183 }
184 return SUCCEEDED(rc) ? 0 : 1;
185}
186
187#if 0 /* disabled until disk shrinking is implemented based on VBoxHDD-new */
188static DECLCALLBACK(int) hardDiskProgressCallback(PVM pVM, unsigned uPercent, void *pvUser)
189{
190 unsigned *pPercent = (unsigned *)pvUser;
191
192 if (*pPercent != uPercent)
193 {
194 *pPercent = uPercent;
195 RTPrintf(".");
196 if ((uPercent % 10) == 0 && uPercent)
197 RTPrintf("%d%%", uPercent);
198 RTStrmFlush(g_pStdOut);
199 }
200
201 return VINF_SUCCESS;
202}
203#endif
204
205
206int handleModifyHardDisk(int argc, char *argv[],
207 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
208{
209 HRESULT rc;
210
211 /* The uuid/filename and a command */
212 if (argc < 2)
213 return errorSyntax(USAGE_MODIFYHD, "Incorrect number of parameters");
214
215 ComPtr<IHardDisk2> hardDisk;
216 Bstr filepath;
217
218 /* first guess is that it's a UUID */
219 Guid uuid(argv[0]);
220 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
221 /* no? then it must be a filename */
222 if (!hardDisk)
223 {
224 filepath = argv[0];
225 CHECK_ERROR(virtualBox, FindHardDisk2(filepath, hardDisk.asOutParam()));
226 }
227
228 /* let's find out which command */
229 if (strcmp(argv[1], "settype") == 0)
230 {
231 /* hard disk must be registered */
232 if (SUCCEEDED(rc) && hardDisk)
233 {
234 char *type = NULL;
235
236 if (argc <= 2)
237 return errorArgument("Missing argument to for settype");
238
239 type = argv[2];
240
241 HardDiskType_T hddType;
242 CHECK_ERROR(hardDisk, COMGETTER(Type)(&hddType));
243
244 if (strcmp(type, "normal") == 0)
245 {
246 if (hddType != HardDiskType_Normal)
247 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
248 }
249 else if (strcmp(type, "writethrough") == 0)
250 {
251 if (hddType != HardDiskType_Writethrough)
252 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
253
254 }
255 else if (strcmp(type, "immutable") == 0)
256 {
257 if (hddType != HardDiskType_Immutable)
258 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
259 }
260 else
261 {
262 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(type).raw());
263 }
264 }
265 else
266 return errorArgument("Hard disk image not registered");
267 }
268 else if (strcmp(argv[1], "compact") == 0)
269 {
270#if 1
271 RTPrintf("Error: Shrink hard disk operation is temporarily unavailable!\n");
272 return 1;
273#else
274 /* the hard disk image might not be registered */
275 if (!hardDisk)
276 {
277 virtualBox->OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam());
278 if (!hardDisk)
279 return errorArgument("Hard disk image not found");
280 }
281
282 Bstr format;
283 hardDisk->COMGETTER(Format)(format.asOutParam());
284 if (format != "VDI")
285 return errorArgument("Invalid hard disk type. The command only works on VDI files\n");
286
287 Bstr fileName;
288 hardDisk->COMGETTER(Location)(fileName.asOutParam());
289
290 /* make sure the object reference is released */
291 hardDisk = NULL;
292
293 unsigned uProcent;
294
295 RTPrintf("Shrinking '%lS': 0%%", fileName.raw());
296 int vrc = VDIShrinkImage(Utf8Str(fileName).raw(), hardDiskProgressCallback, &uProcent);
297 if (RT_FAILURE(vrc))
298 {
299 RTPrintf("Error while shrinking hard disk image: %Rrc\n", vrc);
300 rc = E_FAIL;
301 }
302#endif
303 }
304 else
305 return errorSyntax(USAGE_MODIFYHD, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
306
307 return SUCCEEDED(rc) ? 0 : 1;
308}
309
310int handleCloneHardDisk(int argc, char *argv[],
311 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
312{
313#if 1
314 RTPrintf("Error: Clone hard disk operation is temporarily unavailable!\n");
315 return 1;
316#else
317 /// @todo NEWMEDIA use IHardDisk2::cloneTo/flattenTo (not yet implemented)
318 HRESULT rc;
319
320 /* source hard disk and target path */
321 if (argc != 2)
322 return errorSyntax(USAGE_CLONEHD, "Incorrect number of parameters");
323
324 /* first guess is that it's a UUID */
325 Guid uuid(argv[0]);
326 ComPtr<IHardDisk2> hardDisk;
327 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
328 if (!hardDisk)
329 {
330 /* not successful? Then it must be a filename */
331 CHECK_ERROR(virtualBox, OpenHardDisk2(Bstr(argv[0]), hardDisk.asOutParam()));
332 }
333 if (hardDisk)
334 {
335 ComPtr<IProgress> progress;
336 CHECK_ERROR(hardDisk, CloneToImage(Bstr(argv[1]), hardDisk.asOutParam(), progress.asOutParam()));
337 if (SUCCEEDED(rc))
338 {
339 showProgress(progress);
340 progress->COMGETTER(ResultCode)(&rc);
341 if (FAILED(rc))
342 {
343 com::ProgressErrorInfo info(progress);
344 if (info.isBasicAvailable())
345 {
346 RTPrintf("Error: failed to clone disk image. Error message: %lS\n", info.getText().raw());
347 }
348 else
349 {
350 RTPrintf("Error: failed to clone disk image. No error message available!\n");
351 }
352 }
353 }
354 }
355 return SUCCEEDED(rc) ? 0 : 1;
356#endif
357}
358
359int handleConvertHardDisk(int argc, char **argv)
360{
361 Bstr srcformat;
362 Bstr dstformat;
363 Bstr src;
364 Bstr dst;
365 int vrc;
366 PVBOXHDD pSrcDisk = NULL;
367 PVBOXHDD pDstDisk = NULL;
368
369 /* Parse the arguments. */
370 for (int i = 0; i < argc; i++)
371 {
372 if (strcmp(argv[i], "-srcformat") == 0)
373 {
374 if (argc <= i + 1)
375 {
376 return errorArgument("Missing argument to '%s'", argv[i]);
377 }
378 i++;
379 srcformat = argv[i];
380 }
381 else if (strcmp(argv[i], "-dstformat") == 0)
382 {
383 if (argc <= i + 1)
384 {
385 return errorArgument("Missing argument to '%s'", argv[i]);
386 }
387 i++;
388 dstformat = argv[i];
389 }
390 else if (src.isEmpty())
391 {
392 src = argv[i];
393 }
394 else if (dst.isEmpty())
395 {
396 dst = argv[i];
397 }
398 else
399 {
400 return errorSyntax(USAGE_CONVERTHD, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
401 }
402 }
403
404 if (src.isEmpty())
405 return errorSyntax(USAGE_CONVERTHD, "Mandatory input image parameter missing");
406 if (dst.isEmpty())
407 return errorSyntax(USAGE_CONVERTHD, "Mandatory output image parameter missing");
408
409
410 PVDINTERFACE pVDIfs = NULL;
411 VDINTERFACE vdInterfaceError;
412 VDINTERFACEERROR vdInterfaceErrorCallbacks;
413 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
414 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
415 vdInterfaceErrorCallbacks.pfnError = handleVDError;
416
417 vrc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
418 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);
419 AssertRC(vrc);
420
421 do
422 {
423 /* Try to determine input image format */
424 if (srcformat.isEmpty())
425 {
426 char *pszFormat = NULL;
427 vrc = VDGetFormat(Utf8Str(src).raw(), &pszFormat);
428 if (RT_FAILURE(vrc))
429 {
430 RTPrintf("No file format specified and autodetect failed - please specify format: %Rrc\n", vrc);
431 break;
432 }
433 srcformat = pszFormat;
434 RTStrFree(pszFormat);
435 }
436
437 vrc = VDCreate(pVDIfs, &pSrcDisk);
438 if (RT_FAILURE(vrc))
439 {
440 RTPrintf("Error while creating the source virtual disk container: %Rrc\n", vrc);
441 break;
442 }
443
444 /* Open the input image */
445 vrc = VDOpen(pSrcDisk, Utf8Str(srcformat).raw(), Utf8Str(src).raw(), VD_OPEN_FLAGS_READONLY, NULL);
446 if (RT_FAILURE(vrc))
447 {
448 RTPrintf("Error while opening the source image: %Rrc\n", vrc);
449 break;
450 }
451
452 /* Output format defaults to VDI */
453 if (dstformat.isEmpty())
454 dstformat = "VDI";
455
456 vrc = VDCreate(pVDIfs, &pDstDisk);
457 if (RT_FAILURE(vrc))
458 {
459 RTPrintf("Error while creating the destination virtual disk container: %Rrc\n", vrc);
460 break;
461 }
462
463 uint64_t cbSize = VDGetSize(pSrcDisk, VD_LAST_IMAGE);
464 RTPrintf("Converting image \"%s\" with size %RU64 bytes (%RU64MB)...\n", Utf8Str(src).raw(), cbSize, (cbSize + _1M - 1) / _1M);
465
466 /* Create the output image */
467 vrc = VDCopy(pSrcDisk, VD_LAST_IMAGE, pDstDisk, Utf8Str(dstformat).raw(),
468 Utf8Str(dst).raw(), false, 0, NULL, NULL, NULL);
469 if (RT_FAILURE(vrc))
470 {
471 RTPrintf("Error while copying the image: %Rrc\n", vrc);
472 break;
473 }
474 }
475 while (0);
476 if (pDstDisk)
477 VDCloseAll(pDstDisk);
478 if (pSrcDisk)
479 VDCloseAll(pSrcDisk);
480
481 return RT_SUCCESS(vrc) ? 0 : 1;
482}
483
484
485int handleConvertDDImage(int argc, char *argv[])
486{
487 VDIMAGETYPE enmImgType = VD_IMAGE_TYPE_NORMAL;
488 bool fReadFromStdIn = false;
489 const char *format = NULL;
490 const char *srcfilename = NULL;
491 const char *dstfilename = NULL;
492 const char *filesize = NULL;
493 unsigned uImageFlags = 0; /**< @todo allow creation of non-default image variants */
494 void *pvBuf = NULL;
495
496 for (int i = 0; i < argc; i++)
497 {
498 if (!strcmp(argv[i], "-static"))
499 {
500 enmImgType = VD_IMAGE_TYPE_FIXED;
501 }
502 else if (strcmp(argv[i], "-format") == 0)
503 {
504 if (argc <= i + 1)
505 {
506 return errorArgument("Missing argument to '%s'", argv[i]);
507 }
508 i++;
509 format = argv[i];
510 }
511 else
512 {
513 if (srcfilename)
514 {
515 if (dstfilename)
516 {
517 if (fReadFromStdIn && !filesize)
518 filesize = argv[i];
519 else
520 return errorSyntax(USAGE_CONVERTDD, "Incorrect number of parameters");
521 }
522 else
523 dstfilename = argv[i];
524 }
525 else
526 {
527 srcfilename = argv[i];
528#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
529 fReadFromStdIn = !strcmp(srcfilename, "stdin");
530#endif
531 }
532 }
533 }
534
535 RTPrintf("Converting VDI: from DD image file=\"%s\" to file=\"%s\"...\n",
536 srcfilename, dstfilename);
537
538 int rc = VINF_SUCCESS;
539 PVBOXHDD pDisk = NULL;
540
541 PVDINTERFACE pVDIfs = NULL;
542 VDINTERFACE vdInterfaceError;
543 VDINTERFACEERROR vdInterfaceErrorCallbacks;
544 vdInterfaceErrorCallbacks.cbSize = sizeof(VDINTERFACEERROR);
545 vdInterfaceErrorCallbacks.enmInterface = VDINTERFACETYPE_ERROR;
546 vdInterfaceErrorCallbacks.pfnError = handleVDError;
547
548 rc = VDInterfaceAdd(&vdInterfaceError, "VBoxManage_IError", VDINTERFACETYPE_ERROR,
549 &vdInterfaceErrorCallbacks, NULL, &pVDIfs);
550 AssertRC(rc);
551
552 /* open raw image file. */
553 RTFILE File;
554 if (fReadFromStdIn)
555 File = 0;
556 else
557 rc = RTFileOpen(&File, srcfilename, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_WRITE);
558 if (RT_FAILURE(rc))
559 {
560 RTPrintf("File=\"%s\" open error: %Rrf\n", srcfilename, rc);
561 goto out;
562 }
563
564 uint64_t cbFile;
565 /* get image size. */
566 if (fReadFromStdIn)
567 cbFile = RTStrToUInt64(filesize);
568 else
569 rc = RTFileGetSize(File, &cbFile);
570 if (RT_FAILURE(rc))
571 {
572 RTPrintf("Error getting image size for file \"%s\": %Rrc\n", srcfilename, rc);
573 goto out;
574 }
575
576 RTPrintf("Creating %s image with size %RU64 bytes (%RU64MB)...\n", (enmImgType == VD_IMAGE_TYPE_FIXED) ? "fixed" : "dynamic", cbFile, (cbFile + _1M - 1) / _1M);
577 char pszComment[256];
578 RTStrPrintf(pszComment, sizeof(pszComment), "Converted image from %s", srcfilename);
579 rc = VDCreate(pVDIfs, &pDisk);
580 if (RT_FAILURE(rc))
581 {
582 RTPrintf("Error while creating the virtual disk container: %Rrc\n", rc);
583 goto out;
584 }
585
586 Assert(RT_MIN(cbFile / 512 / 16 / 63, 16383) -
587 (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383) == 0);
588 PDMMEDIAGEOMETRY PCHS, LCHS;
589 PCHS.cCylinders = (unsigned int)RT_MIN(cbFile / 512 / 16 / 63, 16383);
590 PCHS.cHeads = 16;
591 PCHS.cSectors = 63;
592 LCHS.cCylinders = 0;
593 LCHS.cHeads = 0;
594 LCHS.cSectors = 0;
595 rc = VDCreateBase(pDisk, format, dstfilename, enmImgType, cbFile,
596 uImageFlags, pszComment, &PCHS, &LCHS, NULL,
597 VD_OPEN_FLAGS_NORMAL, NULL, NULL);
598 if (RT_FAILURE(rc))
599 {
600 RTPrintf("Error while creating the disk image \"%s\": %Rrc\n", dstfilename, rc);
601 goto out;
602 }
603
604 size_t cbBuffer;
605 cbBuffer = _1M;
606 pvBuf = RTMemAlloc(cbBuffer);
607 if (!pvBuf)
608 {
609 rc = VERR_NO_MEMORY;
610 RTPrintf("Not enough memory allocating buffers for image \"%s\": %Rrc\n", dstfilename, rc);
611 goto out;
612 }
613
614 uint64_t offFile;
615 offFile = 0;
616 while (offFile < cbFile)
617 {
618 size_t cbRead;
619 size_t cbToRead;
620 cbRead = 0;
621 cbToRead = cbFile - offFile >= (uint64_t)cbBuffer ?
622 cbBuffer : (size_t) (cbFile - offFile);
623 rc = RTFileRead(File, pvBuf, cbToRead, &cbRead);
624 if (RT_FAILURE(rc) || !cbRead)
625 break;
626 rc = VDWrite(pDisk, offFile, pvBuf, cbRead);
627 if (RT_FAILURE(rc))
628 {
629 RTPrintf("Failed to write to disk image \"%s\": %Rrc\n", dstfilename, rc);
630 goto out;
631 }
632 offFile += cbRead;
633 }
634
635out:
636 if (pvBuf)
637 RTMemFree(pvBuf);
638 if (pDisk)
639 VDClose(pDisk, RT_FAILURE(rc));
640 if (File != NIL_RTFILE)
641 RTFileClose(File);
642
643 return RT_FAILURE(rc);
644}
645
646int handleAddiSCSIDisk(int argc, char *argv[],
647 ComPtr <IVirtualBox> aVirtualBox, ComPtr<ISession> aSession)
648{
649 HRESULT rc;
650 Bstr server;
651 Bstr target;
652 Bstr port;
653 Bstr lun;
654 Bstr username;
655 Bstr password;
656 Bstr comment;
657 bool fIntNet = false;
658
659 /* at least server and target */
660 if (argc < 4)
661 return errorSyntax(USAGE_ADDISCSIDISK, "Not enough parameters");
662
663 /* let's have a closer look at the arguments */
664 for (int i = 0; i < argc; i++)
665 {
666 if (strcmp(argv[i], "-server") == 0)
667 {
668 if (argc <= i + 1)
669 return errorArgument("Missing argument to '%s'", argv[i]);
670 i++;
671 server = argv[i];
672 }
673 else if (strcmp(argv[i], "-target") == 0)
674 {
675 if (argc <= i + 1)
676 return errorArgument("Missing argument to '%s'", argv[i]);
677 i++;
678 target = argv[i];
679 }
680 else if (strcmp(argv[i], "-port") == 0)
681 {
682 if (argc <= i + 1)
683 return errorArgument("Missing argument to '%s'", argv[i]);
684 i++;
685 port = argv[i];
686 }
687 else if (strcmp(argv[i], "-lun") == 0)
688 {
689 if (argc <= i + 1)
690 return errorArgument("Missing argument to '%s'", argv[i]);
691 i++;
692 lun = argv[i];
693 }
694 else if (strcmp(argv[i], "-encodedlun") == 0)
695 {
696 if (argc <= i + 1)
697 return errorArgument("Missing argument to '%s'", argv[i]);
698 i++;
699 lun = L"enc";
700 lun = lun + argv[i];
701 }
702 else if (strcmp(argv[i], "-username") == 0)
703 {
704 if (argc <= i + 1)
705 return errorArgument("Missing argument to '%s'", argv[i]);
706 i++;
707 username = argv[i];
708 }
709 else if (strcmp(argv[i], "-password") == 0)
710 {
711 if (argc <= i + 1)
712 return errorArgument("Missing argument to '%s'", argv[i]);
713 i++;
714 password = argv[i];
715 }
716 else if (strcmp(argv[i], "-comment") == 0)
717 {
718 if (argc <= i + 1)
719 return errorArgument("Missing argument to '%s'", argv[i]);
720 i++;
721 comment = argv[i];
722 }
723 else if (strcmp(argv[i], "-intnet") == 0)
724 {
725 i++;
726 fIntNet = true;
727 }
728 else
729 return errorSyntax(USAGE_ADDISCSIDISK, "Invalid parameter '%s'", Utf8Str(argv[i]).raw());
730 }
731
732 /* check for required options */
733 if (!server || !target)
734 return errorSyntax(USAGE_ADDISCSIDISK, "Parameters -server and -target are required");
735
736 do
737 {
738 ComPtr<IHardDisk2> hardDisk;
739 CHECK_ERROR_BREAK (aVirtualBox,
740 CreateHardDisk2(Bstr ("iSCSI"),
741 BstrFmt ("%ls/%ls", server.raw(), target.raw()),
742 hardDisk.asOutParam()));
743 CheckComRCBreakRC (rc);
744
745 if (!comment.isNull())
746 CHECK_ERROR_BREAK(hardDisk, COMSETTER(Description)(comment));
747
748 if (!port.isNull())
749 server = BstrFmt ("%ls:%ls", server.raw(), port.raw());
750
751 com::SafeArray <BSTR> names;
752 com::SafeArray <BSTR> values;
753
754 Bstr ("TargetAddress").detachTo (names.appendedRaw());
755 server.detachTo (values.appendedRaw());
756 Bstr ("TargetName").detachTo (names.appendedRaw());
757 target.detachTo (values.appendedRaw());
758
759 if (!lun.isNull())
760 {
761 Bstr ("LUN").detachTo (names.appendedRaw());
762 lun.detachTo (values.appendedRaw());
763 }
764 if (!username.isNull())
765 {
766 Bstr ("InitiatorUsername").detachTo (names.appendedRaw());
767 username.detachTo (values.appendedRaw());
768 }
769 if (!password.isNull())
770 {
771 Bstr ("InitiatorSecret").detachTo (names.appendedRaw());
772 password.detachTo (values.appendedRaw());
773 }
774
775 /// @todo add -initiator option
776 Bstr ("InitiatorName").detachTo (names.appendedRaw());
777 Bstr ("iqn.2008-04.com.sun.virtualbox.initiator").detachTo (values.appendedRaw());
778
779 /// @todo add -targetName and -targetPassword options
780
781 if (fIntNet)
782 {
783 Bstr ("HostIPStack").detachTo (names.appendedRaw());
784 Bstr ("0").detachTo (values.appendedRaw());
785 }
786
787 CHECK_ERROR_BREAK (hardDisk,
788 SetProperties (ComSafeArrayAsInParam (names),
789 ComSafeArrayAsInParam (values)));
790
791 Guid guid;
792 CHECK_ERROR(hardDisk, COMGETTER(Id)(guid.asOutParam()));
793 RTPrintf("iSCSI disk created. UUID: %s\n", guid.toString().raw());
794 }
795 while (0);
796
797 return SUCCEEDED(rc) ? 0 : 1;
798}
799
800
801int handleShowHardDiskInfo(int argc, char *argv[],
802 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
803{
804 HRESULT rc;
805
806 if (argc != 1)
807 return errorSyntax(USAGE_SHOWHDINFO, "Incorrect number of parameters");
808
809 ComPtr<IHardDisk2> hardDisk;
810 Bstr filepath;
811
812 bool unknown = false;
813
814 /* first guess is that it's a UUID */
815 Guid uuid(argv[0]);
816 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
817 /* no? then it must be a filename */
818 if (FAILED (rc))
819 {
820 filepath = argv[0];
821 rc = virtualBox->FindHardDisk2(filepath, hardDisk.asOutParam());
822 /* no? well, then it's an unkwnown image */
823 if (FAILED (rc))
824 {
825 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
826 if (SUCCEEDED (rc))
827 {
828 unknown = true;
829 }
830 }
831 }
832 do
833 {
834 if (!SUCCEEDED(rc))
835 break;
836
837 hardDisk->COMGETTER(Id)(uuid.asOutParam());
838 RTPrintf("UUID: %s\n", uuid.toString().raw());
839
840 /* check for accessibility */
841 /// @todo NEWMEDIA check accessibility of all parents
842 /// @todo NEWMEDIA print the full state value
843 MediaState_T state;
844 CHECK_ERROR_BREAK (hardDisk, COMGETTER(State)(&state));
845 RTPrintf("Accessible: %s\n", state != MediaState_Inaccessible ? "yes" : "no");
846
847 if (state == MediaState_Inaccessible)
848 {
849 Bstr err;
850 CHECK_ERROR_BREAK (hardDisk, COMGETTER(LastAccessError)(err.asOutParam()));
851 RTPrintf("Access Error: %lS\n", err.raw());
852 }
853
854 Bstr description;
855 hardDisk->COMGETTER(Description)(description.asOutParam());
856 if (description)
857 {
858 RTPrintf("Description: %lS\n", description.raw());
859 }
860
861 ULONG64 logicalSize;
862 hardDisk->COMGETTER(LogicalSize)(&logicalSize);
863 RTPrintf("Logical size: %llu MBytes\n", logicalSize);
864 ULONG64 actualSize;
865 hardDisk->COMGETTER(Size)(&actualSize);
866 RTPrintf("Current size on disk: %llu MBytes\n", actualSize >> 20);
867
868 HardDiskType_T type;
869 hardDisk->COMGETTER(Type)(&type);
870 const char *typeStr = "unknown";
871 switch (type)
872 {
873 case HardDiskType_Normal:
874 typeStr = "normal";
875 break;
876 case HardDiskType_Immutable:
877 typeStr = "immutable";
878 break;
879 case HardDiskType_Writethrough:
880 typeStr = "writethrough";
881 break;
882 }
883 RTPrintf("Type: %s\n", typeStr);
884
885 Bstr format;
886 hardDisk->COMGETTER(Format)(format.asOutParam());
887 RTPrintf("Storage format: %lS\n", format.raw());
888
889 if (!unknown)
890 {
891 com::SafeGUIDArray machineIds;
892 hardDisk->COMGETTER(MachineIds)(ComSafeArrayAsOutParam(machineIds));
893 for (size_t j = 0; j < machineIds.size(); ++ j)
894 {
895 ComPtr<IMachine> machine;
896 CHECK_ERROR(virtualBox, GetMachine(machineIds[j], machine.asOutParam()));
897 ASSERT(machine);
898 Bstr name;
899 machine->COMGETTER(Name)(name.asOutParam());
900 machine->COMGETTER(Id)(uuid.asOutParam());
901 RTPrintf("%s%lS (UUID: %RTuuid)\n",
902 j == 0 ? "In use by VMs: " : " ",
903 name.raw(), &machineIds[j]);
904 }
905 /// @todo NEWMEDIA check usage in snapshots too
906 /// @todo NEWMEDIA also list children and say 'differencing' for
907 /// hard disks with the parent or 'base' otherwise.
908 }
909
910 Bstr loc;
911 hardDisk->COMGETTER(Location)(loc.asOutParam());
912 RTPrintf("Location: %lS\n", loc.raw());
913 }
914 while (0);
915
916 if (unknown)
917 {
918 /* close the unknown hard disk to forget it again */
919 hardDisk->Close();
920 }
921
922 return SUCCEEDED(rc) ? 0 : 1;
923}
924
925int handleOpenMedium(int argc, char *argv[],
926 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
927{
928 HRESULT rc;
929
930 if (argc < 2)
931 return errorSyntax(USAGE_REGISTERIMAGE, "Not enough parameters");
932
933 Bstr filepath(argv[1]);
934
935 if (strcmp(argv[0], "disk") == 0)
936 {
937 const char *type = NULL;
938 /* there can be a type parameter */
939 if ((argc > 2) && (argc != 4))
940 return errorSyntax(USAGE_REGISTERIMAGE, "Incorrect number of parameters");
941 if (argc == 4)
942 {
943 if (strcmp(argv[2], "-type") != 0)
944 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[2]).raw());
945 if ( (strcmp(argv[3], "normal") != 0)
946 && (strcmp(argv[3], "immutable") != 0)
947 && (strcmp(argv[3], "writethrough") != 0))
948 return errorArgument("Invalid hard disk type '%s' specified", Utf8Str(argv[3]).raw());
949 type = argv[3];
950 }
951
952 ComPtr<IHardDisk2> hardDisk;
953 CHECK_ERROR(virtualBox, OpenHardDisk2(filepath, hardDisk.asOutParam()));
954 if (SUCCEEDED(rc) && hardDisk)
955 {
956 /* change the type if requested */
957 if (type)
958 {
959 if (strcmp(type, "normal") == 0)
960 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Normal));
961 else if (strcmp(type, "immutable") == 0)
962 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Immutable));
963 else if (strcmp(type, "writethrough") == 0)
964 CHECK_ERROR(hardDisk, COMSETTER(Type)(HardDiskType_Writethrough));
965 }
966 }
967 }
968 else if (strcmp(argv[0], "dvd") == 0)
969 {
970 ComPtr<IDVDImage2> dvdImage;
971 CHECK_ERROR(virtualBox, OpenDVDImage(filepath, Guid(), dvdImage.asOutParam()));
972 }
973 else if (strcmp(argv[0], "floppy") == 0)
974 {
975 ComPtr<IFloppyImage2> floppyImage;
976 CHECK_ERROR(virtualBox, OpenFloppyImage(filepath, Guid(), floppyImage.asOutParam()));
977 }
978 else
979 return errorSyntax(USAGE_REGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
980
981 return SUCCEEDED(rc) ? 0 : 1;
982}
983
984int handleCloseMedium(int argc, char *argv[],
985 ComPtr<IVirtualBox> virtualBox, ComPtr<ISession> session)
986{
987 HRESULT rc;
988
989 if (argc != 2)
990 return errorSyntax(USAGE_UNREGISTERIMAGE, "Incorrect number of parameters");
991
992 /* first guess is that it's a UUID */
993 Guid uuid(argv[1]);
994
995 if (strcmp(argv[0], "disk") == 0)
996 {
997 ComPtr<IHardDisk2> hardDisk;
998 rc = virtualBox->GetHardDisk2(uuid, hardDisk.asOutParam());
999 /* not a UUID or not registered? Then it must be a filename */
1000 if (!hardDisk)
1001 {
1002 CHECK_ERROR(virtualBox, FindHardDisk2(Bstr(argv[1]), hardDisk.asOutParam()));
1003 }
1004 if (SUCCEEDED(rc) && hardDisk)
1005 {
1006 CHECK_ERROR(hardDisk, Close());
1007 }
1008 }
1009 else
1010 if (strcmp(argv[0], "dvd") == 0)
1011 {
1012 ComPtr<IDVDImage2> dvdImage;
1013 rc = virtualBox->GetDVDImage(uuid, dvdImage.asOutParam());
1014 /* not a UUID or not registered? Then it must be a filename */
1015 if (!dvdImage)
1016 {
1017 CHECK_ERROR(virtualBox, FindDVDImage(Bstr(argv[1]), dvdImage.asOutParam()));
1018 }
1019 if (SUCCEEDED(rc) && dvdImage)
1020 {
1021 CHECK_ERROR(dvdImage, Close());
1022 }
1023 }
1024 else
1025 if (strcmp(argv[0], "floppy") == 0)
1026 {
1027 ComPtr<IFloppyImage2> floppyImage;
1028 rc = virtualBox->GetFloppyImage(uuid, floppyImage.asOutParam());
1029 /* not a UUID or not registered? Then it must be a filename */
1030 if (!floppyImage)
1031 {
1032 CHECK_ERROR(virtualBox, FindFloppyImage(Bstr(argv[1]), floppyImage.asOutParam()));
1033 }
1034 if (SUCCEEDED(rc) && floppyImage)
1035 {
1036 CHECK_ERROR(floppyImage, Close());
1037 }
1038 }
1039 else
1040 return errorSyntax(USAGE_UNREGISTERIMAGE, "Invalid parameter '%s'", Utf8Str(argv[1]).raw());
1041
1042 return SUCCEEDED(rc) ? 0 : 1;
1043}
1044#endif /* !VBOX_ONLY_DOCS */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette