/*********************************************************
- * 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
/*
*-----------------------------------------------------------------------------
*
- * HgfsNotify_Deactivate --
+ * HgfsNotify_Activate --
*
- * Deactivates generating file system change notifications.
+ * Activates generating file system change notifications.
*
* Results:
* None.
*/
void
-HgfsNotify_Deactivate(HgfsNotifyActivateReason reason) // IN: reason unused
+HgfsNotify_Activate(HgfsNotifyActivateReason reason, // IN: reason
+ struct HgfsSessionInfo *session) // IN: session
{
}
/*
*-----------------------------------------------------------------------------
*
- * HgfsNotify_Activate --
+ * HgfsNotify_Deactivate --
*
- * Activates generating file system change notifications.
+ * Deactivates generating file system change notifications.
*
* Results:
* None.
*/
void
-HgfsNotify_Activate(HgfsNotifyActivateReason reason) // IN: reason unused
+HgfsNotify_Deactivate(HgfsNotifyActivateReason reason, // IN: reason
+ struct HgfsSessionInfo *session) // IN: session
{
}
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.
HgfsServerSessionInvalidateObjects,
HgfsServerSessionInvalidateInactiveSessions,
HgfsServerSessionSendComplete,
+ HgfsServerSessionQuiesce,
},
};
/* 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
static void
HgfsServerSessionGet(HgfsSessionInfo *session) // IN: session context
{
- ASSERT(session);
+ ASSERT(session && Atomic_Read(&session->refCount) != 0);
Atomic_Inc(&session->refCount);
}
gHgfsCfgSettings.flags &= ~HGFS_CONFIG_OPLOCK_ENABLED;
}
}
- gHgfsInitialized = TRUE;
} else {
HgfsServer_ExitState(); // Cleanup partially initialized state
}
void
HgfsServer_ExitState(void)
{
- gHgfsInitialized = FALSE;
-
if (0 != (gHgfsCfgSettings.flags & HGFS_CONFIG_OPLOCK_ENABLED)) {
HgfsServerOplockDestroy();
}
/* 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;
/*
*----------------------------------------------------------------------------
*
- * 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
*----------------------------------------------------------------------------
*/
-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__));
}