VirtualBox

source: vbox/trunk/src/VBox/Additions/darwin/vboxfs/VBoxVFS.cpp@ 58195

Last change on this file since 58195 was 58195, checked in by vboxsync, 9 years ago

VBoxGuestR0LibSharedFolders: Prefixed functions ('vbox' wasn't a very good one). Hope I found all places these functions are called...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: VBoxVFS.cpp 58195 2015-10-12 15:13:47Z vboxsync $ */
2/** @file
3 * VBoxVFS - Guest Additions Shared Folders driver. KEXT entry point.
4 */
5
6/*
7 * Copyright (C) 2013-2015 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 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27#include <IOKit/IOLib.h> /* Assert as function */
28#include <IOKit/IOService.h>
29#include <mach/mach_port.h>
30
31
32#include <mach/kmod.h>
33#include <libkern/libkern.h>
34#include <mach/mach_types.h>
35#include <sys/mount.h>
36
37#include <iprt/cdefs.h>
38#include <iprt/types.h>
39#include <sys/param.h>
40#include <VBox/version.h>
41#include <iprt/asm.h>
42
43#include <VBox/log.h>
44
45#include "vboxvfs.h"
46
47
48/*********************************************************************************************************************************
49* Structures and Typedefs *
50*********************************************************************************************************************************/
51
52/**
53 * The service class for dealing with Share Folder filesystem.
54 */
55class org_virtualbox_VBoxVFS : public IOService
56{
57 OSDeclareDefaultStructors(org_virtualbox_VBoxVFS);
58
59private:
60 IOService * waitForCoreService(void);
61
62 IOService * coreService;
63
64public:
65 virtual bool start(IOService *pProvider);
66 virtual void stop(IOService *pProvider);
67};
68
69OSDefineMetaClassAndStructors(org_virtualbox_VBoxVFS, IOService);
70
71
72/*********************************************************************************************************************************
73* Global Variables *
74*********************************************************************************************************************************/
75
76/**
77 * Declare the module stuff.
78 */
79RT_C_DECLS_BEGIN
80static kern_return_t VBoxVFSModuleLoad(struct kmod_info *pKModInfo, void *pvData);
81static kern_return_t VBoxVFSModuleUnLoad(struct kmod_info *pKModInfo, void *pvData);
82extern kern_return_t _start(struct kmod_info *pKModInfo, void *pvData);
83extern kern_return_t _stop(struct kmod_info *pKModInfo, void *pvData);
84KMOD_EXPLICIT_DECL(VBoxVFS, VBOX_VERSION_STRING, _start, _stop)
85DECLHIDDEN(kmod_start_func_t *) _realmain = VBoxVFSModuleLoad;
86DECLHIDDEN(kmod_stop_func_t *) _antimain = VBoxVFSModuleUnLoad;
87DECLHIDDEN(int) _kext_apple_cc = __APPLE_CC__;
88RT_C_DECLS_END
89
90/** The number of IOService class instances. */
91static bool volatile g_fInstantiated = 0;
92/* Global connection to the host service */
93VBSFCLIENT g_vboxSFClient;
94/* VBoxVFS filesystem handle. Needed for FS unregistering. */
95static vfstable_t g_oVBoxVFSHandle;
96
97
98/**
99 * KEXT Module BSD entry point
100 */
101static kern_return_t VBoxVFSModuleLoad(struct kmod_info *pKModInfo, void *pvData)
102{
103 int rc;
104
105 /* Initialize the R0 guest library. */
106#if 0
107 rc = VbglR0SfInit();
108 if (RT_FAILURE(rc))
109 return KERN_FAILURE;
110#endif
111
112 PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders "
113 "driver is loaded");
114
115 return KERN_SUCCESS;
116}
117
118
119/**
120 * KEXT Module BSD exit point
121 */
122static kern_return_t VBoxVFSModuleUnLoad(struct kmod_info *pKModInfo, void *pvData)
123{
124 int rc;
125
126#if 0
127 VbglR0SfTerminate();
128#endif
129
130 PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders driver is unloaded");
131
132 return KERN_SUCCESS;
133}
134
135
136/**
137 * Register VBoxFS filesystem.
138 *
139 * @returns IPRT status code.
140 */
141int VBoxVFSRegisterFilesystem(void)
142{
143 struct vfs_fsentry oVFsEntry;
144 int rc;
145
146 memset(&oVFsEntry, 0, sizeof(oVFsEntry));
147 /* Attach filesystem operations set */
148 oVFsEntry.vfe_vfsops = &g_oVBoxVFSOpts;
149 /* Attach vnode operations */
150 oVFsEntry.vfe_vopcnt = g_cVBoxVFSVnodeOpvDescListSize;
151 oVFsEntry.vfe_opvdescs = g_VBoxVFSVnodeOpvDescList;
152 /* Set flags */
153 oVFsEntry.vfe_flags =
154#if ARCH_BITS == 64
155 VFS_TBL64BITREADY |
156#endif
157 VFS_TBLTHREADSAFE |
158 VFS_TBLFSNODELOCK |
159 VFS_TBLNOTYPENUM;
160
161 memcpy(oVFsEntry.vfe_fsname, VBOXVBFS_NAME, MFSNAMELEN);
162
163 rc = vfs_fsadd(&oVFsEntry, &g_oVBoxVFSHandle);
164 if (rc)
165 {
166 PINFO("Unable to register VBoxVFS filesystem (%d)", rc);
167 return VERR_GENERAL_FAILURE;
168 }
169
170 PINFO("VBoxVFS filesystem successfully registered");
171 return VINF_SUCCESS;
172}
173
174/**
175 * Unregister VBoxFS filesystem.
176 *
177 * @returns IPRT status code.
178 */
179int VBoxVFSUnRegisterFilesystem(void)
180{
181 int rc;
182
183 if (g_oVBoxVFSHandle == 0)
184 return VERR_INVALID_PARAMETER;
185
186 rc = vfs_fsremove(g_oVBoxVFSHandle);
187 if (rc)
188 {
189 PINFO("Unable to unregister VBoxVFS filesystem (%d)", rc);
190 return VERR_GENERAL_FAILURE;
191 }
192
193 g_oVBoxVFSHandle = 0;
194
195 PINFO("VBoxVFS filesystem successfully unregistered");
196 return VINF_SUCCESS;
197}
198
199
200/**
201 * Start this service.
202 */
203bool org_virtualbox_VBoxVFS::start(IOService *pProvider)
204{
205 int rc;
206
207 if (!IOService::start(pProvider))
208 return false;
209
210 /* Low level initialization should be performed only once */
211 if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
212 {
213 IOService::stop(pProvider);
214 return false;
215 }
216
217 /* Wait for VBoxGuest to be started */
218 coreService = waitForCoreService();
219 if (coreService)
220 {
221 rc = VbglR0SfInit();
222 if (RT_SUCCESS(rc))
223 {
224 /* Connect to the host service. */
225 rc = VbglR0SfConnect(&g_vboxSFClient);
226 if (RT_SUCCESS(rc))
227 {
228 PINFO("VBox client connected");
229 rc = VbglR0SfSetUtf8(&g_vboxSFClient);
230 if (RT_SUCCESS(rc))
231 {
232 rc = VBoxVFSRegisterFilesystem();
233 if (RT_SUCCESS(rc))
234 {
235 registerService();
236 PINFO("Successfully started I/O kit class instance");
237 return true;
238 }
239 PERROR("Unable to register VBoxVFS filesystem");
240 }
241 else
242 {
243 PERROR("VbglR0SfSetUtf8 failed: rc=%d", rc);
244 }
245 VbglR0SfDisconnect(&g_vboxSFClient);
246 }
247 else
248 {
249 PERROR("Failed to get connection to host: rc=%d", rc);
250 }
251 VbglR0SfUninit();
252 }
253 else
254 {
255 PERROR("Failed to initialize low level library");
256 }
257 coreService->release();
258 }
259 else
260 {
261 PERROR("VBoxGuest KEXT not started");
262 }
263
264 ASMAtomicXchgBool(&g_fInstantiated, false);
265 IOService::stop(pProvider);
266
267 return false;
268}
269
270
271/**
272 * Stop this service.
273 */
274void org_virtualbox_VBoxVFS::stop(IOService *pProvider)
275{
276 int rc;
277
278 AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
279
280 rc = VBoxVFSUnRegisterFilesystem();
281 if (RT_FAILURE(rc))
282 {
283 PERROR("VBoxVFS filesystem is busy. Make sure all "
284 "shares are unmounted (%d)", rc);
285 }
286
287 VbglR0SfDisconnect(&g_vboxSFClient);
288 PINFO("VBox client disconnected");
289
290 VbglR0SfTerminate();
291 PINFO("Low level uninit done");
292
293 coreService->release();
294 PINFO("VBoxGuest service released");
295
296 IOService::stop(pProvider);
297
298 ASMAtomicWriteBool(&g_fInstantiated, false);
299
300 PINFO("Successfully stopped I/O kit class instance");
301}
302
303
304/**
305 * Wait for VBoxGuest.kext to be started
306 */
307IOService * org_virtualbox_VBoxVFS::waitForCoreService(void)
308{
309 IOService *service;
310
311 OSDictionary *serviceToMatch = serviceMatching("org_virtualbox_VBoxGuest");
312 if (!serviceToMatch)
313 {
314 PINFO("unable to create matching dictionary");
315 return false;
316 }
317
318 /* Wait 10 seconds for VBoxGuest to be started */
319 service = waitForMatchingService(serviceToMatch, 10ULL * 1000000000ULL);
320 serviceToMatch->release();
321
322 return service;
323}
Note: See TracBrowser for help on using the repository browser.

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