VirtualBox

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

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

Storage/VBoxHDD-new: implement UUID handling in VDCreate. Remove very broken code for handling move/shrink/grow, it would have done more harm than good. Lucky that these cases aren't used yet.

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

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