You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
284 lines
6.2 KiB
284 lines
6.2 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
gump.h
|
|
|
|
Abstract:
|
|
|
|
Private header file for the Global Update Manager (GUM) component
|
|
of the NT Cluster Service
|
|
|
|
Author:
|
|
|
|
John Vert (jvert) 17-Apr-1996
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "service.h"
|
|
|
|
#define LOG_CURRENT_MODULE LOG_MODULE_GUM
|
|
|
|
//
|
|
//
|
|
// Structures and type definitions local to the GUM
|
|
//
|
|
typedef struct _GUM_RECEIVER {
|
|
struct _GUM_RECEIVER *Next;
|
|
PGUM_UPDATE_ROUTINE UpdateRoutine;
|
|
PGUM_LOG_ROUTINE LogRoutine;
|
|
DWORD DispatchCount;
|
|
PGUM_DISPATCH_ENTRY DispatchTable;
|
|
PGUM_VOTE_ROUTINE VoteRoutine;
|
|
} GUM_RECEIVER, *PGUM_RECEIVER;
|
|
|
|
typedef struct _GUM_INFO {
|
|
PGUM_RECEIVER Receivers;
|
|
BOOL Joined;
|
|
BOOL ActiveNode[ClusterMinNodeId + ClusterDefaultMaxNodes];
|
|
} GUM_INFO, *PGUM_INFO;
|
|
|
|
extern GUM_INFO GumTable[GumUpdateMaximum];
|
|
extern CRITICAL_SECTION GumpLock;
|
|
extern DWORD GumNodeGeneration[ClusterMinNodeId + ClusterDefaultMaxNodes];
|
|
|
|
extern DWORD GumpSequence;
|
|
extern CRITICAL_SECTION GumpUpdateLock;
|
|
extern CRITICAL_SECTION GumpSendUpdateLock;
|
|
extern CRITICAL_SECTION GumpRpcLock;
|
|
extern PVOID GumpLastBuffer;
|
|
extern DWORD GumpLastContext;
|
|
extern DWORD GumpLastBufferLength;
|
|
extern DWORD GumpLastUpdateType;
|
|
extern LIST_ENTRY GumpLockQueue;
|
|
extern DWORD GumpLockingNode;
|
|
extern DWORD GumpLockerNode;
|
|
extern BOOL GumpLastBufferValid;
|
|
extern RPC_BINDING_HANDLE GumpRpcBindings[
|
|
ClusterMinNodeId + ClusterDefaultMaxNodes
|
|
];
|
|
extern RPC_BINDING_HANDLE GumpReplayRpcBindings[
|
|
ClusterMinNodeId + ClusterDefaultMaxNodes
|
|
];
|
|
|
|
//
|
|
// structure used to allow GUM clients to wait for
|
|
// a node to transition from active to inactive.
|
|
// Waited on by GumpCommFailure.
|
|
// Set by GumpEventHandler.
|
|
// All access to WaiterCount should be serialized by
|
|
// GumpLock
|
|
//
|
|
typedef struct _GUM_NODE_WAIT {
|
|
DWORD WaiterCount;
|
|
HANDLE hSemaphore;
|
|
} GUM_NODE_WAIT, *PGUM_NODE_WAIT;
|
|
|
|
extern GUM_NODE_WAIT GumNodeWait[ClusterMinNodeId + ClusterDefaultMaxNodes];
|
|
|
|
//
|
|
// Define structure used for enqueuing waiters for the GUM lock.
|
|
//
|
|
#define GUM_WAIT_SYNC 0
|
|
#define GUM_WAIT_ASYNC 1
|
|
|
|
typedef struct _GUM_WAITER {
|
|
LIST_ENTRY ListEntry;
|
|
DWORD WaitType;
|
|
DWORD NodeId;
|
|
DWORD GenerationNum;
|
|
union {
|
|
struct {
|
|
HANDLE WakeEvent;
|
|
} Sync;
|
|
struct {
|
|
DWORD Context;
|
|
DWORD BufferLength;
|
|
DWORD BufferPtr;
|
|
PUCHAR Buffer;
|
|
} Async;
|
|
};
|
|
} GUM_WAITER, *PGUM_WAITER;
|
|
|
|
//
|
|
// Private GUM routines
|
|
//
|
|
DWORD
|
|
WINAPI
|
|
GumpSyncEventHandler(
|
|
IN CLUSTER_EVENT Event,
|
|
IN PVOID Context
|
|
);
|
|
|
|
DWORD
|
|
WINAPI
|
|
GumpEventHandler(
|
|
IN CLUSTER_EVENT Event,
|
|
IN PVOID Context
|
|
);
|
|
|
|
DWORD
|
|
WINAPI
|
|
GumpDispatchUpdate(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD Context,
|
|
IN BOOL IsLocker,
|
|
IN BOOL SourceNode,
|
|
IN DWORD BufferLength,
|
|
IN PUCHAR Buffer
|
|
);
|
|
|
|
DWORD
|
|
GumpUpdateRemoteNode(
|
|
IN PRPC_ASYNC_STATE AsyncState,
|
|
IN DWORD RemoteNodeId,
|
|
IN DWORD UpdateType,
|
|
IN DWORD Context,
|
|
IN DWORD Sequence,
|
|
IN DWORD BufferLength,
|
|
IN UCHAR Buffer[]
|
|
);
|
|
|
|
//
|
|
// Node Generation Numbers
|
|
//
|
|
DWORD
|
|
GumpGetNodeGenNum(PGUM_INFO GumInfo, DWORD NodeId);
|
|
|
|
void
|
|
GumpWaitNodeDown(DWORD NodeId, DWORD gennum);
|
|
|
|
BOOL
|
|
GumpDispatchStart(DWORD NodeId, DWORD gennum);
|
|
|
|
void
|
|
GumpDispatchEnd(DWORD NodeId, DWORD gennum);
|
|
|
|
void
|
|
GumpDispatchAbort();
|
|
|
|
//
|
|
// Macros to serialize usage of RPC handles. We don't use one lock per node
|
|
// because a new sender might grap the RPC to new locker and previous sender
|
|
// wants handle to send update. But previous sender owns updatelock and we
|
|
// will deadlock. So, we just keep things simple for now and use one lock
|
|
// to serialize all RPC calls.
|
|
//
|
|
#define GumpStartRpc(nodeid) EnterCriticalSection(&GumpRpcLock)
|
|
#define GumpEndRpc(nodeid) LeaveCriticalSection(&GumpRpcLock)
|
|
|
|
//
|
|
// Locker interface
|
|
//
|
|
|
|
VOID
|
|
GumpPromoteToLocker(
|
|
VOID
|
|
);
|
|
|
|
DWORD
|
|
GumpDoLockingUpdate(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD NodeId,
|
|
OUT LPDWORD Sequence,
|
|
OUT LPDWORD pGeneratioNum
|
|
);
|
|
|
|
DWORD
|
|
GumpDoLockingPost(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD NodeId,
|
|
OUT LPDWORD Sequence,
|
|
IN DWORD Context,
|
|
IN DWORD BufferLength,
|
|
IN DWORD BufferPtr,
|
|
IN UCHAR Buffer[]
|
|
);
|
|
|
|
VOID
|
|
GumpDeliverPosts(
|
|
IN DWORD FirstNodeId,
|
|
IN GUM_UPDATE_TYPE UpdateType,
|
|
IN DWORD Sequence,
|
|
IN DWORD Context,
|
|
IN DWORD BufferLength,
|
|
IN PVOID Buffer // THIS WILL BE FREED
|
|
);
|
|
|
|
VOID
|
|
GumpDoUnlockingUpdate(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD Sequence,
|
|
IN DWORD NodeId,
|
|
IN DWORD GenerationNum
|
|
);
|
|
|
|
BOOL
|
|
GumpTryLockingUpdate(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD NodeId,
|
|
IN DWORD Sequence,
|
|
OUT LPDWORD pdwGenerationNum
|
|
);
|
|
|
|
error_status_t
|
|
GumpAttemptLockingUpdate(
|
|
IN DWORD NodeId,
|
|
IN DWORD Type,
|
|
IN DWORD Context,
|
|
IN DWORD Sequence,
|
|
IN DWORD BufferLength,
|
|
IN UCHAR Buffer[],
|
|
OUT LPDWORD pdwGenerationNum
|
|
);
|
|
|
|
VOID
|
|
GumpReUpdate(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
GumpCommFailure(
|
|
IN PGUM_INFO GumInfo,
|
|
IN DWORD NodeId,
|
|
IN DWORD ErrorCode,
|
|
IN BOOL Wait
|
|
);
|
|
|
|
//internal routines for dispatching collection of votes
|
|
DWORD GumpCollectVotes(
|
|
IN PGUM_VOTE_DECISION_CONTEXT pVoteContext,
|
|
IN DWORD dwVoteBufSize,
|
|
OUT PBYTE pVoteBuffer,
|
|
OUT LPDWORD pdwNumVotes,
|
|
OUT BOOL *pbDidAllActiveNodesVote
|
|
);
|
|
|
|
|
|
DWORD
|
|
WINAPI
|
|
GumpDispatchVote(
|
|
IN GUM_UPDATE_TYPE Type,
|
|
IN DWORD Context,
|
|
IN DWORD dwInputBufLength,
|
|
IN PUCHAR pInputBuf,
|
|
IN DWORD dwVoteLength,
|
|
OUT PUCHAR pVoteBuf
|
|
);
|
|
|
|
//join interfaces
|
|
error_status_t
|
|
GumpAttemptJoinUpdate(
|
|
IN DWORD JoiningId,
|
|
IN DWORD Type,
|
|
IN DWORD Context,
|
|
IN DWORD Sequence,
|
|
IN DWORD BufferLength,
|
|
IN UCHAR Buffer[],
|
|
IN LPDWORD pdwGenerationNum
|
|
);
|
|
|
|
|