summaryrefslogtreecommitdiffstats
path: root/private/net/svcdlls/repl/server/cliquery.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/net/svcdlls/repl/server/cliquery.c')
-rw-r--r--private/net/svcdlls/repl/server/cliquery.c217
1 files changed, 217 insertions, 0 deletions
diff --git a/private/net/svcdlls/repl/server/cliquery.c b/private/net/svcdlls/repl/server/cliquery.c
new file mode 100644
index 000000000..0c12e2122
--- /dev/null
+++ b/private/net/svcdlls/repl/server/cliquery.c
@@ -0,0 +1,217 @@
+/*++
+
+Copyright (c) 1987-1993 Microsoft Corporation
+
+Module Name:
+
+ CliQuery.c
+
+Abstract:
+
+ Contains ReplClientRespondToQueryMsg().
+
+Author:
+
+ Ported from Lan Man 2.1
+
+Environment:
+
+ User mode only.
+ Requires ANSI C extensions: slash-slash comments, long external names.
+
+Revision History:
+
+ 26-Mar-1993 JohnRo
+ RAID 4267: Replicator has problems when work queue gets large.
+ (Extracted this code from ReplSyncerThread, now called by ClientThread.)
+
+--*/
+
+
+// These must be included first:
+
+#include <windows.h> // DWORD, etc.
+#include <lmcons.h> // NET_API_STATUS (needed by other header files).
+
+// These may be included in any order:
+
+#include <client.h> // My prototype, PCLIENT_LIST_REC, ReplSetTimeOut().
+#include <netdebug.h> // NetpKdPrint(), FORMAT_ equates, etc.
+#include <prefix.h> // PREFIX_ equates.
+#include <repldefs.h> // IF_DEBUG(), PQUERY_MSG, etc.
+
+
+VOID
+ReplClientRespondToQueryMsg(
+ IN PQUERY_MSG QueryMsg
+ )
+/*++
+
+Routine Description:
+
+ ReplClientRespondToQueryMsg is given a query message which the client
+ thread has received. This routine takes care of the message, which
+ may involve updating data structures and/or sending mailslot messages.
+
+Arguments:
+
+ QueryMsg - points to native format query message (DIR_SUPPORTED, etc).
+
+Return Value:
+
+ NONE.
+
+Threads:
+
+ Only called by client thread.
+
+--*/
+{
+ PCLIENT_LIST_REC ClientRecord;
+ DWORD MsgType;
+
+
+ NetpAssert( QueryMsg != NULL );
+
+ MsgType = QueryMsg->header.msg_type;
+
+
+
+ //
+ // Handle DIR_SUPPORTED
+ //
+ // Master still supports directory. This is a reply to IS_SUPPORTED
+ // query, sent after more than pulse * 2 time has passed
+ // without sync/pulse.
+ //
+
+ IF_DEBUG(CLIENT) {
+
+ NetpKdPrint(( PREFIX_REPL_CLIENT
+ "client received a query message "
+ "(type = " FORMAT_DWORD ").\n", MsgType ));
+
+ }
+
+ switch (MsgType) {
+ case DIR_SUPPORTED:
+
+ //
+ // If we still support this directory from this master,
+ // This puts us back to square 2, since no pulse/update
+ // have been received, status is not OK still
+ //
+
+ ACQUIRE_LOCK_SHARED( RCGlobalClientListLock );
+ if ((ClientRecord = ReplGetClientRec(QueryMsg->dir_name,
+ QueryMsg->header.sender )) != NULL) {
+
+ // Note: ReplSetTimeOut needs shared RCGlobalClientListLock.
+ ReplSetTimeOut(PULSE_1_TIMEOUT, ClientRecord);
+ }
+
+ RELEASE_LOCK( RCGlobalClientListLock );
+ break;
+
+
+ //
+ // Handle DIR-NOT-SUPPORTED
+ //
+ // As above but negative, so assume there was an END_REPL
+ // for this dir but it was missed
+ //
+
+ case DIR_NOT_SUPPORTED:
+
+ //
+ // Make sure repl record exists.
+ //
+
+
+ //
+ // If we still support this directory from this master,
+ // set signal to NO_MASTER.
+ //
+
+ ACQUIRE_LOCK_SHARED( RCGlobalClientListLock );
+ if ((ClientRecord = ReplGetClientRec(QueryMsg->dir_name,
+ QueryMsg->header.sender )) != NULL) {
+
+ // Note: ReplMasterDead needs lock (any kind) on
+ // RCGlobalClientListLock.
+ ReplMasterDead(ClientRecord);
+ }
+ RELEASE_LOCK( RCGlobalClientListLock );
+
+ break;
+
+
+ //
+ // Handle MASTER_DIR.
+ //
+ // A duplicate master sent a pulse for this directory and we queried
+ // our master to see if it is still our master. Our master replied
+ // that it is still the master.
+ //
+
+ case MASTER_DIR:
+
+ //
+ // If we still support this directory from this master,
+ // tell all other potential masters that they are duplicates,
+ // reset the timer to expect a pulse from the master.
+ //
+
+ ACQUIRE_LOCK_SHARED( RCGlobalClientListLock );
+ if ((ClientRecord = ReplGetClientRec(QueryMsg->dir_name,
+ QueryMsg->header.sender )) != NULL) {
+
+ // Note: ReplMultiMaster needs lock (any kind) on
+ // RCGlobalClientListLock.
+ ReplMultiMaster(OLD_MASTER_ACTIVE, ClientRecord,
+ QueryMsg->header.sender);
+
+ // Note: ReplSetTimeOut needs shared RCGlobalClientListLock.
+ ReplSetTimeOut(PULSE_1_TIMEOUT, ClientRecord);
+
+ }
+ RELEASE_LOCK( RCGlobalClientListLock );
+ break;
+
+
+ //
+ // Handle NOT_MASTER_DIR.
+ //
+ // Same as above but master replies it is no longer the master.
+ //
+
+ case NOT_MASTER_DIR:
+
+ //
+ // If we still support this directory from this master,
+ // set signal to NO_MASTER and remove dir from client_list.
+ //
+
+ ACQUIRE_LOCK_SHARED( RCGlobalClientListLock );
+ if ((ClientRecord = ReplGetClientRec(QueryMsg->dir_name,
+ QueryMsg->header.sender )) != NULL) {
+
+ // Note: ReplMultiMaster needs lock (any kind) on
+ // RCGlobalClientListLock.
+ ReplMultiMaster(OLD_MASTER_DONE, ClientRecord,
+ QueryMsg->header.sender);
+ }
+ RELEASE_LOCK( RCGlobalClientListLock );
+
+ break;
+
+
+ default:
+ NetpKdPrint(( PREFIX_REPL_CLIENT
+ "ReplClientRespondToQueryMsg: got invalid query message type "
+ FORMAT_DWORD ".\n", MsgType ));
+ break;
+
+ }
+
+}