VirtualBox

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

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

*: scm cleanup run.

  • 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 57358 2015-08-14 15:16:38Z 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 = vboxInit();
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 vboxUninit();
128#endif
129
130 PINFO("VirtualBox " VBOX_VERSION_STRING " shared folders "
131 "driver is unloaded");
132
133 return KERN_SUCCESS;
134}
135
136
137/**
138 * Register VBoxFS filesystem.
139 *
140 * @returns IPRT status code.
141 */
142int VBoxVFSRegisterFilesystem(void)
143{
144 struct vfs_fsentry oVFsEntry;
145 int rc;
146
147 memset(&oVFsEntry, 0, sizeof(oVFsEntry));
148 /* Attach filesystem operations set */
149 oVFsEntry.vfe_vfsops = &g_oVBoxVFSOpts;
150 /* Attach vnode operations */
151 oVFsEntry.vfe_vopcnt = g_cVBoxVFSVnodeOpvDescListSize;
152 oVFsEntry.vfe_opvdescs = g_VBoxVFSVnodeOpvDescList;
153 /* Set flags */
154 oVFsEntry.vfe_flags =
155#if ARCH_BITS == 64
156 VFS_TBL64BITREADY |
157#endif
158 VFS_TBLTHREADSAFE |
159 VFS_TBLFSNODELOCK |
160 VFS_TBLNOTYPENUM;
161
162 memcpy(oVFsEntry.vfe_fsname, VBOXVBFS_NAME, MFSNAMELEN);
163
164 rc = vfs_fsadd(&oVFsEntry, &g_oVBoxVFSHandle);
165 if (rc)
166 {
167 PINFO("Unable to register VBoxVFS filesystem (%d)", rc);
168 return VERR_GENERAL_FAILURE;
169 }
170
171 PINFO("VBoxVFS filesystem successfully registered");
172 return VINF_SUCCESS;
173}
174
175/**
176 * Unregister VBoxFS filesystem.
177 *
178 * @returns IPRT status code.
179 */
180int VBoxVFSUnRegisterFilesystem(void)
181{
182 int rc;
183
184 if (g_oVBoxVFSHandle == 0)
185 return VERR_INVALID_PARAMETER;
186
187 rc = vfs_fsremove(g_oVBoxVFSHandle);
188 if (rc)
189 {
190 PINFO("Unable to unregister VBoxVFS filesystem (%d)", rc);
191 return VERR_GENERAL_FAILURE;
192 }
193
194 g_oVBoxVFSHandle = 0;
195
196 PINFO("VBoxVFS filesystem successfully unregistered");
197 return VINF_SUCCESS;
198}
199
200
201/**
202 * Start this service.
203 */
204bool org_virtualbox_VBoxVFS::start(IOService *pProvider)
205{
206 int rc;
207
208 if (!IOService::start(pProvider))
209 return false;
210
211 /* Low level initialization should be performed only once */
212 if (!ASMAtomicCmpXchgBool(&g_fInstantiated, true, false))
213 {
214 IOService::stop(pProvider);
215 return false;
216 }
217
218 /* Wait for VBoxGuest to be started */
219 coreService = waitForCoreService();
220 if (coreService)
221 {
222 rc = vboxInit();
223 if (RT_SUCCESS(rc))
224 {
225 /* Connect to the host service. */
226 rc = vboxConnect(&g_vboxSFClient);
227 if (RT_SUCCESS(rc))
228 {
229 PINFO("VBox client connected");
230 rc = vboxCallSetUtf8(&g_vboxSFClient);
231 if (RT_SUCCESS(rc))
232 {
233 rc = VBoxVFSRegisterFilesystem();
234 if (RT_SUCCESS(rc))
235 {
236 registerService();
237 PINFO("Successfully started I/O kit class instance");
238 return true;
239 }
240 PERROR("Unable to register VBoxVFS filesystem");
241 }
242 else
243 {
244 PERROR("vboxCallSetUtf8 failed: rc=%d", rc);
245 }
246 vboxDisconnect(&g_vboxSFClient);
247 }
248 else
249 {
250 PERROR("Failed to get connection to host: rc=%d", rc);
251 }
252 vboxUninit();
253 }
254 else
255 {
256 PERROR("Failed to initialize low level library");
257 }
258 coreService->release();
259 }
260 else
261 {
262 PERROR("VBoxGuest KEXT not started");
263 }
264
265 ASMAtomicXchgBool(&g_fInstantiated, false);
266 IOService::stop(pProvider);
267
268 return false;
269}
270
271
272/**
273 * Stop this service.
274 */
275void org_virtualbox_VBoxVFS::stop(IOService *pProvider)
276{
277 int rc;
278
279 AssertReturnVoid(ASMAtomicReadBool(&g_fInstantiated));
280
281 rc = VBoxVFSUnRegisterFilesystem();
282 if (RT_FAILURE(rc))
283 {
284 PERROR("VBoxVFS filesystem is busy. Make sure all "
285 "shares are unmounted (%d)", rc);
286 }
287
288 vboxDisconnect(&g_vboxSFClient);
289 PINFO("VBox client disconnected");
290
291 vboxUninit();
292 PINFO("Low level uninit done");
293
294 coreService->release();
295 PINFO("VBoxGuest service released");
296
297 IOService::stop(pProvider);
298
299 ASMAtomicWriteBool(&g_fInstantiated, false);
300
301 PINFO("Successfully stopped I/O kit class instance");
302}
303
304
305/**
306 * Wait for VBoxGuest.kext to be started
307 */
308IOService * org_virtualbox_VBoxVFS::waitForCoreService(void)
309{
310 IOService *service;
311
312 OSDictionary *serviceToMatch = serviceMatching("org_virtualbox_VBoxGuest");
313 if (!serviceToMatch)
314 {
315 PINFO("unable to create matching dictionary");
316 return false;
317 }
318
319 /* Wait 10 seconds for VBoxGuest to be started */
320 service = waitForMatchingService(serviceToMatch, 10ULL * 1000000000ULL);
321 serviceToMatch->release();
322
323 return service;
324}
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