From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:52 +0000 (-0700) Subject: Hgfs OSX Server: Create and use server callback table for change notifications X-Git-Tag: stable-10.2.0~82 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a08aedc1a3bfbe666896d13380265f3948684ac;p=thirdparty%2Fopen-vm-tools.git Hgfs OSX Server: Create and use server callback table for change notifications There are now three different callbacks into the Hgfs server from the file change notification component. So we now pass these in a table to the nofify module when it is initialized instead of ad hoc. Previously, the same callback is passed for every subscriber watch event and therefore duplicated and stored in each subscriber. Note that the feature is currently switched off by default until these changes are complete. A user will explicitly have to enable the VMX file setting and would cause a VMX assert to be triggered. Details: - The server now creates a table for its notification callbacks and passes it to the notify initialization function. - The server now includes the async thread registration callbacks previously ifdef'd out. - The Notify_Init function APIs are updated to reflect the new argument for callbacks. - The HgfsNotify_AddSubscriber argument does not include the callback as it is now passed once at the initialization time. - The HgfsNotifyEventReceiveCb type has been modified now it is an entry in the callback table. - The subscriber callback function call is now validated to be non-NULL before calling. - The Mac notify module adds the server callback table to its FS event context which is passed to the event generating submodule for the Mac implementation. - The Mac notify module adds its own FS event callbacks for thread register and unregister called from the FS event module when registering and unregistering its FS event thread. --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h b/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h index 44bc4aa10..4fe9daeef 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h +++ b/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h @@ -49,13 +49,22 @@ typedef enum { HGFS_NOTIFY_REASON_SUBSCRIBERS, } HgfsNotifyActivateReason; -/* This is a callback that is implemented in hgfsServer.c */ -typedef void HgfsNotifyEventReceiveCb(HgfsSharedFolderHandle sharedFolder, - HgfsSubscriberHandle subscriber, - char *name, - uint32 mask, - struct HgfsSessionInfo *session); -HgfsInternalStatus HgfsNotify_Init(void); +/* These are the callbacks that are implemented in hgfsServer.c */ +typedef void (*HgfsNotifyRegisterThreadCb)(struct HgfsSessionInfo *session); +typedef void (*HgfsNotifyUnregisterThreadCb)(struct HgfsSessionInfo *session); +typedef void (*HgfsNotifyEventReceiveCb)(HgfsSharedFolderHandle sharedFolder, + HgfsSubscriberHandle subscriber, + char *name, + uint32 mask, + struct HgfsSessionInfo *session); + +typedef struct HgfsServerNotifyCallbacks { + HgfsNotifyRegisterThreadCb registerThread; + HgfsNotifyUnregisterThreadCb unregisterThread; + HgfsNotifyEventReceiveCb eventReceive; +} HgfsServerNotifyCallbacks; + +HgfsInternalStatus HgfsNotify_Init(const HgfsServerNotifyCallbacks *serverCbData); void HgfsNotify_Exit(void); void HgfsNotify_Deactivate(HgfsNotifyActivateReason mode, struct HgfsSessionInfo *session); @@ -68,7 +77,6 @@ HgfsSubscriberHandle HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolde const char *path, uint32 eventFilter, uint32 recursive, - HgfsNotifyEventReceiveCb notify, struct HgfsSessionInfo *session); Bool HgfsNotify_RemoveSharedFolder(HgfsSharedFolderHandle sharedFolder); diff --git a/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c b/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c index 1b558727b..4ce325ff5 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c +++ b/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c @@ -50,7 +50,7 @@ */ HgfsInternalStatus -HgfsNotify_Init(void) +HgfsNotify_Init(const HgfsServerNotifyCallbacks *serverCbData) // IN: serverCbData unused { return HGFS_ERROR_NOT_SUPPORTED; } @@ -172,7 +172,6 @@ HgfsNotify_AddSubscriber(HgfsSharedFolderHandle sharedFolder, // IN: shared fold const char *path, // IN: relative path uint32 eventFilter, // IN: event filter uint32 recursive, // IN: look in subfolders - HgfsNotifyEventReceiveCb eventCb, // IN notification callback struct HgfsSessionInfo *session) // IN: server context { return HGFS_INVALID_SUBSCRIBER_HANDLE; diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index e008ea42e..5d6660e99 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -245,6 +245,24 @@ static const HgfsServerCallbacks gHgfsServerCBTable = { }, }; + +static void HgfsServerNotifyRegisterThreadCb(struct HgfsSessionInfo *session); +static void HgfsServerNotifyUnregisterThreadCb(struct HgfsSessionInfo *session); +static void HgfsServerNotifyReceiveEventCb(HgfsSharedFolderHandle sharedFolder, + HgfsSubscriberHandle subscriber, + char* fileName, + uint32 mask, + struct HgfsSessionInfo *session); + +/* + * Callback table passed to the directory change notification component. + */ +static const HgfsServerNotifyCallbacks gHgfsServerNotifyCBTable = { + HgfsServerNotifyRegisterThreadCb, + HgfsServerNotifyUnregisterThreadCb, + HgfsServerNotifyReceiveEventCb, +}; + /* Lock that protects shared folders list. */ static MXUserExclLock *gHgfsSharedFoldersLock = NULL; @@ -340,11 +358,6 @@ static Bool HgfsHandle2NotifyInfo(HgfsHandle handle, char **fileName, size_t *fileNameSize, HgfsSharedFolderHandle *folderHandle); -static void HgfsServerNotifyReceiveEventCb(HgfsSharedFolderHandle sharedFolder, - HgfsSubscriberHandle subscriber, - char* fileName, - uint32 mask, - struct HgfsSessionInfo *session); static void HgfsFreeSearchDirents(HgfsSearch *search); static HgfsInternalStatus @@ -3932,7 +3945,7 @@ HgfsServer_InitState(const HgfsServerCallbacks **callbackTable, // IN/OUT: our *callbackTable = &gHgfsServerCBTable; if (0 != (gHgfsCfgSettings.flags & HGFS_CONFIG_NOTIFY_ENABLED)) { - gHgfsDirNotifyActive = HgfsNotify_Init() == HGFS_STATUS_SUCCESS; + gHgfsDirNotifyActive = HgfsNotify_Init(&gHgfsServerNotifyCBTable) == HGFS_STATUS_SUCCESS; Log("%s: initialized notification %s.\n", __FUNCTION__, (gHgfsDirNotifyActive ? "active" : "inactive")); } @@ -7828,7 +7841,7 @@ HgfsServerSetDirWatchByHandle(HgfsInputParam *input, // IN: Input params LOG(4, ("%s: adding a subscriber on shared folder handle %#x\n", __FUNCTION__, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, fileName, events, watchTree, - HgfsServerNotifyReceiveEventCb, input->session); + input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; LOG(4, ("%s: result of add subscriber id %"FMT64"x status %u\n", __FUNCTION__, @@ -7915,7 +7928,7 @@ HgfsServerSetDirWatchByName(HgfsInputParam *input, // IN: Input params LOG(8, ("%s: session %p id %"FMT64"x on share hnd %#x\n", __FUNCTION__, input->session, input->session->sessionId, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, tempBuf, events, - watchTree, HgfsServerNotifyReceiveEventCb, + watchTree, input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; @@ -7929,12 +7942,11 @@ HgfsServerSetDirWatchByName(HgfsInputParam *input, // IN: Input params } else { LOG(8, ("%s: adding subscriber on share hnd %#x\n", __FUNCTION__, sharedFolder)); *watchId = HgfsNotify_AddSubscriber(sharedFolder, "", events, watchTree, - HgfsServerNotifyReceiveEventCb, input->session); status = (HGFS_INVALID_SUBSCRIBER_HANDLE == *watchId) ? HGFS_ERROR_INTERNAL : HGFS_ERROR_SUCCESS; - LOG(8, ("%s: adding subscriber on share hnd %#x result %u\n", __FUNCTION__, - sharedFolder, status)); + LOG(8, ("%s: adding subscriber on share hnd %#x watchId %"FMT64"x result %u\n", + __FUNCTION__, sharedFolder, *watchId, status)); } } else if (HGFS_NAME_STATUS_INCOMPLETE_BASE == nameStatus) { LOG(4, ("%s: Notification for root share is not supported yet\n", @@ -9191,7 +9203,6 @@ HgfsServerGetTargetRelativePath(const char* source, // IN: source file name } -#ifdef HGFS_NOTIFY_THREAD_REGISTER_SUPPORTED /* *----------------------------------------------------------------------------- * @@ -9219,6 +9230,8 @@ HgfsServerNotifyRegisterThreadCb(struct HgfsSessionInfo *session) // IN: ses ASSERT(session); transportSession = session->transportSession; + LOG(4, ("%s: Registering thread on session %"FMT64"x\n", __FUNCTION__, session->sessionId)); + if (transportSession->channelCbTable->registerThread != NULL) { transportSession->channelCbTable->registerThread(); } @@ -9252,11 +9265,12 @@ HgfsServerNotifyUnregisterThreadCb(struct HgfsSessionInfo *session) // IN: s ASSERT(session); transportSession = session->transportSession; + LOG(4, ("%s: Unregistering thread on session %"FMT64"x\n", __FUNCTION__, session->sessionId)); + if (transportSession->channelCbTable->unregisterThread != NULL) { transportSession->channelCbTable->unregisterThread(); } } -#endif // HGFS_NOTIFY_THREAD_REGISTER_SUPPORTED /*