Changeset 93065 in vbox for trunk/src/VBox/ImageMounter/vboximg-mount
- Timestamp:
- Dec 23, 2021 11:27:42 AM (3 years ago)
- svn:sync-xref-src-repo-rev:
- 149072
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ImageMounter/vboximg-mount/vboximg-mount.cpp
r91840 r93065 121 121 122 122 /* Global variables */ 123 static RTVFSFILE g_hVfsFileDisk ; /** Disk as VFS file handle. */124 static uint32_t g_cbSector; /** Disk sector size. */125 static RTDVM g_hDvmMgr; /** Handle to the volume manager. */126 static char *g_pszDiskUuid; /** UUID of image (if known, otherwise NULL) */127 static PVDINTERFACE g_pVdIfs; /** @todo Remove when VD I/O becomes threadsafe */128 static VDINTERFACETHREADSYNC g_VDIfThreadSync; /** @todo Remove when VD I/O becomes threadsafe */129 static RTCRITSECT g_vdioLock; /** @todo Remove when VD I/O becomes threadsafe */130 static char *g_pszImageName ;/** Base filename for current VD image */131 static char *g_pszImagePath; /** Full path to current VD image */132 static char *g_pszBaseImagePath; /** Base image known after parsing */133 static char *g_pszBaseImageName; /** Base image known after parsing */134 static uint32_t g_cImages; /** Number of images in diff chain */123 static RTVFSFILE g_hVfsFileDisk = NIL_RTVFSFILE; /** Disk as VFS file handle. */ 124 static uint32_t g_cbSector; /** Disk sector size. */ 125 static RTDVM g_hDvmMgr; /** Handle to the volume manager. */ 126 static char *g_pszDiskUuid; /** UUID of image (if known, otherwise NULL) */ 127 static PVDINTERFACE g_pVdIfs; /** @todo Remove when VD I/O becomes threadsafe */ 128 static VDINTERFACETHREADSYNC g_VDIfThreadSync; /** @todo Remove when VD I/O becomes threadsafe */ 129 static RTCRITSECT g_vdioLock; /** @todo Remove when VD I/O becomes threadsafe */ 130 static char *g_pszImageName = NULL; /** Base filename for current VD image */ 131 static char *g_pszImagePath; /** Full path to current VD image */ 132 static char *g_pszBaseImagePath; /** Base image known after parsing */ 133 static char *g_pszBaseImageName; /** Base image known after parsing */ 134 static uint32_t g_cImages; /** Number of images in diff chain */ 135 135 136 136 /** Pointer to the detected volumes. */ … … 306 306 { 307 307 /* Skip the root specifier and start with the component coming afterwards. */ 308 if (!RTStrCmp(pPathSplit->apszComps[1], "vhdd")) 308 if ( !RTStrCmp(pPathSplit->apszComps[1], "vhdd") 309 && g_hVfsFileDisk != NIL_RTVFSFILE) 309 310 *phVfsObj = RTVfsObjFromFile(g_hVfsFileDisk); 310 311 else if (!RTStrNCmp(pPathSplit->apszComps[1], "vol", sizeof("vol") - 1)) … … 314 315 int rcIprt = RTStrToUInt32Full(&pPathSplit->apszComps[1][3], 10, &idxVol); 315 316 if ( rcIprt == VINF_SUCCESS 316 && idxVol < g_cVolumes) 317 && idxVol < g_cVolumes 318 && g_paVolumes[idxVol].hVfsFileVol != NIL_RTVFSFILE) 317 319 *phVfsObj = RTVfsObjFromFile(g_paVolumes[idxVol].hVfsFileVol); 318 320 else … … 471 473 case RTVFSOBJTYPE_FILE: 472 474 { 475 size_t cbRead = 0; 473 476 RTVFSFILE hVfsFile = RTVfsObjToFile(hVfsObj); 474 int rcIprt = RTVfsFileReadAt(hVfsFile, offset, pbBuf, cbBuf, NULL);475 if ( RT_FAILURE(rc))476 rc = -RTErrConvertToErrno(rcIprt);477 else 478 rc = cbBuf;477 int rcIprt = RTVfsFileReadAt(hVfsFile, offset, pbBuf, cbBuf, &cbRead); 478 if (cbRead) 479 rc = cbRead; 480 else if (rcIprt == VINF_EOF) 481 rc = -RTErrConvertToErrno(VERR_EOF); 479 482 RTVfsFileRelease(hVfsFile); 480 483 break; … … 515 518 case RTVFSOBJTYPE_FILE: 516 519 { 520 size_t cbWritten = 0; 517 521 RTVFSFILE hVfsFile = RTVfsObjToFile(hVfsObj); 518 int rcIprt = RTVfsFileWriteAt(hVfsFile, offset, pbBuf, cbBuf, NULL);519 if ( RT_FAILURE(rc))520 rc = -RTErrConvertToErrno(rcIprt);521 else 522 rc = cbBuf;522 int rcIprt = RTVfsFileWriteAt(hVfsFile, offset, pbBuf, cbBuf, &cbWritten); 523 if (cbWritten) 524 rc = cbWritten; 525 else if (rcIprt == VINF_EOF) 526 rc = -RTErrConvertToErrno(VERR_EOF); 523 527 RTVfsFileRelease(hVfsFile); 524 528 break; … … 549 553 stbuf->st_nlink = 2; 550 554 } 551 else if (RTStrNCmp(pszPath + 1, g_pszImageName, strlen(g_pszImageName)) == 0) 555 else if ( g_pszImageName 556 && RTStrNCmp(pszPath + 1, g_pszImageName, strlen(g_pszImageName)) == 0) 552 557 { 553 558 /* When the disk is partitioned, the symbolic link named from `basename` of … … 720 725 pfnFiller(pvBuf, "..", NULL, 0); 721 726 722 /* 723 * Create FUSE FS dir entry that is depicted here (and exposed via stat()) as 724 * a symbolic link back to the resolved path to the VBox virtual disk image, 725 * whose symlink name is basename that path. This is a convenience so anyone 726 * listing the dir can figure out easily what the vhdd FUSE node entry 727 * represents. 728 */ 729 pfnFiller(pvBuf, g_pszImageName, NULL, 0); 730 731 /* 732 * Create entry named "vhdd" denoting the whole disk, which getattr() will describe as a 733 * regular file, and thus will go through the open/release/read/write vectors 734 * to access the VirtualBox image as processed by the IRPT VD API. 735 */ 736 pfnFiller(pvBuf, "vhdd", NULL, 0); 727 if (g_pszImageName) 728 { 729 /* 730 * Create FUSE FS dir entry that is depicted here (and exposed via stat()) as 731 * a symbolic link back to the resolved path to the VBox virtual disk image, 732 * whose symlink name is basename that path. This is a convenience so anyone 733 * listing the dir can figure out easily what the vhdd FUSE node entry 734 * represents. 735 */ 736 pfnFiller(pvBuf, g_pszImageName, NULL, 0); 737 } 738 739 if (g_hVfsFileDisk != NIL_RTVFSFILE) 740 { 741 /* 742 * Create entry named "vhdd" denoting the whole disk, which getattr() will describe as a 743 * regular file, and thus will go through the open/release/read/write vectors 744 * to access the VirtualBox image as processed by the IRPT VD API. 745 */ 746 pfnFiller(pvBuf, "vhdd", NULL, 0); 747 } 737 748 738 749 /* Create entries for the individual volumes. */ … … 740 751 { 741 752 char tmp[64]; 742 RTStrPrintf(tmp, sizeof (tmp), "vol%u", i); 743 pfnFiller(pvBuf, tmp, NULL, 0); 753 if (g_paVolumes[i].hVfsFileVol != NIL_RTVFSFILE) 754 { 755 RTStrPrintf(tmp, sizeof (tmp), "vol%u", i); 756 pfnFiller(pvBuf, tmp, NULL, 0); 757 } 744 758 745 759 if (g_paVolumes[i].hVfsRoot != NIL_RTVFS) … … 922 936 } 923 937 924 int 925 main(int argc, char **argv) 926 { 927 928 int rc = RTR3InitExe(argc, &argv, 0); 929 if (RT_FAILURE(rc)) 930 return RTMsgErrorExitFailure("RTR3InitExe failed, rc=%Rrc\n", rc); 931 932 rc = VDInit(); 933 if (RT_FAILURE(rc)) 934 return RTMsgErrorExitFailure("VDInit failed, rc=%Rrc\n", rc); 935 936 rc = RTFuseLoadLib(); 937 if (RT_FAILURE(rc)) 938 return RTMsgErrorExitFailure("Failed to load the fuse library, rc=%Rrc\n", rc); 939 940 memset(&g_vboximgOps, 0, sizeof(g_vboximgOps)); 941 g_vboximgOps.open = vboximgOp_open; 942 g_vboximgOps.read = vboximgOp_read; 943 g_vboximgOps.write = vboximgOp_write; 944 g_vboximgOps.getattr = vboximgOp_getattr; 945 g_vboximgOps.release = vboximgOp_release; 946 g_vboximgOps.readdir = vboximgOp_readdir; 947 g_vboximgOps.readlink = vboximgOp_readlink; 948 949 struct fuse_args args = FUSE_ARGS_INIT(argc, argv); 950 memset(&g_vboximgOpts, 0, sizeof(g_vboximgOpts)); 951 952 rc = fuse_opt_parse(&args, &g_vboximgOpts, vboximgOptDefs, vboximgOptHandler); 953 if (rc < 0 || argc < 2 || RTStrCmp(argv[1], "-?" ) == 0 || g_vboximgOpts.fBriefUsage) 954 { 955 briefUsage(); 956 return 0; 957 } 958 959 if (g_vboximgOpts.fAllowRoot) 960 fuse_opt_add_arg(&args, "-oallow_root"); 961 962 /* 963 * FUSE doesn't seem to like combining options with one hyphen, as traditional UNIX 964 * command line utilities allow. The following flags, fWideList and fVerboseList, 965 * and their respective option definitions give the appearance of combined opts, 966 * so that -vl, -lv, -wl, -lw options are allowed, since those in particular would 967 * tend to conveniently facilitate some of the most common use cases. 968 */ 969 if (g_vboximgOpts.fWideList) 970 { 971 g_vboximgOpts.fWide = true; 972 g_vboximgOpts.fList = true; 973 } 974 if (g_vboximgOpts.fVerboseList) 975 { 976 g_vboximgOpts.fVerbose = true; 977 g_vboximgOpts.fList = true; 978 } 979 if (g_vboximgOpts.fAllowRoot) 980 fuse_opt_add_arg(&args, "-oallow_root"); 981 938 939 static int vboxImgMntImageSetup(struct fuse_args *args) 940 { 982 941 /* 983 942 * Initialize COM. … … 1031 990 if (g_vboximgOpts.pszImageUuidOrPath) 1032 991 { 992 HRESULT rc; 993 1033 994 /* compiler was too fussy about access mode's data type in conditional expr, so... */ 1034 995 if (g_vboximgOpts.fRW) … … 1040 1001 AccessMode_ReadOnly, false /* forceNewUuid */, pVDiskMedium.asOutParam())); 1041 1002 1042 if (FAILED( rc))1003 if (FAILED(hrc)) 1043 1004 return RTMsgErrorExitFailure("\nCould't find specified VirtualBox base or snapshot disk image:\n%s", 1044 1005 g_vboximgOpts.pszImageUuidOrPath); … … 1115 1076 Bstr pBase64EncodedKeyStore; 1116 1077 1117 rc = pVDiskBaseMedium->GetProperty(Bstr("CRYPT/KeyStore").raw(), pBase64EncodedKeyStore.asOutParam());1118 if (SUCCEEDED( rc) && strlen(CSTR(pBase64EncodedKeyStore)) != 0)1078 hrc = pVDiskBaseMedium->GetProperty(Bstr("CRYPT/KeyStore").raw(), pBase64EncodedKeyStore.asOutParam()); 1079 if (SUCCEEDED(hrc) && strlen(CSTR(pBase64EncodedKeyStore)) != 0) 1119 1080 { 1120 1081 RTPrintf("\nvboximgMount: Encrypted disks not supported in this version\n\n"); … … 1228 1189 /* **************** END IFDEF'D (STUBBED-OUT) CODE ***************** */ 1229 1190 1230 rc = RTCritSectInit(&g_vdioLock);1191 int rc = RTCritSectInit(&g_vdioLock); 1231 1192 if (RT_SUCCESS(rc)) 1232 1193 { … … 1337 1298 RTPrintf("\nvboximg-mount: Going into background...\n"); 1338 1299 1339 rc = fuse_main_real(args .argc, args.argv, &g_vboximgOps, sizeof(g_vboximgOps), NULL);1300 rc = fuse_main_real(args->argc, args->argv, &g_vboximgOps, sizeof(g_vboximgOps), NULL); 1340 1301 1341 1302 int rc2 = RTVfsFileRelease(g_hVfsFileDisk); … … 1345 1306 } 1346 1307 1308 1309 int main(int argc, char **argv) 1310 { 1311 1312 int rc = RTR3InitExe(argc, &argv, 0); 1313 if (RT_FAILURE(rc)) 1314 return RTMsgErrorExitFailure("RTR3InitExe failed, rc=%Rrc\n", rc); 1315 1316 rc = VDInit(); 1317 if (RT_FAILURE(rc)) 1318 return RTMsgErrorExitFailure("VDInit failed, rc=%Rrc\n", rc); 1319 1320 rc = RTFuseLoadLib(); 1321 if (RT_FAILURE(rc)) 1322 return RTMsgErrorExitFailure("Failed to load the fuse library, rc=%Rrc\n", rc); 1323 1324 memset(&g_vboximgOps, 0, sizeof(g_vboximgOps)); 1325 g_vboximgOps.open = vboximgOp_open; 1326 g_vboximgOps.read = vboximgOp_read; 1327 g_vboximgOps.write = vboximgOp_write; 1328 g_vboximgOps.getattr = vboximgOp_getattr; 1329 g_vboximgOps.release = vboximgOp_release; 1330 g_vboximgOps.readdir = vboximgOp_readdir; 1331 g_vboximgOps.readlink = vboximgOp_readlink; 1332 1333 struct fuse_args args = FUSE_ARGS_INIT(argc, argv); 1334 memset(&g_vboximgOpts, 0, sizeof(g_vboximgOpts)); 1335 1336 rc = fuse_opt_parse(&args, &g_vboximgOpts, vboximgOptDefs, vboximgOptHandler); 1337 if (rc < 0 || argc < 2 || RTStrCmp(argv[1], "-?" ) == 0 || g_vboximgOpts.fBriefUsage) 1338 { 1339 briefUsage(); 1340 return 0; 1341 } 1342 1343 if (g_vboximgOpts.fAllowRoot) 1344 fuse_opt_add_arg(&args, "-oallow_root"); 1345 1346 /* 1347 * FUSE doesn't seem to like combining options with one hyphen, as traditional UNIX 1348 * command line utilities allow. The following flags, fWideList and fVerboseList, 1349 * and their respective option definitions give the appearance of combined opts, 1350 * so that -vl, -lv, -wl, -lw options are allowed, since those in particular would 1351 * tend to conveniently facilitate some of the most common use cases. 1352 */ 1353 if (g_vboximgOpts.fWideList) 1354 { 1355 g_vboximgOpts.fWide = true; 1356 g_vboximgOpts.fList = true; 1357 } 1358 if (g_vboximgOpts.fVerboseList) 1359 { 1360 g_vboximgOpts.fVerbose = true; 1361 g_vboximgOpts.fList = true; 1362 } 1363 if (g_vboximgOpts.fAllowRoot) 1364 fuse_opt_add_arg(&args, "-oallow_root"); 1365 1366 if ( !g_vboximgOpts.pszImageUuidOrPath 1367 || !RTVfsChainIsSpec(g_vboximgOpts.pszImageUuidOrPath)) 1368 return vboxImgMntImageSetup(&args); 1369 1370 /* Mount the VFS chain. */ 1371 RTVFSOBJ hVfsObj; 1372 rc = RTVfsChainOpenObj(g_vboximgOpts.pszImageUuidOrPath, RTFILE_O_READWRITE | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, 1373 RTVFSOBJ_F_OPEN_ANY | RTVFSOBJ_F_CREATE_NOTHING | RTPATH_F_ON_LINK, 1374 &hVfsObj, NULL, NULL); 1375 if ( RT_SUCCESS(rc) 1376 && RTVfsObjGetType(hVfsObj) == RTVFSOBJTYPE_VFS) 1377 { 1378 g_paVolumes = (PVBOXIMGMOUNTVOL)RTMemAllocZ(sizeof(*g_paVolumes)); 1379 if (RT_LIKELY(g_paVolumes)) 1380 { 1381 g_cVolumes = 1; 1382 g_paVolumes[0].hVfsRoot = RTVfsObjToVfs(hVfsObj); 1383 g_paVolumes[0].hVfsFileVol = NIL_RTVFSFILE; 1384 RTVfsObjRelease(hVfsObj); 1385 1386 rc = RTVfsOpenRoot(g_paVolumes[0].hVfsRoot, &g_paVolumes[0].hVfsDirRoot); 1387 if (RT_SUCCESS(rc)) 1388 { 1389 /* 1390 * Hand control over to libfuse. 1391 */ 1392 if (VERBOSE) 1393 RTPrintf("\nvboximg-mount: Going into background...\n"); 1394 1395 rc = fuse_main_real(args.argc, args.argv, &g_vboximgOps, sizeof(g_vboximgOps), NULL); 1396 RTVfsDirRelease(g_paVolumes[0].hVfsDirRoot); 1397 RTVfsRelease(g_paVolumes[0].hVfsRoot); 1398 } 1399 1400 RTMemFree(g_paVolumes); 1401 g_paVolumes = NULL; 1402 g_cVolumes = 0; 1403 } 1404 else 1405 rc = VERR_NO_MEMORY; 1406 1407 RTVfsObjRelease(hVfsObj); 1408 } 1409 1410 return rc; 1411 } 1412
Note:
See TracChangeset
for help on using the changeset viewer.