From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:48 +0000 (-0700) Subject: Hgfs OSX Server: Reinstate checkpoint synchronization and process session X-Git-Tag: stable-10.2.0~130 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=087e74c292fcad86afa08d6a21b88cb57ab3bc7e;p=thirdparty%2Fopen-vm-tools.git Hgfs OSX Server: Reinstate checkpoint synchronization and process session First reinstate the server checkpoint synchronization routine by adding it into the table the HGFS server session callback table which is returned to the transports upon initialization. These transports will then call into the HGFS server when asked by the HGFS server manager which receives the check point synchronization calls. When processing the synchronization request for the operation type - freeze or thaw we must pass through the session information to the activation and deactivation calls into the file system change notification subsystem. These calls will require the session for register-unregister any active threads generating events. This change just plumbs through the session as the argument. Follow on changes will make use of the session argument passing it on to the event generating component. Bonus here is that we can delete an unwarranted global from the HGFS server. A to do comment is added to move the async globals into the HGFS server session object as they should be a per HGFS session and are useful only on a per session basis. No session then no need for them to be around and if the session does have asynchronous support then again will not be required. For example, if the transport does not support this behavior no need to check them. --- diff --git a/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h b/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h index b95e3138a..44bc4aa10 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h +++ b/open-vm-tools/lib/hgfsServer/hgfsDirNotify.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2009-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2009-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -57,8 +57,10 @@ typedef void HgfsNotifyEventReceiveCb(HgfsSharedFolderHandle sharedFolder, struct HgfsSessionInfo *session); HgfsInternalStatus HgfsNotify_Init(void); void HgfsNotify_Exit(void); -void HgfsNotify_Deactivate(HgfsNotifyActivateReason mode); -void HgfsNotify_Activate(HgfsNotifyActivateReason mode); +void HgfsNotify_Deactivate(HgfsNotifyActivateReason mode, + struct HgfsSessionInfo *session); +void HgfsNotify_Activate(HgfsNotifyActivateReason mode, + struct HgfsSessionInfo *session); HgfsSharedFolderHandle HgfsNotify_AddSharedFolder(const char *path, const char *shareName); diff --git a/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c b/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c index 3a19f1280..1b558727b 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c +++ b/open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 2009-2016 VMware, Inc. All rights reserved. + * Copyright (C) 2009-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -81,9 +81,9 @@ HgfsNotify_Exit(void) /* *----------------------------------------------------------------------------- * - * HgfsNotify_Deactivate -- + * HgfsNotify_Activate -- * - * Deactivates generating file system change notifications. + * Activates generating file system change notifications. * * Results: * None. @@ -95,7 +95,8 @@ HgfsNotify_Exit(void) */ void -HgfsNotify_Deactivate(HgfsNotifyActivateReason reason) // IN: reason unused +HgfsNotify_Activate(HgfsNotifyActivateReason reason, // IN: reason + struct HgfsSessionInfo *session) // IN: session { } @@ -103,9 +104,9 @@ HgfsNotify_Deactivate(HgfsNotifyActivateReason reason) // IN: reason unused /* *----------------------------------------------------------------------------- * - * HgfsNotify_Activate -- + * HgfsNotify_Deactivate -- * - * Activates generating file system change notifications. + * Deactivates generating file system change notifications. * * Results: * None. @@ -117,7 +118,8 @@ HgfsNotify_Deactivate(HgfsNotifyActivateReason reason) // IN: reason unused */ void -HgfsNotify_Activate(HgfsNotifyActivateReason reason) // IN: reason unused +HgfsNotify_Deactivate(HgfsNotifyActivateReason reason, // IN: reason + struct HgfsSessionInfo *session) // IN: session { } diff --git a/open-vm-tools/lib/hgfsServer/hgfsServer.c b/open-vm-tools/lib/hgfsServer/hgfsServer.c index 1087000dc..3d5ae7c5d 100644 --- a/open-vm-tools/lib/hgfsServer/hgfsServer.c +++ b/open-vm-tools/lib/hgfsServer/hgfsServer.c @@ -234,6 +234,7 @@ static void HgfsServerSessionInvalidateObjects(void *clientData, DblLnkLst_Links *shares); static uint32 HgfsServerSessionInvalidateInactiveSessions(void *clientData); static void HgfsServerSessionSendComplete(HgfsPacket *packet, void *clientData); +static void HgfsServerSessionQuiesce(void * clientData, HgfsQuiesceOp quiesceOp); /* * Callback table passed to transport and any channels. @@ -247,6 +248,7 @@ static const HgfsServerCallbacks gHgfsServerCBTable = { HgfsServerSessionInvalidateObjects, HgfsServerSessionInvalidateInactiveSessions, HgfsServerSessionSendComplete, + HgfsServerSessionQuiesce, }, }; @@ -256,8 +258,6 @@ static MXUserExclLock *gHgfsSharedFoldersLock = NULL; /* List of shared folders nodes. */ static DblLnkLst_Links gHgfsSharedFoldersList; -static Bool gHgfsInitialized = FALSE; - /* * Number of active sessions that support change directory notification. HGFS server * needs to maintain up-to-date shared folders list when there is @@ -403,7 +403,7 @@ static void HgfsServerRemoveDirNotifyWatch(HgfsInputParam *input); static void HgfsServerSessionGet(HgfsSessionInfo *session) // IN: session context { - ASSERT(session); + ASSERT(session && Atomic_Read(&session->refCount) != 0); Atomic_Inc(&session->refCount); } @@ -3948,7 +3948,6 @@ HgfsServer_InitState(const HgfsServerCallbacks **callbackTable, // IN/OUT: our gHgfsCfgSettings.flags &= ~HGFS_CONFIG_OPLOCK_ENABLED; } } - gHgfsInitialized = TRUE; } else { HgfsServer_ExitState(); // Cleanup partially initialized state } @@ -3980,8 +3979,6 @@ HgfsServer_InitState(const HgfsServerCallbacks **callbackTable, // IN/OUT: our void HgfsServer_ExitState(void) { - gHgfsInitialized = FALSE; - if (0 != (gHgfsCfgSettings.flags & HGFS_CONFIG_OPLOCK_ENABLED)) { HgfsServerOplockDestroy(); } @@ -4501,10 +4498,8 @@ HgfsServerAllocateSession(HgfsTransportSessionInfo *transportSession, // IN: /* Initialize search freelist. */ DblLnkLst_Init(&session->searchFreeList); - Atomic_Write(&session->refCount, 0); - /* Give our session a reference to hold while we are open. */ - HgfsServerSessionGet(session); + Atomic_Write(&session->refCount, 1); /* Allocate array of searches and add them to free list. */ session->numSearches = NUM_SEARCHES; @@ -4850,7 +4845,7 @@ HgfsServerSessionSendComplete(HgfsPacket *packet, // IN/OUT: Hgfs packet /* *---------------------------------------------------------------------------- * - * HgfsServer_Quiesce -- + * HgfsServerSessionQuiesce -- * * The function is called when VM is about to take a snapshot and * when creation of the snapshot completed. When the freeze is TRUE the @@ -4868,30 +4863,58 @@ HgfsServerSessionSendComplete(HgfsPacket *packet, // IN/OUT: Hgfs packet *---------------------------------------------------------------------------- */ -void -HgfsServer_Quiesce(Bool freeze) // IN: +static void +HgfsServerSessionQuiesce(void *clientData, // IN: transport and session + HgfsQuiesceOp quiesceOp) // IN: operation { - if (!gHgfsInitialized) { - return; - } + HgfsTransportSessionInfo *transportSession = clientData; + DblLnkLst_Links *curr; - if (freeze) { - /* Suspend background activity. */ - if (gHgfsDirNotifyActive) { - HgfsNotify_Deactivate(HGFS_NOTIFY_REASON_SERVER_SYNC); - } - /* Wait for outstanding asynchronous requests to complete. */ - MXUser_AcquireExclLock(gHgfsAsyncLock); - while (Atomic_Read(&gHgfsAsyncCounter)) { - MXUser_WaitCondVarExclLock(gHgfsAsyncLock, gHgfsAsyncVar); - } - MXUser_ReleaseExclLock(gHgfsAsyncLock); - } else { - /* Resume background activity. */ - if (gHgfsDirNotifyActive) { - HgfsNotify_Activate(HGFS_NOTIFY_REASON_SERVER_SYNC); + LOG(4, ("%s: Beginning\n", __FUNCTION__)); + + MXUser_AcquireExclLock(transportSession->sessionArrayLock); + + DblLnkLst_ForEach(curr, &transportSession->sessionArray) { + HgfsSessionInfo *session = DblLnkLst_Container(curr, HgfsSessionInfo, links); + + switch(quiesceOp) { + case HGFS_QUIESCE_FREEZE: + /* Suspend background activity. */ + LOG(8, ("%s: Halt file system activity for session %p\n", + __FUNCTION__, session)); + + if (gHgfsDirNotifyActive) { + HgfsNotify_Deactivate(HGFS_NOTIFY_REASON_SERVER_SYNC, session); + } + + /* + * XXX - TODO move these globals into the session! + * Wait for outstanding asynchronous requests to complete. + */ + MXUser_AcquireExclLock(gHgfsAsyncLock); + while (Atomic_Read(&gHgfsAsyncCounter)) { + MXUser_WaitCondVarExclLock(gHgfsAsyncLock, gHgfsAsyncVar); + } + MXUser_ReleaseExclLock(gHgfsAsyncLock); + break; + + case HGFS_QUIESCE_THAW: + /* Resume background activity. */ + LOG(8, ("%s: Resume file system activity for session %p\n", + __FUNCTION__, session)); + + if (gHgfsDirNotifyActive) { + HgfsNotify_Activate(HGFS_NOTIFY_REASON_SERVER_SYNC, session); + } + break; + + default: + NOT_REACHED(); } + } + MXUser_ReleaseExclLock(transportSession->sessionArrayLock); + LOG(4, ("%s: Ending\n", __FUNCTION__)); } diff --git a/open-vm-tools/lib/include/hgfsServer.h b/open-vm-tools/lib/include/hgfsServer.h index 68f6c975b..d8509c12d 100644 --- a/open-vm-tools/lib/include/hgfsServer.h +++ b/open-vm-tools/lib/include/hgfsServer.h @@ -1,5 +1,5 @@ /********************************************************* - * Copyright (C) 1998-2016 VMware, Inc. All rights reserved. + * Copyright (C) 1998-2017 VMware, Inc. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published @@ -217,9 +217,6 @@ Bool HgfsServer_ShareAccessCheck(HgfsOpenMode accessMode, uint32 HgfsServer_GetHandleCounter(void); void HgfsServer_SetHandleCounter(uint32 newHandleCounter); - -void HgfsServer_Quiesce(Bool freeze); - #if defined(__cplusplus) } // extern "C" #endif