VirtualBox

Ignore:
Timestamp:
Aug 2, 2010 3:00:33 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
64338
Message:

Shared Folders/AutoMount: Update for non-Windows guests.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp

    r31216 r31311  
    2323#include <iprt/dir.h>
    2424#include <iprt/mem.h>
     25#include <iprt/path.h>
    2526#include <iprt/string.h>
    2627#include <iprt/semaphore.h>
     
    3031
    3132#include <errno.h>
     33#include <grp.h>
    3234#include <sys/mount.h>
    3335#ifdef RT_OS_SOLARIS
     
    7981
    8082
    81 static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint)
    82 {
    83 #ifdef RT_OS_SOLARIS
    84     int flags = 0; /* No flags used yet. */
    85     int r = mount(pszShareName,
    86                   pszMountPoint,
    87                   flags,
    88                   "vboxsf",
    89                   NULL,                     /* char *dataptr */
    90                   0,                        /* int datalen */
    91                   NULL,                     /* char *optptr */
    92                   0);                       /* int optlen */
    93     if (r == 0)
     83static int VBoxServiceAutoMountPrepareMountPoint(const char *pszMountPoint, vbsf_mount_opts *pOpts)
     84{
     85    AssertPtr(pOpts);
     86
     87    RTFMODE fMode = 0770; /* Owner (=root) and the group (=vboxsf) have full access. */
     88    int rc = RTDirCreateFullPath(pszMountPoint, fMode);
     89    if (RT_SUCCESS(rc))
    9490    {
    95         VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
     91        rc = RTPathSetOwnerEx(pszMountPoint, -1 /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);
     92        if (RT_SUCCESS(rc))
     93        {
     94            rc = RTPathSetMode(pszMountPoint, fMode);
     95            VBoxServiceVerbose(3, "RTPathSetMode = rc = %Rrc\n");
     96            if (RT_FAILURE(rc))
     97                VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set mode for mount directory \"%s\", rc = %Rrc\n",
     98                                 pszMountPoint, rc);
     99        }
     100        else
     101            VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set permissions for mount directory \"%s\", rc = %Rrc\n",
     102                             pszMountPoint, rc);
    96103    }
    97104    else
     105        VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not create mount directory \"%s\", rc = %Rrc\n",
     106                         pszMountPoint, rc);
     107    return rc;
     108}
     109
     110
     111static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint,
     112                                            vbsf_mount_opts *pOpts)
     113{
     114    AssertPtr(pOpts);
     115
     116    int rc = VBoxServiceAutoMountPrepareMountPoint(pszMountPoint, pOpts);
     117    if (RT_SUCCESS(rc))
    98118    {
    99         if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
    100             VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
    101                              pszShareName, pszMountPoint, strerror(errno));
     119#ifdef RT_OS_SOLARIS
     120        int flags = 0; /* No flags used yet. */
     121        int r = mount(pszShareName,
     122                      pszMountPoint,
     123                      flags,
     124                      "vboxsf",
     125                      NULL,                     /* char *dataptr */
     126                      0,                        /* int datalen */
     127                      NULL,                     /* char *optptr */
     128                      0);                       /* int optlen */
     129        if (r == 0)
     130        {
     131            VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
     132        }
     133        else
     134        {
     135            if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
     136                VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
     137                                 pszShareName, pszMountPoint, strerror(errno));
     138        }
     139#else /* !RT_OS_SOLARIS */
     140        unsigned long flags = MS_NODEV;
     141
     142        const char *szOptions = { "rw" };
     143        struct vbsf_mount_info_new mntinf;
     144
     145        mntinf.nullchar     = '\0';
     146        mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
     147        mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
     148        mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
     149        mntinf.length       = sizeof(mntinf);
     150
     151        mntinf.uid   = pOpts->uid;
     152        mntinf.gid   = pOpts->gid;
     153        mntinf.ttl   = pOpts->ttl;
     154        mntinf.dmode = pOpts->dmode;
     155        mntinf.fmode = pOpts->fmode;
     156        mntinf.dmask = pOpts->dmask;
     157        mntinf.fmask = pOpts->fmask;
     158
     159        strcpy(mntinf.name, pszShareName);
     160        strcpy(mntinf.nls_name, "\0");
     161
     162        int r = mount(NULL,
     163                      pszMountPoint,
     164                      "vboxsf",
     165                      flags,
     166                      &mntinf);
     167        if (r == 0)
     168        {
     169            VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
     170
     171            r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts);
     172            switch (r)
     173            {
     174                case 0: /* Success. */
     175                    errno = 0; /* Clear all errors/warnings. */
     176                    break;
     177
     178                case 1:
     179                    VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
     180                    break;
     181
     182                case 2:
     183                    VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
     184                    break;
     185
     186                case 3:
     187                    VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno));
     188                    break;
     189
     190                default:
     191                    VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
     192                    break;
     193            }
     194        }
     195        else /* r != 0 */
     196        {
     197            if (errno == EPROTO)
     198            {
     199                /* Sometimes the mount utility messes up the share name.  Try to
     200                 * un-mangle it again. */
     201                char szCWD[4096];
     202                size_t cchCWD;
     203                if (!getcwd(szCWD, sizeof(szCWD)))
     204                    VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
     205                cchCWD = strlen(szCWD);
     206                if (!strncmp(pszMountPoint, szCWD, cchCWD))
     207                {
     208                    while (pszMountPoint[cchCWD] == '/')
     209                        ++cchCWD;
     210                    /* We checked before that we have enough space */
     211                    strcpy(mntinf.name, pszMountPoint + cchCWD);
     212                }
     213                r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
     214            }
     215            if (errno == EPROTO)
     216            {
     217                /* New mount tool with old vboxsf module? Try again using the old
     218                 * vbsf_mount_info_old structure. */
     219                struct vbsf_mount_info_old mntinf_old;
     220                memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
     221                memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
     222                mntinf_old.uid = mntinf.uid;
     223                mntinf_old.gid = mntinf.gid;
     224                mntinf_old.ttl = mntinf.ttl;
     225                r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
     226            }
     227            if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
     228                VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
     229                                 pszShareName, pszMountPoint, strerror(errno));
     230        }
     231#endif /* !RT_OS_SOLARIS */
    102232    }
    103 #else /* !RT_OS_SOLARIS */
    104     unsigned long flags = MS_NODEV;
    105     struct vbsf_mount_opts opts =
    106     {
    107         0,     /* uid */
    108         0,     /* gid */
    109         0,     /* ttl */
    110        ~0,     /* dmode */
    111        ~0,     /* fmode*/
    112         0,     /* dmask */
    113         0,     /* fmask */
    114         0,     /* ronly */
    115         0,     /* noexec */
    116         0,     /* nodev */
    117         0,     /* nosuid */
    118         0,     /* remount */
    119         "\0",  /* nls_name */
    120         NULL,  /* convertcp */
    121     };
    122 
    123     const char *szOptions = { "rw" };
    124     struct vbsf_mount_info_new mntinf;
    125 
    126     mntinf.nullchar     = '\0';
    127     mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
    128     mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
    129     mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
    130     mntinf.length       = sizeof(mntinf);
    131 
    132     mntinf.uid   = 0;
    133     mntinf.gid   = 0;
    134     mntinf.ttl   = 0;
    135     mntinf.dmode = ~0;
    136     mntinf.fmode = ~0;
    137     mntinf.dmask = 0;
    138     mntinf.fmask = 0;
    139 
    140     strcpy(mntinf.name, pszShareName);
    141     strcpy(mntinf.nls_name, "\0");
    142 
    143     int r = mount(NULL,
    144                   pszMountPoint,
    145                   "vboxsf",
    146                   flags,
    147                   &mntinf);
    148     if (r == 0)
    149     {
    150         VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
    151 
    152         r = vbsfmount_complete(pszShareName, pszMountPoint, flags, &opts);
    153         switch (r)
    154         {
    155             case 0: /* Success. */
    156                 errno = 0; /* Clear all errors/warnings. */
    157                 break;
    158 
    159             case 1:
    160                 VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
    161                 break;
    162 
    163             case 2:
    164                 VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
    165                 break;
    166 
    167             case 3:
    168                 VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno));
    169                 break;
    170 
    171             default:
    172                 VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
    173                 break;
    174         }
    175     }
    176     else /* r != 0 */
    177     {
    178         if (errno == EPROTO)
    179         {
    180             /* Sometimes the mount utility messes up the share name.  Try to
    181              * un-mangle it again. */
    182             char szCWD[4096];
    183             size_t cchCWD;
    184             if (!getcwd(szCWD, sizeof(szCWD)))
    185                 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
    186             cchCWD = strlen(szCWD);
    187             if (!strncmp(pszMountPoint, szCWD, cchCWD))
    188             {
    189                 while (pszMountPoint[cchCWD] == '/')
    190                     ++cchCWD;
    191                 /* We checked before that we have enough space */
    192                 strcpy(mntinf.name, pszMountPoint + cchCWD);
    193             }
    194             r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
    195         }
    196         if (errno == EPROTO)
    197         {
    198             /* New mount tool with old vboxsf module? Try again using the old
    199              * vbsf_mount_info_old structure. */
    200             struct vbsf_mount_info_old mntinf_old;
    201             memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
    202             memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
    203             mntinf_old.uid = mntinf.uid;
    204             mntinf_old.gid = mntinf.gid;
    205             mntinf_old.ttl = mntinf.ttl;
    206             r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
    207         }
    208         if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
    209             VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
    210                              pszShareName, pszMountPoint, strerror(errno));
    211     }
    212 #endif /* !RT_OS_SOLARIS */
    213 
    214     VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with errno=%d, error=%s\n",
    215                        errno, strerror(errno));
     233
     234    VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc, errno=%d, error=%s\n",
     235                       rc, errno, strerror(errno));
    216236    return RTErrConvertFromErrno(errno);
    217237}
     
    267287                            && pszMountPoint)
    268288                        {
    269                             /* We always use "/media" as our root mounting directory. */
    270                             /** @todo Detect the correct "media/mnt" directory, based on the current guest (?). */
    271                             RTFMODE fMode = 0700;
    272                             rc = RTDirCreateFullPath(pszMountPoint, fMode);
    273                             if (RT_SUCCESS(rc))
     289                            struct group *grp_vboxsf = getgrnam("vboxsf");
     290                            if (grp_vboxsf)
    274291                            {
    275                                 rc = VBoxServiceAutoMountSharedFolder(pszShareName, pszMountPoint);
     292                                struct vbsf_mount_opts mount_opts =
     293                                {
     294                                    0,                     /* uid */
     295                                    grp_vboxsf->gr_gid,    /* gid */
     296                                    0,                     /* ttl */
     297                                    0770,                  /* dmode, owner and group "vboxsf" have full access */
     298                                    0770,                  /* fmode, owner and group "vboxsf" have full access */
     299                                    0,                     /* dmask */
     300                                    0,                     /* fmask */
     301                                    0,                     /* ronly */
     302                                    0,                     /* noexec */
     303                                    0,                     /* nodev */
     304                                    0,                     /* nosuid */
     305                                    0,                     /* remount */
     306                                    "\0",                  /* nls_name */
     307                                    NULL,                  /* convertcp */
     308                                };
     309
     310                                /* We always use "/media" as our root mounting directory. */
     311                                /** @todo Detect the correct "media/mnt" directory, based on the current guest (?). */
     312                                rc = VBoxServiceAutoMountSharedFolder(pszShareName, pszMountPoint, &mount_opts);
    276313                            }
    277314                            else
    278                                 VBoxServiceError("VBoxServiceAutoMountWorker: Could not create mount directory \"%s\", rc = %Rrc\n",
    279                                                  pszMountPoint, rc);
     315                                VBoxServiceError("VBoxServiceAutoMountWorker: Group \"vboxsf\" does not exist\n");
    280316                            RTStrFree(pszMountPoint);
    281317                        }
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