VirtualBox

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

Last change on this file since 68643 was 68584, checked in by vboxsync, 7 years ago

merging vbglioc r117762: darwin/vboxfs fixes

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