VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxService/VBoxServiceAutoMount.cpp@ 31211

Last change on this file since 31211 was 31211, checked in by vboxsync, 15 years ago

Another build fix.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: VBoxServiceAutoMount.cpp 31211 2010-07-29 13:17:02Z vboxsync $ */
2/** @file
3 * VBoxService - Auto-mounting for Shared Folders.
4 */
5
6/*
7 * Copyright (C) 2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <iprt/assert.h>
23#include <iprt/dir.h>
24#include <iprt/mem.h>
25#include <iprt/string.h>
26#include <iprt/semaphore.h>
27#include <VBox/VBoxGuestLib.h>
28#include "VBoxServiceInternal.h"
29#include "VBoxServiceUtils.h"
30
31#include <errno.h>
32#include <sys/mount.h>
33#ifdef RT_OS_SOLARIS
34#include <sys/vfs.h>
35#endif
36#include <unistd.h>
37
38#ifdef RT_OS_LINUX
39 RT_C_DECLS_BEGIN
40 #include "../../linux/sharedfolders/vbsfmount.h"
41 RT_C_DECLS_END
42#endif
43
44/*******************************************************************************
45* Global Variables *
46*******************************************************************************/
47/** The semaphore we're blocking on. */
48static RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
49
50
51/** @copydoc VBOXSERVICE::pfnPreInit */
52static DECLCALLBACK(int) VBoxServiceAutoMountPreInit(void)
53{
54 return VINF_SUCCESS;
55}
56
57
58/** @copydoc VBOXSERVICE::pfnOption */
59static DECLCALLBACK(int) VBoxServiceAutoMountOption(const char **ppszShort, int argc, char **argv, int *pi)
60{
61 NOREF(ppszShort);
62 NOREF(argc);
63 NOREF(argv);
64 NOREF(pi);
65 return VINF_SUCCESS;
66}
67
68
69/** @copydoc VBOXSERVICE::pfnInit */
70static DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
71{
72 VBoxServiceVerbose(3, "VBoxServiceAutoMountInit\n");
73
74 int rc = RTSemEventMultiCreate(&g_AutoMountEvent);
75 AssertRCReturn(rc, rc);
76
77 return rc;
78}
79
80
81static 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)
94 {
95 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
96 }
97 else
98 {
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));
102 }
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));
216 return RTErrConvertFromErrno(errno);
217}
218
219
220/** @copydoc VBOXSERVICE::pfnWorker */
221DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown)
222{
223 /*
224 * Tell the control thread that it can continue
225 * spawning services.
226 */
227 RTThreadUserSignal(RTThreadSelf());
228
229 uint32_t u32ClientId;
230 int rc = VbglR3SharedFolderConnect(&u32ClientId);
231 if (!RT_SUCCESS(rc))
232 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Failed to connect to the shared folder service, error %Rrc\n", rc);
233 else
234 {
235 uint32_t cMappings;
236 VBGLR3SHAREDFOLDERMAPPING *paMappings;
237
238 rc = VbglR3SharedFolderGetMappings(u32ClientId, true /* Only process auto-mounted folders */,
239 &paMappings, &cMappings);
240 if (RT_SUCCESS(rc))
241 {
242#if 0
243 /* Check for a fixed/virtual auto-mount share. */
244 if (VbglR3SharedFolderExists(u32ClientId, "vbsfAutoMount"))
245 {
246 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n");
247 }
248 else
249 {
250#endif
251 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings);
252 for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++)
253 {
254 char *pszShareName = NULL;
255 rc = VbglR3SharedFolderGetName(u32ClientId, paMappings[i].u32Root, &pszShareName);
256 if ( RT_SUCCESS(rc)
257 && *pszShareName)
258 {
259 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
260
261 char *pszMountPoint = NULL;
262 if ( RTStrAPrintf(&pszMountPoint, "/media/sf_%s", pszShareName) > 0
263 && pszMountPoint)
264 {
265 /* We always use "/media" as our root mounting directory. */
266 /** @todo Detect the correct "media" directory, based on the current guest (?). */
267 RTFMODE fMode = 0777;
268 rc = RTDirCreateFullPath(pszMountPoint, fMode);
269 if (RT_SUCCESS(rc))
270 {
271 rc = VBoxServiceAutoMountSharedFolder(pszShareName, pszMountPoint);
272 }
273 else
274 VBoxServiceError("VBoxServiceAutoMountWorker: Could not create mount directory \"%s\", rc = %Rrc\n",
275 pszMountPoint, rc);
276 RTStrFree(pszMountPoint);
277 }
278 else
279 rc = VERR_NO_MEMORY;
280 RTStrFree(pszShareName);
281 }
282 else
283 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
284 paMappings[i].u32Root, rc);
285 }
286#if 0
287 }
288#endif
289 RTMemFree(paMappings);
290 }
291 else
292 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
293 VbglR3SharedFolderDisconnect(u32ClientId);
294 }
295
296 RTSemEventMultiDestroy(g_AutoMountEvent);
297 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
298
299 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished\n");
300 return 0;
301}
302
303/** @copydoc VBOXSERVICE::pfnTerm */
304static DECLCALLBACK(void) VBoxServiceAutoMountTerm(void)
305{
306 VBoxServiceVerbose(3, "VBoxServiceAutoMountTerm\n");
307 return;
308}
309
310
311/** @copydoc VBOXSERVICE::pfnStop */
312static DECLCALLBACK(void) VBoxServiceAutoMountStop(void)
313{
314 RTSemEventMultiSignal(g_AutoMountEvent);
315}
316
317
318/**
319 * The 'automount' service description.
320 */
321VBOXSERVICE g_AutoMount =
322{
323 /* pszName. */
324 "automount",
325 /* pszDescription. */
326 "Auto-mount for Shared Folders",
327 /* pszUsage. */
328 NULL,
329 /* pszOptions. */
330 NULL,
331 /* methods */
332 VBoxServiceAutoMountPreInit,
333 VBoxServiceAutoMountOption,
334 VBoxServiceAutoMountInit,
335 VBoxServiceAutoMountWorker,
336 VBoxServiceAutoMountStop,
337 VBoxServiceAutoMountTerm
338};
Note: See TracBrowser for help on using the repository browser.

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