Changeset 87463 in vbox for trunk/src/VBox/Additions
- Timestamp:
- Jan 28, 2021 3:38:55 PM (4 years ago)
- svn:sync-xref-src-repo-rev:
- 142482
- Location:
- trunk/src/VBox/Additions
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp
r84238 r87463 65 65 # include <sys/mnttab.h> 66 66 # include <sys/vfs.h> 67 RT_C_DECLS_BEGIN /* Only needed for old code.*/68 # include "../../linux/sharedfolders/vbsfmount.h"69 RT_C_DECLS_END70 67 # elif defined(RT_OS_LINUX) 71 68 # include <mntent.h> 72 69 # include <paths.h> 70 # include <sys/utsname.h> 73 71 RT_C_DECLS_BEGIN 74 72 # include "../../linux/sharedfolders/vbsfmount.h" … … 313 311 * @param pszMountPoint The mount point. 314 312 * @param pszShareName Unused. 315 * @param pOpts For getting the group ID. 316 */ 317 static int vbsvcAutoMountPrepareMountPointOld(const char *pszMountPoint, const char *pszShareName, vbsf_mount_opts *pOpts) 318 { 319 AssertPtrReturn(pOpts, VERR_INVALID_PARAMETER); 313 * @param gidGroup The group ID. 314 */ 315 static int vbsvcAutoMountPrepareMountPointOld(const char *pszMountPoint, const char *pszShareName, RTGID gidGroup) 316 { 320 317 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER); 321 318 AssertPtrReturn(pszShareName, VERR_INVALID_PARAMETER); 319 320 /** @todo r=bird: There is no reason why gidGroup should have write access? 321 * Seriously, what kind of non-sense is this? */ 322 322 323 323 RTFMODE fMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG; /* Owner (=root) and the group (=vboxsf) have full access. */ … … 325 325 if (RT_SUCCESS(rc)) 326 326 { 327 rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);327 rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, gidGroup, RTPATH_F_ON_LINK); 328 328 if (RT_SUCCESS(rc)) 329 329 { … … 374 374 } 375 375 376 struct vbsf_mount_opts Opts = 377 { 378 -1, /* ttl */ 379 -1, /* msDirCacheTTL */ 380 -1, /* msInodeTTL */ 381 0, /* cMaxIoPages */ 382 0, /* cbDirBuf */ 383 kVbsfCacheMode_Default, 384 0, /* uid */ 385 (int)grp_vboxsf->gr_gid, /* gid */ 386 0770, /* dmode, owner and group "vboxsf" have full access */ 387 0770, /* fmode, owner and group "vboxsf" have full access */ 388 0, /* dmask */ 389 0, /* fmask */ 390 0, /* ronly */ 391 0, /* sloppy */ 392 0, /* noexec */ 393 0, /* nodev */ 394 0, /* nosuid */ 395 0, /* remount */ 396 "\0", /* nls_name */ 397 NULL, /* convertcp */ 398 }; 399 400 int rc = vbsvcAutoMountPrepareMountPointOld(pszMountPoint, pszShareName, &Opts); 376 int rc = vbsvcAutoMountPrepareMountPointOld(pszMountPoint, pszShareName, grp_vboxsf->gr_gid); 401 377 if (RT_SUCCESS(rc)) 402 378 { 403 379 # ifdef RT_OS_SOLARIS 404 int fFlags = 0; 405 if (Opts.ronly) 406 fFlags |= MS_RDONLY; 380 int const fFlags = MS_OPTIONSTR; 407 381 char szOptBuf[MAX_MNTOPT_STR] = { '\0', }; 408 RTStrPrintf(szOptBuf, sizeof(szOptBuf), "uid=%d,gid=%d,dmode=%0o,fmode=%0o,dmask=%0o,fmask=%0o", 409 Opts.uid, Opts.gid, Opts.dmode, Opts.fmode, Opts.dmask, Opts.fmask); 382 RTStrPrintf(szOptBuf, sizeof(szOptBuf), "uid=0,gid=%d,dmode=0770,fmode=0770,dmask=0000,fmask=0000", grp_vboxsf->gr_gid); 410 383 int r = mount(pszShareName, 411 384 pszMountPoint, 412 fFlags | MS_OPTIONSTR,385 fFlags, 413 386 "vboxfs", 414 387 NULL, /* char *dataptr */ … … 423 396 424 397 # else /* RT_OS_LINUX */ 425 unsigned long fFlags = MS_NODEV; 426 427 /*const char *szOptions = { "rw" }; - ??? */ 428 struct vbsf_mount_info_new mntinf; 429 RT_ZERO(mntinf); 430 431 mntinf.nullchar = '\0'; 432 mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0; 433 mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1; 434 mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2; 435 mntinf.length = sizeof(mntinf); 436 437 mntinf.uid = Opts.uid; 438 mntinf.gid = Opts.gid; 439 mntinf.ttl = Opts.ttl; 440 mntinf.dmode = Opts.dmode; 441 mntinf.fmode = Opts.fmode; 442 mntinf.dmask = Opts.dmask; 443 mntinf.fmask = Opts.fmask; 444 mntinf.cMaxIoPages = Opts.cMaxIoPages; 445 mntinf.szTag[0] = '\0'; 446 447 strcpy(mntinf.name, pszShareName); 448 strcpy(mntinf.nls_name, "\0"); 398 struct utsname uts; 399 AssertStmt(uname(&uts) != -1, strcpy(uts.release, "4.4.0")); 400 401 unsigned long const fFlags = MS_NODEV; 402 char szOpts[MAX_MNTOPT_STR] = { '\0' }; 403 ssize_t cchOpts = RTStrPrintf2(szOpts, sizeof(szOpts), "uid=0,gid=%d,dmode=0770,fmode=0770,dmask=0000,fmask=0000", 404 grp_vboxsf->gr_gid); 405 if (cchOpts > 0 && RTStrVersionCompare(uts.release, "2.6.0") < 0) 406 cchOpts = RTStrPrintf2(&szOpts[cchOpts], sizeof(szOpts) - cchOpts, ",sf_name=%s", pszShareName); 407 if (cchOpts <= 0) 408 { 409 VGSvcError("vbsvcAutomounterMountIt: szOpts overflow! %zd (share %s)\n", cchOpts, pszShareName); 410 return VERR_BUFFER_OVERFLOW; 411 } 449 412 450 413 int r = mount(pszShareName, … … 452 415 "vboxsf", 453 416 fFlags, 454 &mntinf);417 szOpts); 455 418 if (r == 0) 456 419 { 457 420 VGSvcVerbose(0, "vbsvcAutoMountWorker: Shared folder '%s' was mounted to '%s'\n", pszShareName, pszMountPoint); 458 421 459 r = vbsfmount_complete(pszShareName, pszMountPoint, fFlags, &Opts);422 r = vbsfmount_complete(pszShareName, pszMountPoint, fFlags, szOpts); 460 423 switch (r) 461 424 { … … 463 426 errno = 0; /* Clear all errors/warnings. */ 464 427 break; 465 466 428 case 1: 467 VGSvcError("vbsvcAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", 468 strerror(errno)); 429 VGSvcError("vbsvcAutoMountWorker: Could not update mount table (malloc failure)\n"); 469 430 break; 470 471 431 case 2: 472 432 VGSvcError("vbsvcAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno)); 473 433 break; 474 475 434 case 3: 476 435 /* VGSvcError("vbsvcAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */ 477 436 errno = 0; 478 437 break; 479 480 438 default: 481 439 VGSvcError("vbsvcAutoMountWorker: Unknown error while completing mount operation: %d\n", r); … … 485 443 else /* r == -1, we got some error in errno. */ 486 444 { 487 if (errno == EPROTO) 488 { 489 VGSvcVerbose(3, "vbsvcAutoMountWorker: Messed up share name, re-trying ...\n"); 490 491 /** @todo r=bird: What on earth is going on here????? Why can't you 492 * strcpy(mntinf.name, pszShareName) to fix it again? */ 493 494 /* Sometimes the mount utility messes up the share name. Try to 495 * un-mangle it again. */ 496 char szCWD[RTPATH_MAX]; 497 size_t cchCWD; 498 if (!getcwd(szCWD, sizeof(szCWD))) 499 { 500 VGSvcError("vbsvcAutoMountWorker: Failed to get the current working directory\n"); 501 szCWD[0] = '\0'; 502 } 503 cchCWD = strlen(szCWD); 504 if (!strncmp(pszMountPoint, szCWD, cchCWD)) 505 { 506 while (pszMountPoint[cchCWD] == '/') 507 ++cchCWD; 508 /* We checked before that we have enough space */ 509 strcpy(mntinf.name, pszMountPoint + cchCWD); 510 } 511 r = mount(mntinf.name, pszMountPoint, "vboxsf", fFlags, &mntinf); 512 } 513 if (r == -1) /* Was there some error from one of the tries above? */ 514 { 515 switch (errno) 516 { 517 /* If we get EINVAL here, the system already has mounted the Shared Folder to another 518 * mount point. */ 519 case EINVAL: 520 VGSvcVerbose(0, "vbsvcAutoMountWorker: Shared folder '%s' already is mounted!\n", pszShareName); 521 /* Ignore this error! */ 522 break; 523 case EBUSY: 524 /* Ignore these errors! */ 525 break; 526 527 default: 528 VGSvcError("vbsvcAutoMountWorker: Could not mount shared folder '%s' to '%s': %s (%d)\n", 529 pszShareName, pszMountPoint, strerror(errno), errno); 530 rc = RTErrConvertFromErrno(errno); 531 break; 532 } 445 switch (errno) 446 { 447 /* If we get EINVAL here, the system already has mounted the Shared Folder to another 448 * mount point. */ 449 case EINVAL: 450 VGSvcVerbose(0, "vbsvcAutoMountWorker: Shared folder '%s' is already mounted!\n", pszShareName); 451 /* Ignore this error! */ 452 break; 453 case EBUSY: 454 /* Ignore these errors! */ 455 break; 456 default: 457 VGSvcError("vbsvcAutoMountWorker: Could not mount shared folder '%s' to '%s': %s (%d)\n", 458 pszShareName, pszMountPoint, strerror(errno), errno); 459 rc = RTErrConvertFromErrno(errno); 460 break; 533 461 } 534 462 } … … 1531 1459 * Linux a bit more work... 1532 1460 */ 1533 struct vbsf_mount_info_new MntInfo; 1534 RT_ZERO(MntInfo); 1535 struct vbsf_mount_opts MntOpts; 1536 RT_ZERO(MntOpts); 1537 MntInfo.nullchar = '\0'; 1538 MntInfo.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0; 1539 MntInfo.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1; 1540 MntInfo.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2; 1541 MntInfo.length = sizeof(MntInfo); 1542 MntInfo.ttl = MntOpts.ttl = -1 /*default*/; 1543 MntInfo.msDirCacheTTL= MntOpts.msDirCacheTTL = -1 /*default*/; 1544 MntInfo.msInodeTTL = MntOpts.msInodeTTL = -1 /*default*/; 1545 MntInfo.cMaxIoPages = MntOpts.cMaxIoPages = 0 /*default*/; 1546 MntInfo.cbDirBuf = MntOpts.cbDirBuf = 0 /*default*/; 1547 MntInfo.enmCacheMode = MntOpts.enmCacheMode = kVbsfCacheMode_Default; 1548 MntInfo.uid = MntOpts.uid = 0; 1549 MntInfo.gid = MntOpts.gid = gidMount; 1550 MntInfo.dmode = MntOpts.dmode = 0770; 1551 MntInfo.fmode = MntOpts.fmode = 0770; 1552 MntInfo.dmask = MntOpts.dmask = 0000; 1553 MntInfo.fmask = MntOpts.fmask = 0000; 1554 memcpy(MntInfo.szTag, g_szTag, sizeof(g_szTag)); AssertCompile(sizeof(MntInfo.szTag) >= sizeof(g_szTag)); 1555 rc = RTStrCopy(MntInfo.name, sizeof(MntInfo.name), pEntry->pszName); 1556 if (RT_FAILURE(rc)) 1557 { 1558 VGSvcError("vbsvcAutomounterMountIt: Share name '%s' is too long for the MntInfo.name field!\n", pEntry->pszName); 1559 return rc; 1560 } 1561 1461 struct utsname uts; 1462 AssertStmt(uname(&uts) != -1, strcpy(uts.release, "4.4.0")); 1463 1464 /* Built mount option string. Need st_name for pre 2.6.0 kernels. */ 1465 unsigned long const fFlags = MS_NODEV; 1466 char szOpts[MAX_MNTOPT_STR] = { '\0' }; 1467 ssize_t cchOpts = RTStrPrintf2(szOpts, sizeof(szOpts), 1468 "uid=0,gid=%d,dmode=0770,fmode=0770,dmask=0000,fmask=0000,tag=%s", gidMount, g_szTag); 1469 if (RTStrVersionCompare(uts.release, "2.6.0") < 0 && cchOpts > 0) 1470 cchOpts += RTStrPrintf2(&szOpts[cchOpts], sizeof(szOpts) - cchOpts, ",sf_name=%s", pEntry->pszName); 1471 if (cchOpts <= 0) 1472 { 1473 VGSvcError("vbsvcAutomounterMountIt: szOpts overflow! %zd\n", cchOpts); 1474 return VERR_BUFFER_OVERFLOW; 1475 } 1476 1477 /* Do the mounting. The fallback w/o tag is for the Linux vboxsf fork 1478 which lagged a lot behind when it first appeared in 5.6. */ 1562 1479 errno = 0; 1563 unsigned long fFlags = MS_NODEV; 1564 rc = mount(pEntry->pszName, pEntry->pszActualMountPoint, "vboxsf", fFlags, &MntInfo); 1480 rc = mount(pEntry->pszName, pEntry->pszActualMountPoint, "vboxsf", fFlags, szOpts); 1481 if (rc != 0 && errno == EINVAL && RTStrVersionCompare(uts.release, "5.6.0") >= 0) 1482 { 1483 VGSvcVerbose(2, "vbsvcAutomounterMountIt: mount returned EINVAL, retrying without the tag.\n"); 1484 *strstr(szOpts, ",tag=") = '\0'; 1485 errno = 0; 1486 rc = mount(pEntry->pszName, pEntry->pszActualMountPoint, "vboxsf", fFlags, szOpts); 1487 if (rc == 0) 1488 VGSvcVerbose(0, "vbsvcAutomounterMountIt: Running outdated vboxsf module without support for the 'tag' option?\n"); 1489 } 1565 1490 if (rc == 0) 1566 1491 { … … 1569 1494 1570 1495 errno = 0; 1571 rc = vbsfmount_complete(pEntry->pszName, pEntry->pszActualMountPoint, fFlags, &MntOpts);1496 rc = vbsfmount_complete(pEntry->pszName, pEntry->pszActualMountPoint, fFlags, szOpts); 1572 1497 if (rc != 0) /* Ignorable. /etc/mtab is probably a link to /proc/mounts. */ 1573 1498 VGSvcVerbose(1, "vbsvcAutomounterMountIt: vbsfmount_complete failed: %s (%d/%d)\n", 1574 rc == 1 ? " open_memstream" : rc == 2 ? "setmntent" : rc == 3 ? "addmntent" : "unknown", rc, errno);1499 rc == 1 ? "malloc" : rc == 2 ? "setmntent" : rc == 3 ? "addmntent" : "unknown", rc, errno); 1575 1500 return VINF_SUCCESS; 1576 1501 } 1577 else if (errno == EINVAL) 1502 1503 if (errno == EINVAL) 1578 1504 VGSvcError("vbsvcAutomounterMountIt: Failed to mount '%s' on '%s' because it is probably mounted elsewhere arleady! (%d,%d)\n", 1579 1505 pEntry->pszName, pEntry->pszActualMountPoint, rc, errno); -
trunk/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c
r82968 r87463 44 44 #include <limits.h> 45 45 #include <iconv.h> 46 #include <sys/utsname.h> 47 #include <linux/version.h> 46 48 47 49 #include "vbsfmount.h" 48 50 49 #include <iprt/assert.h> 50 51 51 #include <iprt/assertcompile.h> 52 #include <iprt/param.h> /* PAGE_SIZE (used by MAX_MNTOPT_STR) */ 53 #include <iprt/string.h> 54 55 56 /********************************************************************************************************************************* 57 * Defined Constants And Macros * 58 *********************************************************************************************************************************/ 52 59 #define PANIC_ATTR __attribute ((noreturn, __format__ (__printf__, 1, 2))) 60 61 62 /********************************************************************************************************************************* 63 * Structures and Typedefs * 64 *********************************************************************************************************************************/ 65 struct vbsf_mount_opts 66 { 67 unsigned long fFlags; /**< MS_XXX */ 68 69 /** @name Preformatted option=value or empty if not specified. 70 * Helps eliminate duplicate options as well as simplifying concatting. 71 * @{ */ 72 char szTTL[32]; 73 char szMsDirCacheTTL[32]; 74 char szMsInodeTTL[32]; 75 char szMaxIoPages[32]; 76 char szDirBuf[32]; 77 char szCacheMode[32]; 78 char szUid[32]; 79 char szGid[32]; 80 char szDMode[32]; 81 char szFMode[32]; 82 char szDMask[32]; 83 char szFMask[32]; 84 char szIoCharset[32]; 85 /** @} */ 86 87 bool fSloppy; 88 char *pszConvertCp; 89 }; 90 53 91 54 92 static void PANIC_ATTR … … 134 172 HO_FMASK, 135 173 HO_IOCHARSET, 174 HO_NLS, 136 175 HO_CONVERTCP, 137 176 HO_NOEXEC, … … 164 203 {"cache", HO_CACHE, 1, "cache mode: none, strict (default), read, readwrite"}, 165 204 {"iocharset", HO_IOCHARSET, 1, "i/o charset (default utf8)"}, 205 {"nls", HO_NLS, 1, "i/o charset (default utf8)"}, 166 206 {"convertcp", HO_CONVERTCP, 1, "convert share name from given charset to utf8"}, 167 207 {"dmode", HO_DMODE, 1, "mode of all directories"}, … … 230 270 { 231 271 panic("%.*s requires an argument (i.e. %.*s=<arg>)\n", 232 272 (int)len, s, (int)len, s); 233 273 } 234 274 } … … 237 277 { 238 278 case HO_RW: 239 opts-> ronly = 0;279 opts->fFlags &= ~MS_RDONLY; 240 280 break; 241 281 case HO_RO: 242 opts-> ronly = 1;282 opts->fFlags |= MS_RDONLY; 243 283 break; 244 284 case HO_NOEXEC: 245 opts-> noexec = 1;285 opts->fFlags |= MS_NOEXEC; 246 286 break; 247 287 case HO_EXEC: 248 opts-> noexec = 0;288 opts->fFlags &= ~MS_NOEXEC; 249 289 break; 250 290 case HO_NODEV: 251 opts-> nodev = 1;291 opts->fFlags |= MS_NODEV; 252 292 break; 253 293 case HO_DEV: 254 opts-> nodev = 0;294 opts->fFlags &= ~MS_NODEV; 255 295 break; 256 296 case HO_NOSUID: 257 opts-> nosuid = 1;297 opts->fFlags |= MS_NOSUID; 258 298 break; 259 299 case HO_SUID: 260 opts-> nosuid = 0;300 opts->fFlags &= ~MS_NOSUID; 261 301 break; 262 302 case HO_REMOUNT: 263 opts-> remount = 1;303 opts->fFlags |= MS_REMOUNT; 264 304 break; 265 305 case HO_TTL: 266 opts->ttl = safe_atoi(val, val_len, 10); 306 snprintf(opts->szTTL, sizeof(opts->szTTL), 307 "ttl=%d", safe_atoi(val, val_len, 10)); 267 308 break; 268 309 case HO_DENTRY_TTL: 269 opts->msDirCacheTTL = safe_atoi(val, val_len, 10); 310 snprintf(opts->szMsDirCacheTTL, sizeof(opts->szMsDirCacheTTL), 311 "dcachettl=%d", safe_atoi(val, val_len, 10)); 270 312 break; 271 313 case HO_INODE_TTL: 272 opts->msInodeTTL = safe_atoi(val, val_len, 10); 314 snprintf(opts->szMsInodeTTL, sizeof(opts->szMsInodeTTL), 315 "inodettl=%d", safe_atoi(val, val_len, 10)); 273 316 break; 274 317 case HO_MAX_IO_PAGES: 275 opts->cMaxIoPages = safe_atoiu(val, val_len, 10); 318 snprintf(opts->szMaxIoPages, sizeof(opts->szMaxIoPages), 319 "maxiopages=%d", safe_atoiu(val, val_len, 10)); 276 320 break; 277 321 case HO_DIR_BUF: 278 opts->cbDirBuf = safe_atoiu(val, val_len, 10); 322 snprintf(opts->szDirBuf, sizeof(opts->szDirBuf), 323 "dirbuf=%d", safe_atoiu(val, val_len, 10)); 279 324 break; 280 325 case HO_CACHE: 281 326 #define IS_EQUAL(a_sz) (val_len == sizeof(a_sz) - 1U && strncmp(val, a_sz, sizeof(a_sz) - 1U) == 0) 282 327 if (IS_EQUAL("default")) 283 opts->enmCacheMode = kVbsfCacheMode_Default;328 strcpy(opts->szCacheMode, "cache=default"); 284 329 else if (IS_EQUAL("none")) 285 opts->enmCacheMode = kVbsfCacheMode_None;330 strcpy(opts->szCacheMode, "cache=none"); 286 331 else if (IS_EQUAL("strict")) 287 opts->enmCacheMode = kVbsfCacheMode_Strict;332 strcpy(opts->szCacheMode, "cache=strict"); 288 333 else if (IS_EQUAL("read")) 289 opts->enmCacheMode = kVbsfCacheMode_Read;334 strcpy(opts->szCacheMode, "cache=read"); 290 335 else if (IS_EQUAL("readwrite")) 291 opts->enmCacheMode = kVbsfCacheMode_ReadWrite;336 strcpy(opts->szCacheMode, "cache=readwrite"); 292 337 else 293 338 panic("invalid cache mode '%.*s'\n" … … 297 342 case HO_UID: 298 343 /** @todo convert string to id. */ 299 opts->uid = safe_atoi(val, val_len, 10); 344 snprintf(opts->szUid, sizeof(opts->szUid), 345 "uid=%d", safe_atoi(val, val_len, 10)); 300 346 break; 301 347 case HO_GID: 302 348 /** @todo convert string to id. */ 303 opts->gid = safe_atoi(val, val_len, 10); 349 snprintf(opts->szGid, sizeof(opts->szGid), 350 "gid=%d", safe_atoi(val, val_len, 10)); 304 351 break; 305 352 case HO_DMODE: 306 opts->dmode = safe_atoi(val, val_len, 8); 353 snprintf(opts->szDMode, sizeof(opts->szDMode), 354 "dmode=0%o", safe_atoi(val, val_len, 8)); 307 355 break; 308 356 case HO_FMODE: 309 opts->fmode = safe_atoi(val, val_len, 8); 357 snprintf(opts->szFMode, sizeof(opts->szFMode), 358 "fmode=0%o", safe_atoi(val, val_len, 8)); 310 359 break; 311 360 case HO_UMASK: 312 opts->dmask = opts->fmask = safe_atoi(val, val_len, 8); 313 break; 361 { 362 int fMask = safe_atoi(val, val_len, 8); 363 snprintf(opts->szDMask, sizeof(opts->szDMask), "dmask=0%o", fMask); 364 snprintf(opts->szFMask, sizeof(opts->szFMask), "fmask=0%o", fMask); 365 break; 366 } 314 367 case HO_DMASK: 315 opts->dmask = safe_atoi(val, val_len, 8); 368 snprintf(opts->szDMask, sizeof(opts->szDMask), 369 "dmask=0%o", safe_atoi(val, val_len, 8)); 316 370 break; 317 371 case HO_FMASK: 318 opts->fmask = safe_atoi(val, val_len, 8); 372 snprintf(opts->szFMask, sizeof(opts->szFMask), 373 "fmask=0%o", safe_atoi(val, val_len, 8)); 319 374 break; 320 375 case HO_IOCHARSET: 321 if (val_len + 1 > sizeof(opts->nls_name)) 322 { 323 panic("iocharset name too long\n"); 324 } 325 memcpy(opts->nls_name, val, val_len); 326 opts->nls_name[val_len] = 0; 376 case HO_NLS: 377 if (val_len >= MAX_NLS_NAME) 378 panic("the character set name for I/O is too long: %*.*s\n", (int)val_len, (int)val_len, val); 379 snprintf(opts->szIoCharset, sizeof(opts->szIoCharset), 380 "%s=%*.*s", handler->opt == HO_IOCHARSET ? "iocharset" : "nls", (int)val_len, (int)val_len, val); 327 381 break; 328 382 case HO_CONVERTCP: 329 opts->convertcp = malloc(val_len + 1); 330 if (!opts->convertcp) 331 { 383 opts->pszConvertCp = malloc(val_len + 1); 384 if (!opts->pszConvertCp) 332 385 panic_err("could not allocate memory"); 333 } 334 memcpy(opts->convertcp, val, val_len); 335 opts->convertcp[val_len] = 0; 386 memcpy(opts->pszConvertCp, val, val_len); 387 opts->pszConvertCp[val_len] = '\0'; 336 388 break; 337 389 case HO_NOAUTO: … … 345 397 346 398 if ( !handler->name 347 && !opts-> sloppy)399 && !opts->fSloppy) 348 400 { 349 401 fprintf(stderr, "unknown mount option `%.*s'\n", (int)len, s); … … 354 406 if (handler->desc) 355 407 fprintf(stderr, " %-10s%s %s\n", handler->name, 356 handler->has_arg ? "=<arg>" : "", handler->desc);408 handler->has_arg ? "=<arg>" : "", handler->desc); 357 409 } 358 410 exit(EXIT_FAILURE); … … 361 413 } 362 414 415 /** Appends @a pszOptVal to pszOpts if not empty. */ 416 static size_t append_option(char *pszOpts, size_t cbOpts, size_t offOpts, const char *pszOptVal) 417 { 418 if (*pszOptVal != '\0') 419 { 420 size_t cchOptVal = strlen(pszOptVal); 421 if (offOpts + (offOpts > 0) + cchOptVal < cbOpts) 422 { 423 if (offOpts) 424 pszOpts[offOpts++] = ','; 425 memcpy(&pszOpts[offOpts], pszOptVal, cchOptVal); 426 offOpts += cchOptVal; 427 pszOpts[offOpts] = '\0'; 428 } 429 else 430 panic("Too many options!"); 431 } 432 return offOpts; 433 } 434 363 435 static void 364 convertcp(char *in_codeset, char * host_name, struct vbsf_mount_info_new *info)365 { 366 char *i = host_name;367 char *o = info->name;368 size_t ib = strlen( host_name);369 size_t ob = sizeof(info->name)- 1;436 convertcp(char *in_codeset, char *pszSharedFolder, char *pszDst) 437 { 438 char *i = pszSharedFolder; 439 char *o = pszDst; 440 size_t ib = strlen(pszSharedFolder); 441 size_t ob = MAX_HOST_NAME - 1; 370 442 iconv_t cd; 371 443 372 444 cd = iconv_open("UTF-8", in_codeset); 373 if (cd == (iconv_t) 445 if (cd == (iconv_t)-1) 374 446 { 375 447 panic_err("could not convert share name, iconv_open `%s' failed", … … 380 452 { 381 453 size_t c = iconv(cd, &i, &ib, &o, &ob); 382 if (c == (size_t) 454 if (c == (size_t)-1) 383 455 { 384 456 panic_err("could not convert share name(%s) at %d", 385 host_name, (int)(strlen (host_name) - ib));457 pszSharedFolder, (int)(strlen(pszSharedFolder) - ib)); 386 458 } 387 459 } … … 454 526 int saved_errno; 455 527 int nomtab = 0; 456 unsigned long flags = MS_NODEV; 457 char *host_name; 458 char *mount_point; 459 struct vbsf_mount_info_new mntinf; 528 char *pszSharedFolder; 529 char *pszMountPoint; 530 struct utsname uts; 531 int major, minor, patch; 532 size_t offOpts; 533 static const char s_szSfNameOpt[] = "sf_name="; 534 char szSharedFolderIconved[sizeof(s_szSfNameOpt) - 1 + MAX_HOST_NAME]; 535 char szOpts[MAX_MNTOPT_STR]; 460 536 struct vbsf_mount_opts opts = 461 537 { 462 -1, /* ttl */ 463 -1, /* msDirCacheTTL */ 464 -1, /* msInodeTTL */ 465 0, /* cMaxIoPages */ 466 0, /* cbDirBuf */ 467 kVbsfCacheMode_Default, 468 0, /* uid */ 469 0, /* gid */ 470 ~0U, /* dmode */ 471 ~0U, /* fmode*/ 472 0, /* dmask */ 473 0, /* fmask */ 474 0, /* ronly */ 475 0, /* sloppy */ 476 0, /* noexec */ 477 0, /* nodev */ 478 0, /* nosuid */ 479 0, /* remount */ 480 "\0", /* nls_name */ 481 NULL, /* convertcp */ 538 MS_NODEV, 539 "", 540 "", 541 "", 542 "", 543 "", 544 "", 545 "", 546 "", 547 "", 548 "", 549 "", 550 "", 551 "", 552 false, /*fSloppy*/ 553 NULL, 482 554 }; 555 483 556 AssertCompile(sizeof(uid_t) == sizeof(int)); 484 557 AssertCompile(sizeof(gid_t) == sizeof(int)); 485 558 486 memset(&mntinf, 0, sizeof(mntinf));487 mntinf.nullchar = '\0';488 mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;489 mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;490 mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;491 mntinf.length = sizeof(mntinf);492 mntinf.szTag[0] = '\0';493 494 559 if (getuid()) 495 560 panic("Only root can mount shared folders from the host.\n"); … … 498 563 argv[0] = "mount.vboxsf"; 499 564 565 /* 566 * Parse options. 567 */ 500 568 while ((c = getopt(argc, argv, "rwsno:h")) != -1) 501 569 { … … 510 578 511 579 case 'r': 512 opts. ronly = 1;580 opts.fFlags |= MS_RDONLY; 513 581 break; 514 582 515 583 case 'w': 516 opts. ronly = 0;584 opts.fFlags &= ~MS_RDONLY; 517 585 break; 518 586 519 587 case 's': 520 opts. sloppy = 1;588 opts.fSloppy = true; 521 589 break; 522 590 … … 534 602 return usage(argv[0]); 535 603 536 host_name = argv[optind]; 537 mount_point = argv[optind + 1]; 538 539 if (opts.convertcp) 540 convertcp(opts.convertcp, host_name, &mntinf); 541 else 542 { 543 if (strlen(host_name) > MAX_HOST_NAME - 1) 544 panic("host name is too big\n"); 545 546 strcpy(mntinf.name, host_name); 547 } 548 549 if (strlen(opts.nls_name) > MAX_NLS_NAME - 1) 550 panic("%s: the character set name for I/O is too long.\n", argv[0]); 551 552 strcpy(mntinf.nls_name, opts.nls_name); 553 554 if (opts.ronly) 555 flags |= MS_RDONLY; 556 if (opts.noexec) 557 flags |= MS_NOEXEC; 558 if (opts.nodev) 559 flags |= MS_NODEV; 560 if (opts.remount) 561 flags |= MS_REMOUNT; 562 563 mntinf.ttl = opts.ttl; 564 mntinf.msDirCacheTTL = opts.msDirCacheTTL; 565 mntinf.msInodeTTL = opts.msInodeTTL; 566 mntinf.cMaxIoPages = opts.cMaxIoPages; 567 mntinf.cbDirBuf = opts.cbDirBuf; 568 mntinf.enmCacheMode = opts.enmCacheMode; 569 570 mntinf.uid = opts.uid; 571 mntinf.gid = opts.gid; 572 mntinf.dmode = opts.dmode; 573 mntinf.fmode = opts.fmode; 574 mntinf.dmask = opts.dmask; 575 mntinf.fmask = opts.fmask; 604 pszSharedFolder = argv[optind]; 605 pszMountPoint = argv[optind + 1]; 606 if (opts.pszConvertCp) 607 { 608 convertcp(opts.pszConvertCp, pszSharedFolder, &szSharedFolderIconved[sizeof(s_szSfNameOpt) - 1]); 609 pszSharedFolder = &szSharedFolderIconved[sizeof(s_szSfNameOpt) - 1]; 610 } 576 611 577 612 /* 578 * Note: When adding and/or modifying parameters of the vboxsf mounting 579 * options you also would have to adjust VBoxServiceAutoMount.cpp 580 * to keep this code here slick without having VbglR3. 613 * Concat option strings. 581 614 */ 582 err = mount(host_name, mount_point, "vboxsf", flags, &mntinf); 615 offOpts = 0; 616 szOpts[0] = '\0'; 617 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szTTL); 618 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szMsDirCacheTTL); 619 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szMsInodeTTL); 620 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szMaxIoPages); 621 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szDirBuf); 622 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szCacheMode); 623 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szUid); 624 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szGid); 625 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szDMode); 626 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szFMode); 627 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szDMask); 628 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szFMask); 629 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, opts.szIoCharset); 630 631 /* For pre-2.6 kernels we have to supply the shared folder name as a 632 string option because the kernel hides the device name from us. */ 633 RT_ZERO(uts); 634 if ( uname(&uts) == -1 635 || sscanf(uts.release, "%d.%d.%d", &major, &minor, &patch) != 3) 636 major = minor = patch = 5; 637 638 if (KERNEL_VERSION(major, minor, patch) < KERNEL_VERSION(2,6,0)) 639 { 640 memcpy(szSharedFolderIconved, s_szSfNameOpt, sizeof(s_szSfNameOpt) - 1); 641 if (!opts.pszConvertCp) 642 { 643 if (strlen(pszSharedFolder) >= MAX_HOST_NAME) 644 panic("%s: shared folder name is too long (max %d)", argv[0], (int)MAX_HOST_NAME - 1); 645 strcpy(&szSharedFolderIconved[sizeof(s_szSfNameOpt) - 1], pszSharedFolder); 646 } 647 offOpts = append_option(szOpts, sizeof(szOpts), offOpts, szSharedFolderIconved); 648 } 649 650 /* 651 * Do the actual mounting. 652 */ 653 err = mount(pszSharedFolder, pszMountPoint, "vboxsf", opts.fFlags, szOpts); 583 654 saved_errno = errno; 584 655 585 /* Some versions of the mount utility (unknown which, if any) will turn the586 shared folder name into an absolute path. So, we check if it starts with587 the CWD and removes it. We must do this after failing, because there is588 not actual restrictions on the shared folder name wrt to slashes and such. */589 if (err == -1 && errno == ENXIO && host_name[0] == '/')590 {591 char szCWD[4096];592 if (getcwd(szCWD, sizeof(szCWD)) != NULL)593 {594 size_t cchCWD = strlen(szCWD);595 if (!strncmp(host_name, szCWD, cchCWD))596 {597 while (host_name[cchCWD] == '/')598 ++cchCWD;599 if (host_name[cchCWD])600 {601 /* We checked before that we have enough space. */602 strcpy(mntinf.name, host_name + cchCWD);603 err = mount(host_name, mount_point, "vboxsf", flags, &mntinf);604 saved_errno = errno;605 }606 }607 }608 else609 fprintf(stderr, "%s: failed to get the current working directory: %s", argv[0], strerror(errno));610 errno = saved_errno;611 }612 656 if (err) 613 657 { 614 658 if (saved_errno == ENXIO) 615 panic("%s: shared folder '%s' was not found (check VM settings / spelling)\n", argv[0], host_name);659 panic("%s: shared folder '%s' was not found (check VM settings / spelling)\n", argv[0], pszSharedFolder); 616 660 else 617 661 panic_err("%s: mounting failed with the error", argv[0]); … … 620 664 if (!nomtab) 621 665 { 622 err = vbsfmount_complete( host_name, mount_point, flags, &opts);666 err = vbsfmount_complete(pszSharedFolder, pszMountPoint, opts.fFlags, szOpts); 623 667 switch (err) 624 668 { … … 627 671 628 672 case 1: 629 panic_err("%s: Could not update mount table ( failed to create memstream).", argv[0]);673 panic_err("%s: Could not update mount table (out of memory).", argv[0]); 630 674 break; 631 675 -
trunk/src/VBox/Additions/linux/sharedfolders/vbsfmount.c
r82968 r87463 17 17 */ 18 18 19 20 /********************************************************************************************************************************* 21 * Header Files * 22 *********************************************************************************************************************************/ 19 23 #ifndef _GNU_SOURCE 20 # define _GNU_SOURCE24 # define _GNU_SOURCE 21 25 #endif 26 #include <assert.h> 22 27 #include <ctype.h> 23 28 #include <mntent.h> … … 32 37 33 38 /** @todo Use defines for return values! */ 34 int vbsfmount_complete(const char * host_name, const char *mount_point,35 unsigned long f lags, struct vbsf_mount_opts *opts)39 int vbsfmount_complete(const char *pszSharedFolder, const char *pszMountPoint, 40 unsigned long fFlags, const char *pszOpts) 36 41 { 37 FILE *f, *m; 38 char *buf; 39 size_t size; 40 struct mntent e; 41 int rc = 0; 42 /* 43 * Combine pszOpts and fFlags. 44 */ 45 int rc; 46 size_t const cchFlags = (fFlags & MS_NOSUID ? strlen(MNTOPT_NOSUID) + 1 : 0) 47 + (fFlags & MS_RDONLY ? strlen(MNTOPT_RO) : strlen(MNTOPT_RW)); 48 size_t const cchOpts = pszOpts ? 1 + strlen(pszOpts) : 0; 49 char *pszBuf = (char *)malloc(cchFlags + cchOpts + 8); 50 if (pszBuf) 51 { 52 char *psz = pszBuf; 53 FILE *pMTab; 42 54 43 m = open_memstream(&buf, &size); 44 if (!m) 45 return 1; /* Could not update mount table (failed to create memstream). */ 55 strcpy(psz, fFlags & MS_RDONLY ? MNTOPT_RO : MNTOPT_RW); 56 psz += strlen(psz); 46 57 47 if (opts->ttl != -1) 48 fprintf(m, "ttl=%d,", opts->ttl); 49 if (opts->msDirCacheTTL >= 0) 50 fprintf(m, "dcachettl=%d,", opts->msDirCacheTTL); 51 if (opts->msInodeTTL >= 0) 52 fprintf(m, "inodettl=%d,", opts->msInodeTTL); 53 if (opts->cMaxIoPages) 54 fprintf(m, "maxiopages=%u,", opts->cMaxIoPages); 55 if (opts->cbDirBuf) 56 fprintf(m, "dirbuf=%u,", opts->cbDirBuf); 57 switch (opts->enmCacheMode) 58 { 59 default: 60 case kVbsfCacheMode_Default: 61 break; 62 case kVbsfCacheMode_None: fprintf(m, "cache=none,"); break; 63 case kVbsfCacheMode_Strict: fprintf(m, "cache=strict,"); break; 64 case kVbsfCacheMode_Read: fprintf(m, "cache=read,"); break; 65 case kVbsfCacheMode_ReadWrite: fprintf(m, "cache=readwrite,"); break; 66 } 67 if (opts->uid) 68 fprintf(m, "uid=%d,", opts->uid); 69 if (opts->gid) 70 fprintf(m, "gid=%d,", opts->gid); 71 if (*opts->nls_name) 72 fprintf(m, "iocharset=%s,", opts->nls_name); 73 if (flags & MS_NOSUID) 74 fprintf(m, "%s,", MNTOPT_NOSUID); 75 if (flags & MS_RDONLY) 76 fprintf(m, "%s,", MNTOPT_RO); 77 else 78 fprintf(m, "%s,", MNTOPT_RW); 58 if (fFlags & MS_NOSUID) 59 { 60 *psz++ = ','; 61 strcpy(psz, MNTOPT_NOSUID); 62 psz += strlen(psz); 63 } 79 64 80 fclose(m); 65 if (cchOpts) 66 { 67 *psz++ = ','; 68 strcpy(psz, pszOpts); 69 } 81 70 82 if (size > 0) 83 buf[size - 1] = 0; 84 else 85 buf = "defaults"; 71 assert(strlen(pszBuf) <= cchFlags + cchOpts); 86 72 87 f = setmntent(MOUNTED, "a+"); 88 if (!f) 89 { 90 rc = 2; /* Could not open mount table for update. */ 73 /* 74 * Open the mtab and update it: 75 */ 76 pMTab = setmntent(MOUNTED, "a+"); 77 if (pMTab) 78 { 79 struct mntent Entry; 80 Entry.mnt_fsname = (char*)pszSharedFolder; 81 Entry.mnt_dir = (char *)pszMountPoint; 82 Entry.mnt_type = "vboxsf"; 83 Entry.mnt_opts = pszBuf; 84 Entry.mnt_freq = 0; 85 Entry.mnt_passno = 0; 86 87 if (!addmntent(pMTab, &Entry)) 88 rc = 0; /* success. */ 89 else 90 rc = 3; /* Could not add an entry to the mount table. */ 91 92 endmntent(pMTab); 93 } 94 else 95 rc = 2; /* Could not open mount table for update. */ 96 97 free(pszBuf); 91 98 } 92 99 else 93 { 94 e.mnt_fsname = (char*)host_name; 95 e.mnt_dir = (char*)mount_point; 96 e.mnt_type = "vboxsf"; 97 e.mnt_opts = buf; 98 e.mnt_freq = 0; 99 e.mnt_passno = 0; 100 101 if (addmntent(f, &e)) 102 rc = 3; /* Could not add an entry to the mount table. */ 103 104 endmntent(f); 105 } 106 107 if (size > 0) 108 { 109 memset(buf, 0, size); 110 free(buf); 111 } 112 100 rc = 1; /* allocation error */ 113 101 return rc; 114 102 } 103 -
trunk/src/VBox/Additions/linux/sharedfolders/vbsfmount.h
r82968 r87463 35 35 #endif 36 36 37 /* Linux constraints the size of data mount argument to PAGE_SIZE - 1. */ 38 #define MAX_HOST_NAME 256 39 #define MAX_NLS_NAME 32 37 /* Linux constrains the size of data mount argument to PAGE_SIZE - 1. */ 38 #define MAX_MNTOPT_STR PAGE_SIZE 39 #define MAX_HOST_NAME 256 40 #define MAX_NLS_NAME 32 40 41 #define VBSF_DEFAULT_TTL_MS 200 41 42 … … 135 136 #endif 136 137 137 /**138 * For use with the vbsfmount_complete() helper.139 */140 struct vbsf_mount_opts {141 int ttl;142 int32_t msDirCacheTTL;143 int32_t msInodeTTL;144 uint32_t cMaxIoPages;145 uint32_t cbDirBuf;146 enum vbsf_cache_mode enmCacheMode;147 int uid;148 int gid;149 int dmode;150 int fmode;151 int dmask;152 int fmask;153 int ronly;154 int sloppy;155 int noexec;156 int nodev;157 int nosuid;158 int remount;159 char nls_name[MAX_NLS_NAME];160 char *convertcp;161 };162 163 138 /** Completes the mount operation by adding the new mount point to mtab if required. */ 164 int vbsfmount_complete(const char * host_name, const char *mount_point,165 unsigned long f lags, struct vbsf_mount_opts *opts);139 int vbsfmount_complete(const char *pszSharedFolder, const char *pszMountPoint, 140 unsigned long fFlags, const char *pszOpts); 166 141 167 142 #endif /* !GA_INCLUDED_SRC_linux_sharedfolders_vbsfmount_h */
Note:
See TracChangeset
for help on using the changeset viewer.