247 lines
5.1 KiB
C
247 lines
5.1 KiB
C
/*++
|
||
|
||
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 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;
|
||
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
|
||
);
|
||
|
||
//
|
||
// 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
|
||
);
|
||
|
||
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
|
||
);
|
||
|
||
BOOL
|
||
GumpTryLockingUpdate(
|
||
IN GUM_UPDATE_TYPE Type,
|
||
IN DWORD NodeId,
|
||
IN DWORD Sequence
|
||
);
|
||
|
||
VOID
|
||
GumpReUpdate(
|
||
IN GUM_UPDATE_TYPE UpdateType,
|
||
IN DWORD EndId
|
||
);
|
||
|
||
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
|
||
);
|
||
|
||
|
||
|