VBoxServiceAutoMount.cpp revision 1313e5cbe01a41e7ccb1499d2d73c455a2495955
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * VBoxService - Auto-mounting for Shared Folders.
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2010 Oracle Corporation
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * available from http://www.virtualbox.org. This file is free software;
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * you can redistribute it and/or modify it under the terms of the GNU
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * General Public License (GPL) as published by the Free Software
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/*******************************************************************************
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync* Header Files *
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync*******************************************************************************/
76a0b518a2bb00a37607af4a8f4ff86e2f8d3134vboxsync/*******************************************************************************
76a0b518a2bb00a37607af4a8f4ff86e2f8d3134vboxsync* Global Variables *
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync*******************************************************************************/
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** The semaphore we're blocking on. */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsyncstatic RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** The Shared Folders service client ID. */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** @copydoc VBOXSERVICE::pfnPreInit */
76a0b518a2bb00a37607af4a8f4ff86e2f8d3134vboxsyncstatic DECLCALLBACK(int) VBoxServiceAutoMountPreInit(void)
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** @copydoc VBOXSERVICE::pfnOption */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsyncstatic DECLCALLBACK(int) VBoxServiceAutoMountOption(const char **ppszShort, int argc, char **argv, int *pi)
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** @copydoc VBOXSERVICE::pfnInit */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsyncstatic DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountInit\n");
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync rc = VbglR3SharedFolderConnect(&g_SharedFoldersSvcClientID);
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceVerbose(3, "VBoxServiceAutoMountInit: Service Client ID: %#x\n", g_SharedFoldersSvcClientID);
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync /* If the service was not found, we disable this service without
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync causing VBoxService to fail. */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceVerbose(0, "VBoxServiceAutoMountInit: Shared Folders service is not available\n");
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceError("Control: Failed to connect to the Shared Folders service! Error: %Rrc\n", rc);
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync/** @todo Integrate into RTFsQueryMountpoint(). */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsyncstatic bool VBoxServiceAutoMountShareIsMounted(const char *pszShare,
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync AssertReturn(cbMountPoint, VERR_INVALID_PARAMETER);
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync bool fMounted = false;
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync /* @todo What to do if we have a relative path in mtab instead
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * of an absolute one ("temp" vs. "/media/temp")?
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * procfs contains the full path but not the actual share name ...
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync * FILE *pFh = setmntent("/proc/mounts", "r+t"); */
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", mntTab.mnt_mountp)
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync ? true : false;
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", pMntEnt->mnt_dir)
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync ? true : false;
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync VBoxServiceVerbose(4, "VBoxServiceAutoMountShareIsMounted: Share \"%s\" at mount point \"%s\" = %s\n",
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync pszShare, fMounted ? pszMountPoint : "<None>", fMounted ? "Yes" : "No");
412ad5bac323727b4073056113e1d8e0faf60db3vboxsyncstatic int VBoxServiceAutoMountUnmount(const char *pszMountPoint)
412ad5bac323727b4073056113e1d8e0faf60db3vboxsync AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
return rc;
static int VBoxServiceAutoMountPrepareMountPoint(const char *pszMountPoint, const char *pszShareName,
RTFMODE fMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG; /* Owner (=root) and the group (=vboxsf) have full access. */
rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);
VBoxServiceVerbose(3, "VBoxServiceAutoMountPrepareMountPoint: Mount directory \"%s\" already is used/mounted\n", pszMountPoint);
VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set mode %RTfmode for mount directory \"%s\", rc = %Rrc\n",
VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set permissions for mount directory \"%s\", rc = %Rrc\n",
VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not create mount directory \"%s\" with mode %RTfmode, rc = %Rrc\n",
return rc;
if ( VBoxServiceAutoMountShareIsMounted(pszShareName, szAlreadyMountedTo, sizeof(szAlreadyMountedTo))
VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", unmounting ...\n",
#ifdef RT_OS_SOLARIS
VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
&mntinf);
VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno));
VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
++cchCWD;
switch (errno)
case EINVAL:
VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName);
case EBUSY:
VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n",
return rc;
static int VBoxServiceAutoMountProcessMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings, uint32_t cMappings,
if (cMappings == 0)
return VINF_SUCCESS;
&& *pszShareName)
VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
if (grp_vboxsf)
VBoxServiceError("VBoxServiceAutoMountWorker: Unable to join mount point/prefix/shrae, rc = %Rrc\n", rc);
VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
return rc;
int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */,
&& cMappings)
char *pszMountDir;
VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir);
char *pszSharePrefix;
VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix);
#ifdef USE_VIRTUAL_SHARES
rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID);
#ifdef USE_VIRTUAL_SHARES
VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc);
VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc);
VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
else if (!cMappings)
if (*pfShutdown)
return VINF_SUCCESS;
NULL,
NULL,