VirtualBox

Changeset 87463 in vbox for trunk/src/VBox/Additions/linux


Ignore:
Timestamp:
Jan 28, 2021 3:38:55 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
142482
Message:

linux/vboxsf,VBoxService: Modify mount.vboxsf and the VBoxService automounter to pass string-based mount options when calling mount(2). Also include the shared folder name with the mount options for Linux kernels < 2.6.0 since these kernel versions don't pass the shared folder name through to the vboxsf.ko kernel module. bugref:9816

Location:
trunk/src/VBox/Additions/linux/sharedfolders
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/linux/sharedfolders/mount.vboxsf.c

    r82968 r87463  
    4444#include <limits.h>
    4545#include <iconv.h>
     46#include <sys/utsname.h>
     47#include <linux/version.h>
    4648
    4749#include "vbsfmount.h"
    4850
    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*********************************************************************************************************************************/
    5259#define PANIC_ATTR __attribute ((noreturn, __format__ (__printf__, 1, 2)))
     60
     61
     62/*********************************************************************************************************************************
     63*   Structures and Typedefs                                                                                                      *
     64*********************************************************************************************************************************/
     65struct 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
    5391
    5492static void PANIC_ATTR
     
    134172        HO_FMASK,
    135173        HO_IOCHARSET,
     174        HO_NLS,
    136175        HO_CONVERTCP,
    137176        HO_NOEXEC,
     
    164203        {"cache",       HO_CACHE,           1, "cache mode: none, strict (default), read, readwrite"},
    165204        {"iocharset",   HO_IOCHARSET,       1, "i/o charset (default utf8)"},
     205        {"nls",         HO_NLS,             1, "i/o charset (default utf8)"},
    166206        {"convertcp",   HO_CONVERTCP,       1, "convert share name from given charset to utf8"},
    167207        {"dmode",       HO_DMODE,           1, "mode of all directories"},
     
    230270                    {
    231271                        panic("%.*s requires an argument (i.e. %.*s=<arg>)\n",
    232                                (int)len, s, (int)len, s);
     272                              (int)len, s, (int)len, s);
    233273                    }
    234274                }
     
    237277                {
    238278                    case HO_RW:
    239                         opts->ronly = 0;
     279                        opts->fFlags &= ~MS_RDONLY;
    240280                        break;
    241281                    case HO_RO:
    242                         opts->ronly = 1;
     282                        opts->fFlags |= MS_RDONLY;
    243283                        break;
    244284                    case HO_NOEXEC:
    245                         opts->noexec = 1;
     285                        opts->fFlags |= MS_NOEXEC;
    246286                        break;
    247287                    case HO_EXEC:
    248                         opts->noexec = 0;
     288                        opts->fFlags &= ~MS_NOEXEC;
    249289                        break;
    250290                    case HO_NODEV:
    251                         opts->nodev = 1;
     291                        opts->fFlags |= MS_NODEV;
    252292                        break;
    253293                    case HO_DEV:
    254                         opts->nodev = 0;
     294                        opts->fFlags &= ~MS_NODEV;
    255295                        break;
    256296                    case HO_NOSUID:
    257                         opts->nosuid = 1;
     297                        opts->fFlags |= MS_NOSUID;
    258298                        break;
    259299                    case HO_SUID:
    260                         opts->nosuid = 0;
     300                        opts->fFlags &= ~MS_NOSUID;
    261301                        break;
    262302                    case HO_REMOUNT:
    263                         opts->remount = 1;
     303                        opts->fFlags |= MS_REMOUNT;
    264304                        break;
    265305                    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));
    267308                        break;
    268309                    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));
    270312                        break;
    271313                    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));
    273316                        break;
    274317                    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));
    276320                        break;
    277321                    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));
    279324                        break;
    280325                    case HO_CACHE:
    281326#define IS_EQUAL(a_sz) (val_len == sizeof(a_sz) - 1U && strncmp(val, a_sz, sizeof(a_sz) - 1U) == 0)
    282327                        if (IS_EQUAL("default"))
    283                             opts->enmCacheMode = kVbsfCacheMode_Default;
     328                            strcpy(opts->szCacheMode, "cache=default");
    284329                        else if (IS_EQUAL("none"))
    285                             opts->enmCacheMode = kVbsfCacheMode_None;
     330                            strcpy(opts->szCacheMode, "cache=none");
    286331                        else if (IS_EQUAL("strict"))
    287                             opts->enmCacheMode = kVbsfCacheMode_Strict;
     332                            strcpy(opts->szCacheMode, "cache=strict");
    288333                        else if (IS_EQUAL("read"))
    289                             opts->enmCacheMode = kVbsfCacheMode_Read;
     334                            strcpy(opts->szCacheMode, "cache=read");
    290335                        else if (IS_EQUAL("readwrite"))
    291                             opts->enmCacheMode = kVbsfCacheMode_ReadWrite;
     336                            strcpy(opts->szCacheMode, "cache=readwrite");
    292337                        else
    293338                            panic("invalid cache mode '%.*s'\n"
     
    297342                    case HO_UID:
    298343                        /** @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));
    300346                        break;
    301347                    case HO_GID:
    302348                        /** @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));
    304351                        break;
    305352                    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));
    307355                        break;
    308356                    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));
    310359                        break;
    311360                    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                    }
    314367                    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));
    316370                        break;
    317371                    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));
    319374                        break;
    320375                    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);
    327381                        break;
    328382                    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)
    332385                            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';
    336388                        break;
    337389                    case HO_NOAUTO:
     
    345397
    346398        if (   !handler->name
    347             && !opts->sloppy)
     399            && !opts->fSloppy)
    348400        {
    349401            fprintf(stderr, "unknown mount option `%.*s'\n", (int)len, s);
     
    354406                if (handler->desc)
    355407                    fprintf(stderr, "  %-10s%s %s\n", handler->name,
    356                          handler->has_arg ? "=<arg>" : "", handler->desc);
     408                            handler->has_arg ? "=<arg>" : "", handler->desc);
    357409            }
    358410            exit(EXIT_FAILURE);
     
    361413}
    362414
     415/** Appends @a pszOptVal to pszOpts if not empty. */
     416static 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
    363435static 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;
     436convertcp(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;
    370442    iconv_t cd;
    371443
    372444    cd = iconv_open("UTF-8", in_codeset);
    373     if (cd == (iconv_t) -1)
     445    if (cd == (iconv_t)-1)
    374446    {
    375447        panic_err("could not convert share name, iconv_open `%s' failed",
     
    380452    {
    381453        size_t c = iconv(cd, &i, &ib, &o, &ob);
    382         if (c == (size_t) -1)
     454        if (c == (size_t)-1)
    383455        {
    384456            panic_err("could not convert share name(%s) at %d",
    385                       host_name, (int)(strlen (host_name) - ib));
     457                      pszSharedFolder, (int)(strlen(pszSharedFolder) - ib));
    386458        }
    387459    }
     
    454526    int saved_errno;
    455527    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];
    460536    struct vbsf_mount_opts opts =
    461537    {
    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,
    482554    };
     555
    483556    AssertCompile(sizeof(uid_t) == sizeof(int));
    484557    AssertCompile(sizeof(gid_t) == sizeof(int));
    485558
    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 
    494559    if (getuid())
    495560        panic("Only root can mount shared folders from the host.\n");
     
    498563        argv[0] = "mount.vboxsf";
    499564
     565    /*
     566     * Parse options.
     567     */
    500568    while ((c = getopt(argc, argv, "rwsno:h")) != -1)
    501569    {
     
    510578
    511579            case 'r':
    512                 opts.ronly = 1;
     580                opts.fFlags |= MS_RDONLY;
    513581                break;
    514582
    515583            case 'w':
    516                 opts.ronly = 0;
     584                opts.fFlags &= ~MS_RDONLY;
    517585                break;
    518586
    519587            case 's':
    520                 opts.sloppy = 1;
     588                opts.fSloppy = true;
    521589                break;
    522590
     
    534602        return usage(argv[0]);
    535603
    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    }
    576611
    577612    /*
    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.
    581614     */
    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);
    583654    saved_errno = errno;
    584655
    585     /* Some versions of the mount utility (unknown which, if any) will turn the
    586        shared folder name into an absolute path.  So, we check if it starts with
    587        the CWD and removes it.  We must do this after failing, because there is
    588        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         else
    609             fprintf(stderr, "%s: failed to get the current working directory: %s", argv[0], strerror(errno));
    610         errno = saved_errno;
    611     }
    612656    if (err)
    613657    {
    614658        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);
    616660        else
    617661            panic_err("%s: mounting failed with the error", argv[0]);
     
    620664    if (!nomtab)
    621665    {
    622         err = vbsfmount_complete(host_name, mount_point, flags, &opts);
     666        err = vbsfmount_complete(pszSharedFolder, pszMountPoint, opts.fFlags, szOpts);
    623667        switch (err)
    624668        {
     
    627671
    628672            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]);
    630674                break;
    631675
  • trunk/src/VBox/Additions/linux/sharedfolders/vbsfmount.c

    r82968 r87463  
    1717 */
    1818
     19
     20/*********************************************************************************************************************************
     21*   Header Files                                                                                                                 *
     22*********************************************************************************************************************************/
    1923#ifndef _GNU_SOURCE
    20 #define _GNU_SOURCE
     24# define _GNU_SOURCE
    2125#endif
     26#include <assert.h>
    2227#include <ctype.h>
    2328#include <mntent.h>
     
    3237
    3338/** @todo Use defines for return values! */
    34 int vbsfmount_complete(const char *host_name, const char *mount_point,
    35                        unsigned long flags, struct vbsf_mount_opts *opts)
     39int vbsfmount_complete(const char *pszSharedFolder, const char *pszMountPoint,
     40                       unsigned long fFlags, const char *pszOpts)
    3641{
    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;
    4254
    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);
    4657
    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        }
    7964
    80     fclose(m);
     65        if (cchOpts)
     66        {
     67            *psz++ = ',';
     68            strcpy(psz, pszOpts);
     69        }
    8170
    82     if (size > 0)
    83         buf[size - 1] = 0;
    84     else
    85         buf = "defaults";
     71        assert(strlen(pszBuf) <= cchFlags + cchOpts);
    8672
    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);
    9198    }
    9299    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 */
    113101    return rc;
    114102}
     103
  • trunk/src/VBox/Additions/linux/sharedfolders/vbsfmount.h

    r82968 r87463  
    3535#endif
    3636
    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
    4041#define VBSF_DEFAULT_TTL_MS     200
    4142
     
    135136#endif
    136137
    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 
    163138/** 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 flags, struct vbsf_mount_opts *opts);
     139int vbsfmount_complete(const char *pszSharedFolder, const char *pszMountPoint,
     140                       unsigned long fFlags, const char *pszOpts);
    166141
    167142#endif /* !GA_INCLUDED_SRC_linux_sharedfolders_vbsfmount_h */
Note: See TracChangeset for help on using the changeset viewer.

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