]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Hgfs OSX Server: Reinstate checkpoint synchronization and process session
authorOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:48 +0000 (11:23 -0700)
committerOliver Kurth <okurth@vmware.com>
Fri, 15 Sep 2017 18:23:48 +0000 (11:23 -0700)
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.

open-vm-tools/lib/hgfsServer/hgfsDirNotify.h
open-vm-tools/lib/hgfsServer/hgfsDirNotifyStub.c
open-vm-tools/lib/hgfsServer/hgfsServer.c
open-vm-tools/lib/include/hgfsServer.h

index b95e3138a7796de96d222ead74174de2d2643d4f..44bc4aa10f60c971e2ecb2ef763eed5df072b1cc 100644 (file)
@@ -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);
index 3a19f1280252b1f9be48e5cc44fd61d4be039010..1b558727bea8e2d1b64663e7a27004e71ccb98df 100644 (file)
@@ -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
 {
 }
 
index 1087000dc7c32aae5fa3c4c5527af62902036393..3d5ae7c5d08a07f5c7275ae59271dd9367e783c8 100644 (file)
@@ -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__));
 }
 
 
index 68f6c975b101ca0147461354e6c6c2fefe902cce..d8509c12d55fd650d73374ed652ab0e649e8772e 100644 (file)
@@ -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