VirtualBox

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

Last change on this file since 50668 was 50461, checked in by vboxsync, 11 years ago

Additions/VBoxService: skip a share from automounting if it's already mapped

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.4 KB
Line 
1/* $Id: VBoxServiceAutoMount.cpp 50461 2014-02-14 09:49:26Z vboxsync $ */
2/** @file
3 * VBoxService - Auto-mounting for Shared Folders.
4 */
5
6/*
7 * Copyright (C) 2010-2012 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. 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/path.h>
26#include <iprt/string.h>
27#include <iprt/semaphore.h>
28#include <VBox/VBoxGuestLib.h>
29#include "VBoxServiceInternal.h"
30#include "VBoxServiceUtils.h"
31
32#include <errno.h>
33#include <grp.h>
34#include <sys/mount.h>
35#ifdef RT_OS_SOLARIS
36# include <sys/mntent.h>
37# include <sys/mnttab.h>
38# include <sys/vfs.h>
39#else
40# include <mntent.h>
41# include <paths.h>
42#endif
43#include <unistd.h>
44
45RT_C_DECLS_BEGIN
46#include "../../linux/sharedfolders/vbsfmount.h"
47RT_C_DECLS_END
48
49#ifdef RT_OS_SOLARIS
50# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/mnt"
51#else
52# define VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR "/media"
53#endif
54
55#ifndef _PATH_MOUNTED
56 #ifdef RT_OS_SOLARIS
57 #define _PATH_MOUNTED "/etc/mnttab"
58 #else
59 #define _PATH_MOUNTED "/etc/mtab"
60 #endif
61#endif
62
63/*******************************************************************************
64* Global Variables *
65*******************************************************************************/
66/** The semaphore we're blocking on. */
67static RTSEMEVENTMULTI g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
68/** The Shared Folders service client ID. */
69static uint32_t g_SharedFoldersSvcClientID = 0;
70
71/** @copydoc VBOXSERVICE::pfnPreInit */
72static DECLCALLBACK(int) VBoxServiceAutoMountPreInit(void)
73{
74 return VINF_SUCCESS;
75}
76
77
78/** @copydoc VBOXSERVICE::pfnOption */
79static DECLCALLBACK(int) VBoxServiceAutoMountOption(const char **ppszShort, int argc, char **argv, int *pi)
80{
81 NOREF(ppszShort);
82 NOREF(argc);
83 NOREF(argv);
84 NOREF(pi);
85
86 return -1;
87}
88
89
90/** @copydoc VBOXSERVICE::pfnInit */
91static DECLCALLBACK(int) VBoxServiceAutoMountInit(void)
92{
93 VBoxServiceVerbose(3, "VBoxServiceAutoMountInit\n");
94
95 int rc = RTSemEventMultiCreate(&g_AutoMountEvent);
96 AssertRCReturn(rc, rc);
97
98 rc = VbglR3SharedFolderConnect(&g_SharedFoldersSvcClientID);
99 if (RT_SUCCESS(rc))
100 {
101 VBoxServiceVerbose(3, "VBoxServiceAutoMountInit: Service Client ID: %#x\n", g_SharedFoldersSvcClientID);
102 }
103 else
104 {
105 /* If the service was not found, we disable this service without
106 causing VBoxService to fail. */
107 if (rc == VERR_HGCM_SERVICE_NOT_FOUND) /* Host service is not available. */
108 {
109 VBoxServiceVerbose(0, "VBoxServiceAutoMountInit: Shared Folders service is not available\n");
110 rc = VERR_SERVICE_DISABLED;
111 }
112 else
113 VBoxServiceError("Control: Failed to connect to the Shared Folders service! Error: %Rrc\n", rc);
114 RTSemEventMultiDestroy(g_AutoMountEvent);
115 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
116 }
117
118 return rc;
119}
120
121
122/** @todo Integrate into RTFsQueryMountpoint(). */
123static bool VBoxServiceAutoMountShareIsMounted(const char *pszShare,
124 char *pszMountPoint, size_t cbMountPoint)
125{
126 AssertPtrReturn(pszShare, VERR_INVALID_PARAMETER);
127 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
128 AssertReturn(cbMountPoint, VERR_INVALID_PARAMETER);
129
130 bool fMounted = false;
131 /* @todo What to do if we have a relative path in mtab instead
132 * of an absolute one ("temp" vs. "/media/temp")?
133 * procfs contains the full path but not the actual share name ...
134 * FILE *pFh = setmntent("/proc/mounts", "r+t"); */
135#ifdef RT_OS_SOLARIS
136 FILE *pFh = fopen(_PATH_MOUNTED, "r");
137 if (!pFh)
138 VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
139 _PATH_MOUNTED);
140 else
141 {
142 mnttab mntTab;
143 while ((getmntent(pFh, &mntTab)))
144 {
145 if (!RTStrICmp(mntTab.mnt_special, pszShare))
146 {
147 fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", mntTab.mnt_mountp)
148 ? true : false;
149 break;
150 }
151 }
152 fclose(pFh);
153 }
154#else
155 FILE *pFh = setmntent(_PATH_MOUNTED, "r+t");
156 if (pFh == NULL)
157 VBoxServiceError("VBoxServiceAutoMountShareIsMounted: Could not open mount tab \"%s\"!\n",
158 _PATH_MOUNTED);
159 else
160 {
161 mntent *pMntEnt;
162 while ((pMntEnt = getmntent(pFh)))
163 {
164 if (!RTStrICmp(pMntEnt->mnt_fsname, pszShare))
165 {
166 fMounted = RTStrPrintf(pszMountPoint, cbMountPoint, "%s", pMntEnt->mnt_dir)
167 ? true : false;
168 break;
169 }
170 }
171 endmntent(pFh);
172 }
173#endif
174
175 VBoxServiceVerbose(4, "VBoxServiceAutoMountShareIsMounted: Share \"%s\" at mount point \"%s\" = %s\n",
176 pszShare, fMounted ? pszMountPoint : "<None>", fMounted ? "Yes" : "No");
177 return fMounted;
178}
179
180
181static int VBoxServiceAutoMountUnmount(const char *pszMountPoint)
182{
183 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
184
185 int rc = VINF_SUCCESS;
186 uint8_t uTries = 0;
187 int r;
188 while (uTries++ < 3)
189 {
190 r = umount(pszMountPoint);
191 if (r == 0)
192 break;
193 RTThreadSleep(5000); /* Wait a while ... */
194 }
195 if (r == -1)
196 rc = RTErrConvertFromErrno(errno);
197 return rc;
198}
199
200
201static int VBoxServiceAutoMountPrepareMountPoint(const char *pszMountPoint, const char *pszShareName,
202 vbsf_mount_opts *pOpts)
203{
204 AssertPtrReturn(pOpts, VERR_INVALID_PARAMETER);
205 AssertPtrReturn(pszMountPoint, VERR_INVALID_PARAMETER);
206 AssertPtrReturn(pszShareName, VERR_INVALID_PARAMETER);
207
208 RTFMODE fMode = RTFS_UNIX_IRWXU | RTFS_UNIX_IRWXG; /* Owner (=root) and the group (=vboxsf) have full access. */
209 int rc = RTDirCreateFullPath(pszMountPoint, fMode);
210 if (RT_SUCCESS(rc))
211 {
212 rc = RTPathSetOwnerEx(pszMountPoint, NIL_RTUID /* Owner, unchanged */, pOpts->gid, RTPATH_F_ON_LINK);
213 if (RT_SUCCESS(rc))
214 {
215 rc = RTPathSetMode(pszMountPoint, fMode);
216 if (RT_FAILURE(rc))
217 {
218 if (rc == VERR_WRITE_PROTECT)
219 {
220 VBoxServiceVerbose(3, "VBoxServiceAutoMountPrepareMountPoint: Mount directory \"%s\" already is used/mounted\n", pszMountPoint);
221 rc = VINF_SUCCESS;
222 }
223 else
224 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set mode %RTfmode for mount directory \"%s\", rc = %Rrc\n",
225 fMode, pszMountPoint, rc);
226 }
227 }
228 else
229 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not set permissions for mount directory \"%s\", rc = %Rrc\n",
230 pszMountPoint, rc);
231 }
232 else
233 VBoxServiceError("VBoxServiceAutoMountPrepareMountPoint: Could not create mount directory \"%s\" with mode %RTfmode, rc = %Rrc\n",
234 pszMountPoint, fMode, rc);
235 return rc;
236}
237
238
239static int VBoxServiceAutoMountSharedFolder(const char *pszShareName, const char *pszMountPoint,
240 vbsf_mount_opts *pOpts)
241{
242 AssertPtr(pOpts);
243
244 int rc = VINF_SUCCESS;
245 char szAlreadyMountedTo[RTPATH_MAX];
246 bool fSkip = false;
247
248 /* Already mounted? */
249 if (VBoxServiceAutoMountShareIsMounted(pszShareName, szAlreadyMountedTo, sizeof(szAlreadyMountedTo)))
250 {
251 fSkip = true;
252 /* Do if it not mounted to our desired mount point */
253 if (RTStrICmp(pszMountPoint, szAlreadyMountedTo))
254 {
255 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", unmounting ...\n",
256 pszShareName, szAlreadyMountedTo);
257 rc = VBoxServiceAutoMountUnmount(szAlreadyMountedTo);
258 if (RT_FAILURE(rc))
259 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to unmount \"%s\", %s (%d)!\n",
260 szAlreadyMountedTo, strerror(errno), errno);
261 else
262 fSkip = false;
263 }
264 if (fSkip)
265 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already mounted to \"%s\", skipping\n",
266 pszShareName, szAlreadyMountedTo);
267 }
268
269 if (!fSkip && RT_SUCCESS(rc))
270 rc = VBoxServiceAutoMountPrepareMountPoint(pszMountPoint, pszShareName, pOpts);
271 if (!fSkip && RT_SUCCESS(rc))
272 {
273#ifdef RT_OS_SOLARIS
274 char achOptBuf[MAX_MNTOPT_STR] = { '\0', };
275 int flags = 0;
276 if (pOpts->ronly)
277 flags |= MS_RDONLY;
278 RTStrPrintf(achOptBuf, sizeof(achOptBuf), "uid=%d,gid=%d", pOpts->uid, pOpts->gid);
279 int r = mount(pszShareName,
280 pszMountPoint,
281 flags | MS_OPTIONSTR,
282 "vboxfs",
283 NULL, /* char *dataptr */
284 0, /* int datalen */
285 achOptBuf,
286 sizeof(achOptBuf));
287 if (r == 0)
288 {
289 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
290 }
291 else
292 {
293 if (errno != EBUSY) /* Share is already mounted? Then skip error msg. */
294 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\", error = %s\n",
295 pszShareName, pszMountPoint, strerror(errno));
296 }
297#else /* !RT_OS_SOLARIS */
298 unsigned long flags = MS_NODEV;
299
300 const char *szOptions = { "rw" };
301 struct vbsf_mount_info_new mntinf;
302
303 mntinf.nullchar = '\0';
304 mntinf.signature[0] = VBSF_MOUNT_SIGNATURE_BYTE_0;
305 mntinf.signature[1] = VBSF_MOUNT_SIGNATURE_BYTE_1;
306 mntinf.signature[2] = VBSF_MOUNT_SIGNATURE_BYTE_2;
307 mntinf.length = sizeof(mntinf);
308
309 mntinf.uid = pOpts->uid;
310 mntinf.gid = pOpts->gid;
311 mntinf.ttl = pOpts->ttl;
312 mntinf.dmode = pOpts->dmode;
313 mntinf.fmode = pOpts->fmode;
314 mntinf.dmask = pOpts->dmask;
315 mntinf.fmask = pOpts->fmask;
316
317 strcpy(mntinf.name, pszShareName);
318 strcpy(mntinf.nls_name, "\0");
319
320 int r = mount(NULL,
321 pszMountPoint,
322 "vboxsf",
323 flags,
324 &mntinf);
325 if (r == 0)
326 {
327 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" was mounted to \"%s\"\n", pszShareName, pszMountPoint);
328
329 r = vbsfmount_complete(pszShareName, pszMountPoint, flags, pOpts);
330 switch (r)
331 {
332 case 0: /* Success. */
333 errno = 0; /* Clear all errors/warnings. */
334 break;
335
336 case 1:
337 VBoxServiceError("VBoxServiceAutoMountWorker: Could not update mount table (failed to create memstream): %s\n", strerror(errno));
338 break;
339
340 case 2:
341 VBoxServiceError("VBoxServiceAutoMountWorker: Could not open mount table for update: %s\n", strerror(errno));
342 break;
343
344 case 3:
345 /* VBoxServiceError("VBoxServiceAutoMountWorker: Could not add an entry to the mount table: %s\n", strerror(errno)); */
346 errno = 0;
347 break;
348
349 default:
350 VBoxServiceError("VBoxServiceAutoMountWorker: Unknown error while completing mount operation: %d\n", r);
351 break;
352 }
353 }
354 else /* r == -1, we got some error in errno. */
355 {
356 if (errno == EPROTO)
357 {
358 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Messed up share name, re-trying ...\n");
359
360 /* Sometimes the mount utility messes up the share name. Try to
361 * un-mangle it again. */
362 char szCWD[4096];
363 size_t cchCWD;
364 if (!getcwd(szCWD, sizeof(szCWD)))
365 VBoxServiceError("VBoxServiceAutoMountWorker: Failed to get the current working directory\n");
366 cchCWD = strlen(szCWD);
367 if (!strncmp(pszMountPoint, szCWD, cchCWD))
368 {
369 while (pszMountPoint[cchCWD] == '/')
370 ++cchCWD;
371 /* We checked before that we have enough space */
372 strcpy(mntinf.name, pszMountPoint + cchCWD);
373 }
374 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf);
375 }
376 if (errno == EPROTO)
377 {
378 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Re-trying with old mounting structure ...\n");
379
380 /* New mount tool with old vboxsf module? Try again using the old
381 * vbsf_mount_info_old structure. */
382 struct vbsf_mount_info_old mntinf_old;
383 memcpy(&mntinf_old.name, &mntinf.name, MAX_HOST_NAME);
384 memcpy(&mntinf_old.nls_name, mntinf.nls_name, MAX_NLS_NAME);
385 mntinf_old.uid = mntinf.uid;
386 mntinf_old.gid = mntinf.gid;
387 mntinf_old.ttl = mntinf.ttl;
388 r = mount(NULL, pszMountPoint, "vboxsf", flags, &mntinf_old);
389 }
390 if (r == -1) /* Was there some error from one of the tries above? */
391 {
392 switch (errno)
393 {
394 /* If we get EINVAL here, the system already has mounted the Shared Folder to another
395 * mount point. */
396 case EINVAL:
397 VBoxServiceVerbose(0, "VBoxServiceAutoMountWorker: Shared folder \"%s\" already is mounted!\n", pszShareName);
398 /* Ignore this error! */
399 break;
400 case EBUSY:
401 /* Ignore these errors! */
402 break;
403
404 default:
405 VBoxServiceError("VBoxServiceAutoMountWorker: Could not mount shared folder \"%s\" to \"%s\": %s (%d)\n",
406 pszShareName, pszMountPoint, strerror(errno), errno);
407 rc = RTErrConvertFromErrno(errno);
408 break;
409 }
410 }
411 }
412#endif /* !RT_OS_SOLARIS */
413 }
414 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Mounting returned with rc=%Rrc\n", rc);
415 return rc;
416}
417
418static int VBoxServiceAutoMountProcessMappings(PVBGLR3SHAREDFOLDERMAPPING paMappings, uint32_t cMappings,
419 const char *pszMountDir, const char *pszSharePrefix, uint32_t uClientID)
420{
421 if (cMappings == 0)
422 return VINF_SUCCESS;
423 AssertPtrReturn(paMappings, VERR_INVALID_PARAMETER);
424 AssertPtrReturn(pszMountDir, VERR_INVALID_PARAMETER);
425 AssertPtrReturn(pszSharePrefix, VERR_INVALID_PARAMETER);
426 AssertReturn(uClientID > 0, VERR_INVALID_PARAMETER);
427
428 int rc = VINF_SUCCESS;
429 for (uint32_t i = 0; i < cMappings && RT_SUCCESS(rc); i++)
430 {
431 char *pszShareName = NULL;
432 rc = VbglR3SharedFolderGetName(uClientID, paMappings[i].u32Root, &pszShareName);
433 if ( RT_SUCCESS(rc)
434 && *pszShareName)
435 {
436 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Connecting share %u (%s) ...\n", i+1, pszShareName);
437
438 char *pszShareNameFull = NULL;
439 if (RTStrAPrintf(&pszShareNameFull, "%s%s", pszSharePrefix, pszShareName) > 0)
440 {
441 char szMountPoint[RTPATH_MAX];
442 rc = RTPathJoin(szMountPoint, sizeof(szMountPoint), pszMountDir, pszShareNameFull);
443 if (RT_SUCCESS(rc))
444 {
445 VBoxServiceVerbose(4, "VBoxServiceAutoMountWorker: Processing mount point \"%s\"\n", szMountPoint);
446
447 struct group *grp_vboxsf = getgrnam("vboxsf");
448 if (grp_vboxsf)
449 {
450 struct vbsf_mount_opts mount_opts =
451 {
452 0, /* uid */
453 (int)grp_vboxsf->gr_gid, /* gid */
454 0, /* ttl */
455 0770, /* dmode, owner and group "vboxsf" have full access */
456 0770, /* fmode, owner and group "vboxsf" have full access */
457 0, /* dmask */
458 0, /* fmask */
459 0, /* ronly */
460 0, /* noexec */
461 0, /* nodev */
462 0, /* nosuid */
463 0, /* remount */
464 "\0", /* nls_name */
465 NULL, /* convertcp */
466 };
467
468 rc = VBoxServiceAutoMountSharedFolder(pszShareName, szMountPoint, &mount_opts);
469 }
470 else
471 VBoxServiceError("VBoxServiceAutoMountWorker: Group \"vboxsf\" does not exist\n");
472 }
473 else
474 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to join mount point/prefix/shrae, rc = %Rrc\n", rc);
475 RTStrFree(pszShareNameFull);
476 }
477 else
478 VBoxServiceError("VBoxServiceAutoMountWorker: Unable to allocate full share name\n");
479 RTStrFree(pszShareName);
480 }
481 else
482 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder name for root node = %u, rc = %Rrc\n",
483 paMappings[i].u32Root, rc);
484 } /* for cMappings. */
485 return rc;
486}
487
488
489/** @copydoc VBOXSERVICE::pfnWorker */
490DECLCALLBACK(int) VBoxServiceAutoMountWorker(bool volatile *pfShutdown)
491{
492 /*
493 * Tell the control thread that it can continue
494 * spawning services.
495 */
496 RTThreadUserSignal(RTThreadSelf());
497
498 uint32_t cMappings;
499 PVBGLR3SHAREDFOLDERMAPPING paMappings;
500 int rc = VbglR3SharedFolderGetMappings(g_SharedFoldersSvcClientID, true /* Only process auto-mounted folders */,
501 &paMappings, &cMappings);
502 if ( RT_SUCCESS(rc)
503 && cMappings)
504 {
505 char *pszMountDir;
506 rc = VbglR3SharedFolderGetMountDir(&pszMountDir);
507 if (rc == VERR_NOT_FOUND)
508 rc = RTStrDupEx(&pszMountDir, VBOXSERVICE_AUTOMOUNT_DEFAULT_DIR);
509 if (RT_SUCCESS(rc))
510 {
511 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount dir set to \"%s\"\n", pszMountDir);
512
513 char *pszSharePrefix;
514 rc = VbglR3SharedFolderGetMountPrefix(&pszSharePrefix);
515 if (RT_SUCCESS(rc))
516 {
517 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Shared folder mount prefix set to \"%s\"\n", pszSharePrefix);
518#ifdef USE_VIRTUAL_SHARES
519 /* Check for a fixed/virtual auto-mount share. */
520 if (VbglR3SharedFolderExists(g_SharedFoldersSvcClientID, "vbsfAutoMount"))
521 {
522 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Host supports auto-mount root\n");
523 }
524 else
525 {
526#endif
527 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Got %u shared folder mappings\n", cMappings);
528 rc = VBoxServiceAutoMountProcessMappings(paMappings, cMappings, pszMountDir, pszSharePrefix, g_SharedFoldersSvcClientID);
529#ifdef USE_VIRTUAL_SHARES
530 }
531#endif
532 RTStrFree(pszSharePrefix);
533 } /* Mount share prefix. */
534 else
535 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mount prefix, rc = %Rrc\n", rc);
536 RTStrFree(pszMountDir);
537 }
538 else
539 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder directory, rc = %Rrc\n", rc);
540 VbglR3SharedFolderFreeMappings(paMappings);
541 }
542 else if (RT_FAILURE(rc))
543 VBoxServiceError("VBoxServiceAutoMountWorker: Error while getting the shared folder mappings, rc = %Rrc\n", rc);
544 else
545 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: No shared folder mappings found\n");
546
547 /*
548 * Because this thread is a one-timer at the moment we don't want to break/change
549 * the semantics of the main thread's start/stop sub-threads handling.
550 *
551 * This thread exits so fast while doing its own startup in VBoxServiceStartServices()
552 * that this->fShutdown flag is set to true in VBoxServiceThread() before we have the
553 * chance to check for a service failure in VBoxServiceStartServices() to indicate
554 * a VBoxService startup error.
555 *
556 * Therefore *no* service threads are allowed to quit themselves and need to wait
557 * for the pfShutdown flag to be set by the main thread.
558 */
559 for (;;)
560 {
561 /* Do we need to shutdown? */
562 if (*pfShutdown)
563 break;
564
565 /* Let's sleep for a bit and let others run ... */
566 RTThreadSleep(500);
567 }
568
569 RTSemEventMultiDestroy(g_AutoMountEvent);
570 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
571
572 VBoxServiceVerbose(3, "VBoxServiceAutoMountWorker: Finished with rc=%Rrc\n", rc);
573 return VINF_SUCCESS;
574}
575
576/** @copydoc VBOXSERVICE::pfnTerm */
577static DECLCALLBACK(void) VBoxServiceAutoMountTerm(void)
578{
579 VBoxServiceVerbose(3, "VBoxServiceAutoMountTerm\n");
580
581 VbglR3SharedFolderDisconnect(g_SharedFoldersSvcClientID);
582 g_SharedFoldersSvcClientID = 0;
583
584 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
585 {
586 RTSemEventMultiDestroy(g_AutoMountEvent);
587 g_AutoMountEvent = NIL_RTSEMEVENTMULTI;
588 }
589 return;
590}
591
592
593/** @copydoc VBOXSERVICE::pfnStop */
594static DECLCALLBACK(void) VBoxServiceAutoMountStop(void)
595{
596 /*
597 * We need this check because at the moment our auto-mount
598 * thread really is a one-timer which destroys the event itself
599 * after running.
600 */
601 if (g_AutoMountEvent != NIL_RTSEMEVENTMULTI)
602 RTSemEventMultiSignal(g_AutoMountEvent);
603}
604
605
606/**
607 * The 'automount' service description.
608 */
609VBOXSERVICE g_AutoMount =
610{
611 /* pszName. */
612 "automount",
613 /* pszDescription. */
614 "Auto-mount for Shared Folders",
615 /* pszUsage. */
616 NULL,
617 /* pszOptions. */
618 NULL,
619 /* methods */
620 VBoxServiceAutoMountPreInit,
621 VBoxServiceAutoMountOption,
622 VBoxServiceAutoMountInit,
623 VBoxServiceAutoMountWorker,
624 VBoxServiceAutoMountStop,
625 VBoxServiceAutoMountTerm
626};
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