|
|
#ifndef _FMP_H
#define _FMP_H
/*++
Copyright (c) 1996-1999 Microsoft Corporation
Module Name:
fmp.h
Abstract:
Private data structures and procedure prototypes for the Failover Manager subcomponent of the NT Cluster Service
Author:
John Vert (jvert) 7-Feb-1996
Revision History:
--*/
#define UNICODE 1
#include "nt.h"
#include "ntrtl.h"
#include "nturtl.h"
#define QFS_DO_NOT_UNMAP_WIN32
#include "service.h"
#include "clusudef.h"
#include "rm_rpc.h"
#include "stdlib.h"
#define LOG_CURRENT_MODULE LOG_MODULE_FM
#define FMGUM 1
#define RMNOTIFY 2
#define RESOURCE 3
#define FMAPI 4
#define GROUP 5
#define RECV 6
#define EVENT 7
#define FMCLIENT 8
#define TREE 9
#define FMINIT 10
#define IOCTL 11
#define FMREG 12
#define RESMONF 13 //for resmon.c
#define WORKER 14
#define RESFAIL 15
#define GROUPARB 16
#define MONITOR 17
//
// RPC timeout constant (borrowed from nmp.h)
// Node Intracluster RPC record/cancellation routines.
// Useful to terminate outstanding RPCs to failed nodes.
//
#define FM_RPC_TIMEOUT 45000 // 45 secs
//
// Monitor shutdown timeout
//
#define FM_MONITOR_SHUTDOWN_TIMEOUT 15 * 60 * 1000 // 15 min
typedef CLUSTER_EVENT FM_EVENT;
//fm event handling
//events generated by the service
#define FM_EVENT_NODE_DOWN 1
#define FM_EVENT_SHUTDOWN 2
#define FM_EVENT_RESOURCE_ADDED 3
#define FM_EVENT_RESOURCE_DELETED 4
#define FM_EVENT_GROUP_FAILED 5
#define FM_EVENT_NODE_ADDED 6
#define FM_EVENT_CLUSTER_PROPERTY_CHANGE 7
#define FM_EVENT_RESOURCE_PROPERTY_CHANGE 8
//#define FM_EVENT_GROUP_PROPERTY_CHANGE 9
#define FM_EVENT_RESOURCE_CHANGE 10
#define FM_EVENT_NODE_EVICTED 11
//events generated due to resource dll's
#define FM_EVENT_RES_RESOURCE_TRANSITION 128
#define FM_EVENT_RES_RESOURCE_FAILED 129
//generated when DealyedRestart timer fires
#define FM_EVENT_RES_RETRY_TIMER 131
#define FM_EVENT_INTERNAL_PROP_GROUP_STATE 256
#define FM_EVENT_INTERNAL_SHUTDOWN_CLEANUP 258
#define FM_EVENT_INTERNAL_RETRY_ONLINE 259
#define FM_EVENT_INTERNAL_RESOURCE_CHANGE_PARAMS 260
#define FM_EVENT_INTERNAL_ONLINE_GROUPLIST 261
#define FM_EVENT_RESOURCE_NAME_CHANGE 262
// timer activities ( in msec)
#define FM_TIMER_RESLIST_ONLINE_RETRY 1 * 60 * 1000 //( 1 minute)
//
// Global defines
//
#define FMP_GROUP_NAME L"Group"
#define FMP_RESOURCE_NAME L"Resource"
#define FMP_RESOURCE_TYPE_NAME L"ResType"
#define FMP_GROUP_SIGNATURE 'rGmF'
#define FMP_RESOURCE_SIGNATURE 'sRmF'
#define FMP_RESOURCE_TYPE_SIGNATURE 'tRmF'
#define FMP_RESMON_SIGNATURE 'mRmF'
#define PENDING_TIMEOUT (4*1000) // retry pending operations every 4 secs
//
// Globals
//
extern HANDLE FmpShutdownEvent; extern DWORD FmpFMOnline; extern DWORD FmpFMFormPhaseProcessing; extern DWORD FmpFMGroupsInited; extern BOOL FmpShutdown; extern BOOL FmpMajorEvent;
extern CRITICAL_SECTION FmpResourceLock; extern CRITICAL_SECTION FmpGroupLock; extern CRITICAL_SECTION FmpMonitorLock;
//
// 185575: remove use of unique RPC binding handles.
//
//extern CRITICAL_SECTION FmpBindingLock;
extern CL_QUEUE FmpWorkQueue;
//global data relating to the quorum resource
#if NO_SHARED_LOCKS
extern CRITICAL_SECTION gQuoLock; #else
extern RTL_RESOURCE gQuoLock; #endif
#if NO_SHARED_LOCKS
extern CRITICAL_SECTION gQuoChangeLock; #else
extern RTL_RESOURCE gQuoChangeLock; #endif
#if NO_SHARED_LOCKS
extern CRITICAL_SECTION gResTypeLock; #else
extern RTL_RESOURCE gResTypeLock; #endif
extern PFM_RESOURCE gpQuoResource; extern HANDLE ghQuoOnlineEvent; extern DWORD gdwQuoBlockingResources;
extern RPC_BINDING_HANDLE FmpRpcBindings[]; extern RPC_BINDING_HANDLE FmpRpcQuorumBindings[];
extern RESUTIL_PROPERTY_ITEM FmpGroupCommonProperties[];
typedef struct FM_NODE{ DWORD dwNodeDownProcessingInProgress; PNM_NODE pNode; DWORD dwNodeDownProcessingThreadId; }FM_NODE, *PFM_NODE;
extern PFM_NODE gFmpNodeArray; extern LIST_ENTRY g_leFmpMonitorListHead; extern DWORD FmpInitialized;
//
// Macros
//
#define FmpMustBeOnline( ) \
if ( !FmpFMOnline ) { \ if ( FmpShutdown ) { \ return(ERROR_CLUSTER_NODE_SHUTTING_DOWN); \ } else { \ return(ERROR_CLUSTER_NODE_NOT_READY); \ } \ }
#define FmpMustBeOnlineEx( ReturnValue ) \
if ( !FmpFMOnline ) { \ if ( FmpShutdown ) { \ SetLastError(ERROR_CLUSTER_NODE_SHUTTING_DOWN); \ } else { \ SetLastError(ERROR_CLUSTER_NODE_NOT_READY); \ } \ return(ReturnValue); \ }
#define FmpLogGroupInfoEvent1( MsgId, Group) \
{ \ if (!CsNoGroupInfoEvtLogging) \ CsLogEvent1(LOG_NOISE, MsgId, Group); \ } \ #define FmpLogGroupInfoEvent2( MsgId, Resource, Group) \
{ \ if (!CsNoGroupInfoEvtLogging) \ CsLogEvent2(LOG_NOISE, MsgId, Resource, Group); \ }
typedef struct WORK_ITEM { LIST_ENTRY ListEntry; CLUSTER_EVENT Event; PVOID Context1; ULONG_PTR Context2; } WORK_ITEM, *PWORK_ITEM;
// structures for timer activity
typedef struct _FM_RESLIST_ONLINE_RETRY_INFO{ PFM_GROUP pGroup; RESOURCE_ENUM ResourceEnum; }FM_RESLIST_ONLINE_RETRY_INFO, *PFM_RESLIST_ONLINE_RETRY_INFO;
//structure for cleanup at shutdown
typedef struct FM_CLEANUP_INFO{ PGROUP_ENUM pGroupEnum; BOOL bContainsQuorumGroup; DWORD dwTimeOut; }FM_CLEANUP_INFO, *PFM_CLEANUP_INFO;
//
// Wait block used for waiting on completion of pending
// events
//
typedef struct FM_WAIT_BLOCK { LIST_ENTRY ListEntry; HANDLE hEvent; DWORD Status; } FM_WAIT_BLOCK, *PFM_WAIT_BLOCK;
//
// Group Move structure
//
typedef struct MOVE_GROUP { PFM_GROUP Group; PNM_NODE DestinationNode; } MOVE_GROUP, *PMOVE_GROUP;
//
// Information for group affinity calculation.
//
typedef struct GROUP_AFFINITY_NODE_INFO { PFM_GROUP pGroup; PNM_NODE *ppNmNodeList; BOOL fDidPruningOccur; } GROUP_AFFINITY_NODE_INFO, *PGROUP_AFFINITY_NODE_INFO;
//
// Define types of pending routines
//
typedef enum { OfflinePending } PENDING_ROUTINE;
//
// Define types of Group failbacks
//
typedef enum { FailbackNot, FailbackOkay, FailbackMaximum } FAILBACK_TYPE;
//
// Define resource restart actions
//
typedef enum { RestartNot, RestartLocal, RestartGroup, RestartMaximum } RESTART_ACTION;
//
// Define FM to Resmon event types.
//
typedef enum { ResourceTransition, ResourceResuscitate, RmWorkerTerminate, RmUpdateResource, RmRestartResource } RM_EVENT_TYPE;
//
// Macro for easy dereferencing of a quorum target node
//
#define FM_DEREF_QUORUM_TARGET( pQuorumTargetNode ) \
{ \ if ( pQuorumTargetNode ) \ { \ OmDereferenceObject( pQuorumTargetNode ); \ pQuorumTargetNode = NULL; \ } \ }
DWORD WINAPI FmpGumReceiveUpdates( IN DWORD Context, IN BOOL SourceNode, IN DWORD BufferLength, IN PVOID Buffer );
DWORD WINAPI FmpGumVoteHandler( IN DWORD dwContext, IN DWORD dwInputBufLength, IN PVOID pInputBuf, IN DWORD dwVoteLength, OUT PVOID pVoteBuf );
//
// Gum update message buffers.
//
// UpdateResourceState
typedef struct GUM_RESOURCE_STATE { CLUSTER_RESOURCE_STATE State; CLUSTER_RESOURCE_STATE PersistentState; DWORD StateSequence; } GUM_RESOURCE_STATE, *PGUM_RESOURCE_STATE;
// UpdateGroupState
typedef struct GUM_GROUP_STATE { CLUSTER_GROUP_STATE State; CLUSTER_GROUP_STATE PersistentState; DWORD StateSequence; } GUM_GROUP_STATE, *PGUM_GROUP_STATE;
// UpdateGroupFailureCount
typedef struct GUM_FAILURE_COUNT { DWORD Count; DWORD NewTime; WCHAR GroupId[1]; } GUM_FAILURE_COUNT, *PGUM_FAILURE_COUNT;
typedef struct GUM_CREATE_GROUP { PFM_GROUP Group; DWORD GroupIdLen; DWORD GroupNameLen; WCHAR GroupId[1]; // WCHAR GroupName[1];
// WCHAR NodeName[1];
} GUM_CREATE_GROUP, *PGUM_CREATE_GROUP;
typedef struct GUM_DELETE_GROUP { WCHAR GroupId[1]; } GUM_DELETE_GROUP, *PGUM_DELETE_GROUP;
typedef struct GUM_CREATE_RESOURCE { PFM_RESOURCE Resource; DWORD GroupIdLen; DWORD ResourceIdLen; WCHAR GroupId[1]; // WCHAR ResourceId[1];
// WCHAR ResourceName[1];
} GUM_CREATE_RESOURCE, *PGUM_CREATE_RESOURCE;
typedef struct GUM_INIT_RESOURCE { DWORD ResourceIdLen; WCHAR ResourceId[1]; } GUM_INIT_RESOURCE, *PGUM_INIT_RESOURCE;
typedef struct GUM_CHANGE_POSSIBLE_NODE { DWORD ResourceIdLen; WCHAR ResourceId[1]; // WCHAR NodeName[1];
} GUM_CHANGE_POSSIBLE_NODE, *PGUM_CHANGE_POSSIBLE_NODE;
typedef struct GUM_CREATE_RESOURCE_TYPE { WCHAR TypeName[1]; } GUM_CREATE_RESOURCE_TYPE, *PGUM_CREATE_RESOURCE_TYPE;
typedef struct GUM_DELETE_RESOURCE_TYPE { WCHAR TypeName[1]; } GUM_DELETE_RESOURCE_TYPE, *PGUM_DELETE_RESOURCE_TYPE;
typedef struct GUM_CHANGE_GROUP { DWORD ResourceIdLen; WCHAR ResourceId[1]; // WCHAR GroupName[1];
} GUM_CHANGE_GROUP, *PGUM_CHANGE_GROUP;
#if 0
typedef struct GUM_SET_POSSIBLE_NODE_FORRESTYPE{ DWORD ResTypeNameLen; WCHAR ResTypeName[1]; } GUM_SET_POSSIBLE_OWNER_FORRESTYPE, *PGUM_SET_POSSIBLE_OWNER_FORRESTYPE; #endif
typedef struct _FMP_POSSIBLE_NODE { PFM_RESOURCE Resource; PNM_NODE Node; DWORD ControlCode; } FMP_POSSIBLE_NODE, *PFMP_POSSIBLE_NODE;
//VOTE STRUCTURES
typedef struct _FMP_VOTE_POSSIBLE_NODE_FOR_RESTYPE{ DWORD dwSize; DWORD dwNodeId; BOOL bPossibleNode; }FMP_VOTE_POSSIBLE_NODE_FOR_RESTYPE, *PFMP_VOTE_POSSIBLE_NODE_FOR_RESTYPE;
typedef struct _FM_RES_CHANGE_NAME { PFM_RESOURCE pResource; WCHAR szNewResourceName[1]; } FM_RES_CHANGE_NAME, *PFM_RES_CHANGE_NAME;
//
// Monitor resource enumeration
//
typedef struct MONITOR_RESOURCE_ENUM { DWORD EntryCount; DWORD CurrentIndex; BOOL fCreateMonitors; PFM_RESOURCE Entry[1]; } MONITOR_RESOURCE_ENUM, *PMONITOR_RESOURCE_ENUM;
#define ENUM_GROW_SIZE 16
//
// Resource enumeration interface
//
#define RESOURCE_SIZE(Entries) ((Entries-1) * sizeof(RESOURCE_ENUM_ENTRY) + sizeof(RESOURCE_ENUM))
#define MONITOR_RESOURCE_SIZE(Entries) ((Entries-1) * sizeof(PFM_GROUP) + \
sizeof(MONITOR_RESOURCE_ENUM))
//
// Group and resource enumeration entries.
//
#define GROUP_SIZE(Entries) ((Entries-1) * sizeof(GROUP_ENUM_ENTRY) + sizeof(GROUP_ENUM))
#define NODE_SIZE(Entries) ((Entries-1) * sizeof (NM_NODE_INFO2) + sizeof(NM_NODE_ENUM2))
#define RESOURCE_SIZE(Entries) ((Entries-1) * sizeof(RESOURCE_ENUM_ENTRY) + sizeof(RESOURCE_ENUM))
//
// Define structure for a Resource Monitor process
//
typedef struct RESMON { DWORD Signature; HANDLE Process; HANDLE NotifyThread; BOOL Shutdown; DWORD RefCount; RPC_BINDING_HANDLE Binding; struct MONITOR_STATE *SharedState; LIST_ENTRY leMonitor; // Link to the next monitor
DWORD dwDeadlockTimeoutSecs;// Tells us what exactly the monitor has
} RESMON, *PRESMON;
//
// Monitor list enumeration info used for resource DLL upgrade.
//
typedef struct _FM_MONITOR_ENUM_HEADER { DWORD cEntries; DWORD cAllocated; BOOL fDefaultMonitorAdded; PRESMON *ppMonitorList; } FM_MONITOR_ENUM_HEADER, *PFM_MONITOR_ENUM_HEADER;
//
// Structure definitions for passing around group preferred node list info on a node
// down.
//
typedef struct _FM_GROUP_NODE_LIST_ENTRY { DWORD dwPreferredNodeId; WCHAR szGroupId[1]; // Always at the end to help marshalling
} FM_GROUP_NODE_LIST_ENTRY, *PFM_GROUP_NODE_LIST_ENTRY;
typedef struct _FM_GROUP_NODE_LIST { DWORD cbGroupNodeList; FM_GROUP_NODE_LIST_ENTRY leGroupNodeList[1]; // Always at the end to help marshalling
} FM_GROUP_NODE_LIST, *PFM_GROUP_NODE_LIST;
//flags for cluster propery change
#define CLUSTER_NAME_CHANGE 0x00000001
#define CLUSTER_QUORUM_CHANGE 0x00000002
// FM event handling structures
typedef struct CLUSTER_EVENT_PROPERTY_CONTEXT{ DWORD dwFlags; PVOID pContext1; PVOID pContext2; } CLUSTER_EVENT_PROPERTY_CONTEXT, *PCLUSTER_EVENT_PROPERTY_CONTEXT;
typedef struct RESOURCE_STATE_CHANGE{ PFM_RESOURCE pResource; CLUSTER_RESOURCE_STATE OldState; CLUSTER_RESOURCE_STATE NewState; } RESOURCE_STATE_CHANGE, *PRESOURCE_STATE_CHANGE;
typedef struct { LIST_ENTRY Linkage; RM_EVENT_TYPE EventType; union { struct { RM_NOTIFY_KEY NotifyKey; CLUSTER_RESOURCE_STATE NewState; } ResourceTransition; struct { RM_NOTIFY_KEY NotifyKey; } ResourceResuscitate; } Parameters; } RM_EVENT, *PRM_EVENT;
//Cluster Name management
DWORD FmpRegUpdateClusterName( IN LPCWSTR szNewClusterName );
//
// Quorum resource Arbitration.
//
DWORD FmpRmArbitrateResource( IN PFM_RESOURCE Resource );
DWORD FmpRmReleaseResource( IN PFM_RESOURCE Resource );
//
// Interfaces for managing the registry.
//
DWORD FmpRegEnumerateKey( IN HDMKEY ListKey, IN DWORD Index, IN LPWSTR *Name, IN OUT LPDWORD NameMaxSize );
//
// Gum interfaces
//
DWORD FmpEnableGum( );
//
// Interfaces for managing Resource Monitor processes
//
PRESMON FmpCreateMonitor( LPWSTR DebugPrefix, BOOL SeparateMonitor );
VOID FmpShutdownMonitor( IN PRESMON Monitor );
BOOL FmpRestartMonitor( IN PRESMON OldMonitor, IN BOOL fCreateResourcesOnly, OUT OPTIONAL PMONITOR_RESOURCE_ENUM *ppMonitorResourceEnum );
DWORD FmpCreateMonitorRestartThread( IN PRESMON pMonitor );
//
// Interfaces for managing resources via the Resource Monitors
//
DWORD FmpRmCreateResource( PFM_RESOURCE Resource );
DWORD FmpRmCloseResource( PFM_RESOURCE Resource );
DWORD FmpRmOnlineResource( PFM_RESOURCE Resource );
DWORD FmpRmOfflineResource( PFM_RESOURCE Resource );
VOID FmpRmTerminateResource( PFM_RESOURCE Resource );
DWORD FmpRmFailResource( PFM_RESOURCE Resource );
DWORD FmpRmChangeResourceParams( PFM_RESOURCE Resource );
DWORD FmpRmResourceTypeControl( IN LPCWSTR ResourceTypeName, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpRmResourceControl( IN PFM_RESOURCE Resource, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpRmLoadResTypeDll( IN PFM_RESTYPE pResType );
DWORD FmpPostProcessResourceControl( IN PFM_RESOURCE Resource, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
//
// Interfaces for managing resources
//
DWORD FmpInitResource( VOID );
VOID FmpCleanupResource( VOID );
PFM_RESOURCE FmpCreateResource( IN PFM_GROUP Group, IN LPCWSTR ResourceId, IN LPCWSTR ResourceName, IN BOOL Initialize );
VOID FmpDestroyResource( IN PFM_RESOURCE Resource, IN BOOL bDeleteObjOnly );
VOID FmpResourceLastReference( IN PFM_RESOURCE Resource );
DWORD FmpInitializeResource( IN PFM_RESOURCE Resource, IN BOOL Initialize );
DWORD FmpOnlineResource( IN PFM_RESOURCE Resource, IN BOOL ForceOnline );
DWORD FmpArbitrateResource( IN PFM_RESOURCE pResource );
DWORD FmpOfflineResource( IN PFM_RESOURCE Resource, IN BOOL bForceOffline );
DWORD FmpDoOnlineResource( IN PFM_RESOURCE Resource, IN BOOL ForceOnline );
DWORD FmpDoOfflineResource( IN PFM_RESOURCE Resource, IN BOOL bForceOffline );
VOID FmpSetResourcePersistentState( IN PFM_RESOURCE Resource, IN CLUSTER_RESOURCE_STATE State );
VOID FmpCallResourceNotifyCb( IN PFM_RESOURCE Resource, IN CLUSTER_RESOURCE_STATE State );
DWORD FmpPropagateResourceState( IN PFM_RESOURCE Resource, IN CLUSTER_RESOURCE_STATE State );
DWORD FmpGetResourceList( OUT PRESOURCE_ENUM *ReturnEnum, IN PFM_GROUP Group );
DWORD FmpSubmitRetryOnline( IN PRESOURCE_ENUM pResourceEnum, IN PFM_GROUP pGroup );
VOID FmpDeleteResourceEnum( IN PRESOURCE_ENUM Enum );
DWORD FmpOnlineResourceList( IN PRESOURCE_ENUM Enum, IN PFM_GROUP pGroup );
DWORD FmpOfflineResourceList( IN PRESOURCE_ENUM Enum, IN BOOL Restore );
DWORD FmpTerminateResourceList( IN PRESOURCE_ENUM Enum );
VOID FmpPrunePreferredList( IN PFM_RESOURCE Resource );
DWORD FmpCleanupPossibleNodeList( IN PFM_RESOURCE pResource );
DWORD FmpSetPreferredEntry( IN PFM_GROUP Group, IN PNM_NODE Node );
DWORD FmpAddPossibleNode( IN PFM_RESOURCE Resource, IN PNM_NODE Node );
DWORD FmpAddPossibleEntry( IN PFM_RESOURCE Resource, IN PNM_NODE Node );
DWORD FmpRemovePossibleNode( IN PFM_RESOURCE Resource, IN PNM_NODE Node, IN BOOL RemoveQuorum );
DWORD FmpRemoveResourceDependency( IN HXSACTION hXsaction, IN PFM_RESOURCE Resource, IN PFM_RESOURCE DependsOn );
BOOL FmpFindQuorumResource( IN OUT PFM_RESOURCE *QuorumResource, IN PVOID Context2, IN PFM_RESOURCE Resource, IN LPCWSTR Name );
DWORD FmpGetQuorumDiskSignature( IN LPCWSTR lpQuorumId, OUT LPDWORD lpdwSignature );
BOOL FmpReturnResourceType( IN OUT PFM_RESTYPE *FoundResourceType, IN LPCWSTR ResourceTypeName, IN PFM_RESTYPE ResourceType, IN LPCWSTR Name );
DWORD FmpChangeResourceMonitor( IN PFM_RESOURCE Resource, IN DWORD SeparateMonitor );
DWORD FmpChangeResourceGroup( IN PFM_RESOURCE Resource, IN PFM_GROUP Group );
DWORD FmpValAddResourceDependency( IN PFM_RESOURCE pResource, IN PFM_RESOURCE pDependentResource );
DWORD FmpValRemoveResourceDependency( IN PFM_RESOURCE pResource, IN PFM_RESOURCE pDependentResource );
DWORD FmpUpdateChangeResourceName( IN BOOL bSourceNode, IN LPCWSTR lpszResourceId, IN LPCWSTR lpszNewName );
DWORD FmpUpdateDeleteResource( IN BOOL SourceNode, IN LPCWSTR ResourceId );
DWORD FmpUpdateAddDependency( IN BOOL SourceNode, IN LPCWSTR ResourceId, IN LPCWSTR DependsOnId );
DWORD FmpUpdateRemoveDependency( IN BOOL SourceNode, IN LPCWSTR ResourceId, IN LPCWSTR DependsOnId );
DWORD FmpUpdateAssignOwnerToGroups( IN BOOL SourceNode, IN LPCWSTR pszNodeId );
DWORD FmpUpdateApproveJoin( IN BOOL SourceNode, IN LPCWSTR pszNodeId );
DWORD FmpUpdateCreateGroup( IN PGUM_CREATE_GROUP pGumGroup, IN BOOL bSourceNode );
DWORD FmpUpdateCreateResource( IN OUT PGUM_CREATE_RESOURCE pGumResource );
DWORD FmpUpdateCompleteGroupMove( IN BOOL SourceNode, IN LPCWSTR pszNodeId, IN LPCWSTR pszGroupId );
DWORD FmpUpdateCheckAndSetGroupOwner( IN BOOL bSourceNode, IN LPCWSTR lpszGroupId, IN LPCWSTR lpszNodeId );
DWORD FmpUpdateCreateResourceType( IN PVOID Buffer );
DWORD FmpSetResourceName( IN PFM_RESOURCE pResource, IN LPCWSTR lpszFriendlyName );
DWORD FmpClusterEventPropHandler( IN PFM_RESOURCE pResource );
BOOL FmpEnumResourceNodeEvict( IN PVOID Context1, IN PVOID Context2, IN PVOID Object, IN LPCWSTR Name );
DWORD FmpPrepareQuorumResChange( IN PFM_RESOURCE pNewQuoRes, IN LPCWSTR lpszQuoLogPath, IN DWORD dwMaxQuoLogSize );
DWORD FmpCompleteQuorumResChange( IN LPCWSTR lpszOldQuoResId, IN LPCWSTR lpszQuoLogPath );
DWORD FmpBackupClusterDatabase( IN PFM_RESOURCE pQuoRes, IN LPCWSTR lpszPathName );
VOID FmpCheckForGroupCompletionEvent( IN PFM_GROUP pGroup);
//
// Interfaces for handling pending online/offline requests.
//
VOID FmpSignalGroupWaiters( IN PFM_GROUP Group );
DWORD FmpWaitForGroup( IN PFM_GROUP Group );
#define FmpIsGroupPending(_group_) (!IsListEmpty(&((_group_)->WaitQueue)))
//
// There is currently one default monitor process, and resources
// with the SeparateMonitor property have a monitor created for them.
//
extern PRESMON FmpDefaultMonitor;
//
// Interface for notification module
//
DWORD FmpInitializeNotify( VOID );
BOOL FmpPostNotification( IN RM_NOTIFY_KEY NotifyKey, IN DWORD NotifyEvent, IN CLUSTER_RESOURCE_STATE CurrentState );
//
// Event processing routines
//
DWORD FmpStartWorkerThread( VOID );
VOID FmpPostWorkItem( IN CLUSTER_EVENT Event, IN PVOID Context1, IN ULONG_PTR Context2 );
VOID FmpHandleGroupFailure( IN PFM_GROUP Group, IN PFM_RESOURCE pResource OPTIONAL );
DWORD FmpNodeUp( PVOID Context );
DWORD FmpNodeDown( PVOID Context );
VOID FmpPropagateState( VOID );
DWORD FmpSetPossibleNodeForResType( IN LPCWSTR TypeName, IN BOOL bAssumeSupported );
DWORD FmpRemovePossibleNodeForResType( IN LPCWSTR TypeName, IN PNM_NODE pNode );
//
// Object Manager callback routines.
//
DWORD WINAPI FmpQueryGroupInfo( IN PVOID Object, IN BOOL Initialize );
DWORD WINAPI FmpQueryResourceInfo( IN PVOID Object, IN BOOL Initialize );
DWORD WINAPI FmpQueryResTypeInfo( IN PVOID Object );
DWORD WINAPI FmpFixupGroupInfo( IN PFM_GROUP Group );
DWORD WINAPI FmpFixupResourceInfo( IN PFM_RESOURCE Resource );
//
// Synchronization macros
//
#define FmpAcquireResourceLock() EnterCriticalSection(&FmpResourceLock)
#define FmpReleaseResourceLock() LeaveCriticalSection(&FmpResourceLock)
#define FmpAcquireGroupLock() EnterCriticalSection(&FmpGroupLock)
#define FmpReleaseGroupLock() LeaveCriticalSection(&FmpGroupLock)
#define FmpAcquireMonitorLock() EnterCriticalSection(&FmpMonitorLock)
#define FmpReleaseMonitorLock() LeaveCriticalSection(&FmpMonitorLock)
#if 0
// 185575: remove unique RPC binding handles
#define FmpAcquireBindingLock() EnterCriticalSection(&FmpBindingLock)
#define FmpReleaseBindingLock() LeaveCriticalSection(&FmpBindingLock)
#endif
#define FmpTryAcquireGroupLock( Locked, Timeout ) \
{ \ DWORD _retry = (Timeout + 19) / 20; \ do { \ Locked = TryEnterCriticalSection(&FmpGroupLock); \ if ( !Locked ) Sleep( 20 ); \ } while (_retry-- && !Locked ); \ }
// Group and Resource Specific locks
#if 1 // DBG
#define FmpAcquireLocalGroupLock( Group ) \
{ \ DWORD _fmpLockIndx; \ EnterCriticalSection( &Group->Lock ); \ _fmpLockIndx = Group->LockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Group->LockTable[_fmpLockIndx].Module = LOG_MODULE; \ Group->LockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Group->LockTable[_fmpLockIndx].LineNumber = __LINE__; \ Group->LockIndex = ++_fmpLockIndx; \ }
#define FmpTryAcquireLocalGroupLock( Group, Locked ) \
{ \ DWORD _fmpLockIndx; \ Locked = TryEnterCriticalSection( &Group->Lock ); \ if ( Locked ) { \ _fmpLockIndx = Group->LockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Group->LockTable[_fmpLockIndx].Module = LOG_MODULE; \ Group->LockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Group->LockTable[_fmpLockIndx].LineNumber = __LINE__; \ Group->LockIndex = ++_fmpLockIndx; \ } \ }
#define FmpReleaseLocalGroupLock( Group ) \
{ \ DWORD _fmpLockIndx; \ CL_ASSERT(HandleToUlong(Group->Lock.OwningThread) == GetCurrentThreadId()); \ _fmpLockIndx = Group->UnlockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Group->UnlockTable[_fmpLockIndx].Module = LOG_MODULE; \ Group->UnlockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Group->UnlockTable[_fmpLockIndx].LineNumber = __LINE__; \ Group->UnlockIndex = ++_fmpLockIndx; \ LeaveCriticalSection( &Group->Lock ); \ }
#define FmpAcquireLocalResourceLock( Resource ) \
{ \ DWORD _fmpLockIndx; \ PFM_GROUP pGroup; \ while( 1 ) { \ pGroup = Resource->Group; \ EnterCriticalSection( &pGroup->Lock );\ if( pGroup == Resource->Group ) break; \ LeaveCriticalSection( &pGroup->Lock ); \ } \ _fmpLockIndx = Resource->Group->LockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Resource->Group->LockTable[_fmpLockIndx].Module = LOG_MODULE; \ Resource->Group->LockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Resource->Group->LockTable[_fmpLockIndx].LineNumber = __LINE__; \ Resource->Group->LockIndex = ++_fmpLockIndx; \ }
#define FmpReleaseLocalResourceLock( Resource ) \
{ \ DWORD _fmpLockIndx; \ CL_ASSERT(HandleToUlong(Resource->Group->Lock.OwningThread) == GetCurrentThreadId()); \ _fmpLockIndx = Resource->Group->UnlockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Resource->Group->UnlockTable[_fmpLockIndx].Module = LOG_MODULE; \ Resource->Group->UnlockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Resource->Group->UnlockTable[_fmpLockIndx].LineNumber = __LINE__; \ Resource->Group->UnlockIndex = ++_fmpLockIndx; \ LeaveCriticalSection( &Resource->Group->Lock ); \ }
#define FmpTryAcquireLocalResourceLock( Resource, _Status_ ) \
{ \ (_Status_) = TryEnterCriticalSection(&Resource->Group->Lock); \ if ( !(_Status_) ) { \ Sleep(100); \ (_Status_) = TryEnterCriticalSection( &Resource->Group->Lock ); \ } \ if (_Status_) { \ DWORD _fmpLockIndx; \ _fmpLockIndx = Resource->Group->LockIndex & (FM_MAX_LOCK_ENTRIES - 1); \ Resource->Group->LockTable[_fmpLockIndx].Module = LOG_MODULE; \ Resource->Group->LockTable[_fmpLockIndx].ThreadId = GetCurrentThreadId(); \ Resource->Group->LockTable[_fmpLockIndx].LineNumber = __LINE__; \ Resource->Group->LockIndex = ++_fmpLockIndx; \ } \ }
#else // DBG
#define FmpAcquireLocalGroupLock( Group ) \
EnterCriticalSection( &Group->Lock )
#define FmpTryAcquireLocalGroupLock( Group, Locked ) \
Locked = TryEnterCriticalSection( &Group->Lock )
#define FmpReleaseLocalGroupLock( Group ) \
LeaveCriticalSection( &Group->Lock )
#define FmpAcquireLocalResourceLock( Resource ) \
{ \ PFM_GROUP pGroup; \ while( 1 ) { \ pGroup = Resource->Group; \ EnterCriticalSection( &pGroup->Lock );\ if( pGroup == Resource->Group ) break; \ LeaveCriticalSection( &pGroup->Lock ); \ } \ }
#define FmpReleaseLocalResourceLock( Resource ) \
LeaveCriticalSection( &Resource->Group->Lock )
#define FmpTryAcquireLocalResourceLock( Resource, _result_ ) \
if ( !((_result_) = TryEnterCriticalSection(&Resource->Group->Lock)) ) { \ sleep(100); \ (_result_) = TryEnterCriticalSection( &Resource->Group->Lock ); \ }
#endif // DBG
//
// Global Data
//
extern CRITICAL_SECTION FmpResourceLock;
//
// Resource Management Routines
//
//
// Interfaces for managing resource trees.
//
DWORD FmpRestartResourceTree( IN PFM_RESOURCE Resource );
DWORD FmpOnlineWaitingTree( IN PFM_RESOURCE Resource );
DWORD FmpOfflineWaitingTree( IN PFM_RESOURCE Resource );
//++
//
// Routine Description:
//
// Processes the Cluster resource list in the registry. For each
// resource key found, a cluster resource is created.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
DWORD FmpInitResources( VOID );
VOID FmpCleanupResources( VOID );
BOOL FmpInPossibleListForResource( IN PFM_RESOURCE pResource, IN PNM_NODE pNode );
DWORD FmpInitResourceTypes( VOID );
PFM_RESTYPE FmpCreateResType( IN LPWSTR ResTypeName );
DWORD FmpDeleteResType( IN PFM_RESTYPE pResType );
BOOL FmpFindResourceType( IN PFM_RESTYPE Type, IN PBOOL ResourceExists, IN PFM_RESOURCE Resource, IN LPCWSTR Name );
BOOL FmpInPossibleListForResType( IN PFM_RESTYPE pResType, IN PNM_NODE pNode );
DWORD FmpHandleResourceTypeControl( IN PFM_RESTYPE Type, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
BOOL FmpEnumResTypeNodeEvict( IN PVOID Context1, IN PVOID Context2, IN PVOID Object, IN LPCWSTR Name );
VOID FmpResTypeLastRef( IN PFM_RESTYPE Resource );
DWORD FmpAddPossibleNodeToList( IN LPCWSTR pmszPossibleNodes, IN DWORD dwStringSize, IN PLIST_ENTRY pPosNodeList );
BOOL FmpFixupPossibleNodesForResTypeCb( IN PVOID pContext1, IN PVOID pContext2, IN PFM_RESTYPE pResType, IN LPCWSTR ResTypeName );
BOOL FmpFixupResTypePhase2Cb( IN PVOID pContext1, IN PVOID pContext2, IN PFM_RESTYPE pResType, IN LPCWSTR pszResTypeName );
DWORD FmpFixupResourceTypesPhase1( BOOL bJoin, BOOL bNmLocalNodeVersionChanged, PCLUSTERVERSIONINFO pClusterVersionInfo );
DWORD FmpFixupResourceTypesPhase2( BOOL bJoin, BOOL bNmLocalNodeVersionChanged, PCLUSTERVERSIONINFO pClusterVersionInfo );
DWORD FmpDecidePossibleNodeForResType ( IN PGUM_VOTE_DECISION_CONTEXT pDecisionContext, IN DWORD dwVoteBufLength, IN PVOID pVoteBuf, IN DWORD dwNumVotes, IN BOOL bDidAllActiveNodesVote, OUT LPDWORD pdwOutputBufSize, OUT PVOID *ppOutputBuf );
PFM_RESOURCE FmpFindResourceByNotifyKey( RM_NOTIFY_KEY NotifyKey );
DWORD FmpTerminateResource( IN PFM_RESOURCE Resource );
DWORD WINAPI FmpEventHandler( IN CLUSTER_EVENT Event, IN PVOID Context );
DWORD WINAPI FmpSyncEventHandler( IN CLUSTER_EVENT Event, IN PVOID Context );
DWORD FmpSyncArbitration( IN DWORD NewPhase, OUT LPDWORD CurrentPhase );
DWORD FmpEnumSortGroups( OUT PGROUP_ENUM *ReturnEnum, IN LPCWSTR pszOwnerNodeId OPTIONAL, OUT PBOOL QuorumGroup );
VOID FmpPrepareGroupForOnline( IN PFM_GROUP Group );
DWORD FmpSetGroupEnumOwner( IN PGROUP_ENUM pGroupEnum, IN PNM_NODE pDefaultOwnerNode, IN LPCWSTR pszDeadNodeId, IN BOOL bQuorumGroup, IN PFM_GROUP_NODE_LIST pGroupNodeList );
DWORD FmpOnlineGroupList( IN PGROUP_ENUM GroupEnum, IN BOOL bPrepareQuoForOnline );
DWORD FmpOnlineGroupFromList( IN PGROUP_ENUM GroupEnum, IN DWORD Index, IN BOOL bPrepareQuoForOnline );
DWORD FmpOnlineResourceFromList( IN PRESOURCE_ENUM GroupEnum, IN PFM_GROUP pGroup );
BOOL FmpEqualGroupLists( IN PGROUP_ENUM Group1, IN PGROUP_ENUM Group2 );
DWORD FmpOnlineGroup( IN PFM_GROUP Group, IN BOOL ForceOnline );
DWORD FmpOfflineGroup( IN PFM_GROUP Group, IN BOOL OfflineQuorum, IN BOOL SetPersistent );
DWORD FmpDeleteGroup( IN PFM_GROUP pGroup );
DWORD FmpMoveGroup( IN PFM_GROUP Group, IN PNM_NODE DestinationNode, IN BOOL ShutdownHandler, OUT PNM_NODE *pChosenDestinationNode, IN BOOL bChooseMostPreferredNode );
DWORD FmpCompleteMoveGroup( IN PFM_GROUP Group, IN PNM_NODE DestinationNode );
DWORD FmpDoMoveGroup( IN PFM_GROUP Group, IN PNM_NODE DestinationNode, IN BOOL bChooseMostPreferredNode );
BOOL FmpGroupCanMove( IN PFM_GROUP Group );
DWORD FmpUpdateChangeGroupName( IN BOOL SourceNode, IN LPCWSTR ResourceId, IN LPCWSTR NewName );
DWORD FmpUpdateDeleteGroup( IN BOOL SourceNode, IN LPCWSTR GroupId );
BOOL FmpEnumGroupNodeEvict( IN PVOID Context1, IN PVOID Context2, IN PVOID Object, IN LPCWSTR Name );
PNM_NODE FmpFindAnotherNode( IN PFM_GROUP Group, IN BOOL bChooseMostPreferredNode );
PNM_NODE FmpGetPreferredNode( IN PFM_GROUP Group );
//++
//
// Routine Description:
//
// Takes appropriate action based on resource state transitions indicated
// by the Resource Monitor.
//
// Arguments:
//
// Resource - The resource which has transitioned.
//
// NewState - The new state of Resource.
//
// Return Value:
//
// None.
//
//--
VOID FmpHandleResourceTransition( IN PFM_RESOURCE Resource, IN CLUSTER_RESOURCE_STATE NewState );
DWORD FmpCreateResStateChangeHandler( IN PFM_RESOURCE pResource, IN CLUSTER_RESOURCE_STATE NewState, IN CLUSTER_RESOURCE_STATE OldState );
VOID FmpProcessResourceEvents( IN PFM_RESOURCE pResource, IN CLUSTER_RESOURCE_STATE NewState, IN CLUSTER_RESOURCE_STATE OldState );
VOID FmpHandleResourceFailure( IN PFM_RESOURCE Resource );
//
// Group Management Routines
//
//++
//
// Routine Description:
//
// Processes the Cluster Group list in the registry. For each
// Group key found, a cluster Group is created.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
DWORD FmpInitGroups( IN BOOL Initialize );
DWORD FmpCompleteInitGroup( IN PFM_GROUP Group );
VOID FmpCleanupGroups( IN BOOL ClusterShutDownEvent );
DWORD FmpCleanupGroupPhase1( IN PFM_GROUP Group, IN DWORD dwTimeOut );
DWORD FmpCleanupGroupsWorker( IN PFM_CLEANUP_INFO pFmCleanupInfo );
DWORD FmpCleanupGroupPhase2( IN PFM_GROUP Group );
DWORD FmpCleanupQuorumResource( IN PFM_RESOURCE Resource );
BOOL FmpInPreferredList( IN PFM_GROUP Group, IN PNM_NODE Node, IN BOOL bRecalc, IN PFM_RESOURCE pRefResource );
BOOL FmpHigherInPreferredList( IN PFM_GROUP Group, IN PNM_NODE Node1, IN PNM_NODE Node2 );
PFM_GROUP FmpCreateGroup( IN LPWSTR GroupId, IN BOOL Initialize );
DWORD FmpInitializeGroup( IN PFM_GROUP Group, IN BOOL Initialize );
DWORD FmpDestroyGroup( IN PFM_GROUP Group, IN BOOL bDeleteObjOnly );
VOID FmpSetGroupPersistentState( IN PFM_GROUP Group, IN CLUSTER_GROUP_STATE State );
DWORD FmpPropagateGroupState( IN PFM_GROUP Group );
DWORD FmpPropagateFailureCount( IN PFM_GROUP Group, IN BOOL NewTime );
DWORD FmpGetGroupListState( IN PGROUP_ENUM GroupEnum );
DWORD FmpOfflineGroupList( IN PGROUP_ENUM GroupEnum );
VOID FmpGroupLastReference( IN PFM_GROUP pGroup );
//
// Stuff previously in fmclient.h
//
typedef DWORD (WINAPI *PSEND_MSG_ROUTINE) ( IN PGROUP_ENUM MyGroups, IN PGROUP_ENUM OtherGroups, OUT PGROUP_ENUM *ResponseOtherGroups, OUT PGROUP_ENUM *ResponseMyGroups ); //
// Global function prototypes
//
DWORD FmcOnlineGroupRequest( IN PFM_GROUP Group );
DWORD FmcOfflineGroupRequest( IN PFM_GROUP Group );
DWORD FmcMoveGroupRequest( IN PFM_GROUP Group, IN PNM_NODE DestinationNode OPTIONAL );
DWORD FmcTakeGroupRequest( IN PNM_NODE DestinationNode, IN LPCWSTR GroupId, IN PRESOURCE_ENUM ResourceList );
DWORD FmcDeleteGroupRequest( IN PFM_GROUP pGroup );
DWORD FmcOnlineResourceRequest( IN PFM_RESOURCE Resource );
DWORD FmcOfflineResourceRequest( IN PFM_RESOURCE Resource );
DWORD FmcArbitrateResource( IN PFM_RESOURCE Resource );
DWORD FmcFailResource( IN PFM_RESOURCE Resource );
PFM_RESOURCE FmcCreateResource( IN PFM_GROUP Group, IN LPWSTR ResourceId, IN LPCWSTR ResourceName, IN LPCWSTR ResourceType, IN DWORD dwFlags );
DWORD FmcDeleteResource( IN PFM_RESOURCE Resource );
CLUSTER_GROUP_STATE FmcGetGroupState( IN LPCWSTR GroupId, OUT LPWSTR *NodeName );
DWORD FmcChangeResourceNode( IN PFM_RESOURCE Resource, IN PNM_NODE Node, IN BOOL Add );
DWORD FmcResourceControl( IN PNM_NODE Node, IN PFM_RESOURCE Resource, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmcResourceTypeControl( IN PNM_NODE Node, IN LPCWSTR ResourceTypeName, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmcGroupControl( IN PNM_NODE Node, IN PFM_GROUP Group, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmcPrepareQuorumResChange( IN PFM_RESOURCE Resource, IN LPCWSTR lpszQuoLogPath, IN DWORD dwMaxQuoLogSize );
DWORD FmcCompleteQuorumResChange( IN PFM_RESOURCE pOldQuoRes, IN LPCWSTR lpszOldQuoLogPath );
DWORD FmcBackupClusterDatabase( IN PFM_RESOURCE pQuoResource, IN LPCWSTR lpszPathName );
DWORD FmcChangeResourceGroup( IN PFM_RESOURCE pResource, IN PFM_GROUP pNewGroup );
DWORD FmcAddResourceDependency( IN PFM_RESOURCE pResource, IN PFM_RESOURCE pDependentResource );
DWORD FmcRemoveResourceDependency( IN PFM_RESOURCE pResource, IN PFM_RESOURCE pDependentResource );
DWORD FmpGroupControl( IN PFM_GROUP Group, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpHandleGroupControl( IN PFM_GROUP Group, IN DWORD ControlCode, IN PUCHAR InBuffer, IN DWORD InBufferSize, OUT PUCHAR OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpTakeGroupRequest( IN PFM_GROUP Group, IN PRESOURCE_ENUM ResourceList );
CLUSTER_GROUP_STATE FmpGetGroupState( IN PFM_GROUP Group, IN BOOL IsNormalized );
VOID FmpDeleteEnum( IN PGROUP_ENUM Enum );
DWORD FmpClaimAllGroups( PGROUP_ENUM MyGroups );
DWORD FmpAssignOwnersToGroups( IN LPCWSTR pszDeadNodeId, IN PFM_GROUP pGroup, IN PFM_GROUP_NODE_LIST pGroupNodeList );
VOID FmpPruneGroupOwners( IN PFM_GROUP Group );
DWORD FmpQueryGroupNodes( IN PFM_GROUP Group, IN HDMKEY hGroupKey );
DWORD FmpUpdateChangeClusterName( IN BOOL SourceNode, IN LPCWSTR NewName );
DWORD FmpUpdateChangeQuorumResource( IN BOOL SourceNode, IN LPCWSTR NewQuorumResId, IN LPCWSTR pszQuorumLogPath, IN LPDWORD pdwMaxQuorumLogSize );
DWORD FmpUpdateChangeQuorumResource2( IN BOOL SourceNode, IN LPCWSTR NewQuorumResId, IN LPCWSTR pszQuorumLogPath, IN LPDWORD pdwMaxQuorumLogSize, IN LPDWORD pdwQuorumArbTimeout, IN LPDWORD pdwNewQuorumResourceCharacteristics OPTIONAL );
DWORD FmpUpdateResourceState( IN BOOL SourceNode, IN LPCWSTR ResourceId, IN PGUM_RESOURCE_STATE ResourceState );
DWORD FmpUpdateGroupState( IN BOOL SourceNode, IN LPCWSTR GroupId, IN LPCWSTR NodeId, IN PGUM_GROUP_STATE ResourceState );
DWORD FmpUpdateGroupNode( IN BOOL SourceNode, IN LPCWSTR GroupId, IN LPCWSTR NodeId );
DWORD FmpUpdateGroupIntendedOwner( IN BOOL SourceNode, IN LPCWSTR pszGroupId, IN PDWORD pdwNodeId ); //
// Handle group property requests
//
DWORD FmpGroupEnumCommonProperties( OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpGroupEnumPrivateProperties( IN PFM_GROUP Group, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpGroupGetCommonProperties( IN PFM_GROUP Group, IN BOOL ReadOnly, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpGroupValidateCommonProperties( IN PFM_GROUP Group, IN PVOID InBuffer, IN DWORD InBufferSize );
DWORD FmpGroupSetCommonProperties( IN PFM_GROUP Group, IN PVOID InBuffer, IN DWORD InBufferSize );
DWORD FmpGroupGetPrivateProperties( IN PFM_GROUP Group, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
DWORD FmpGroupValidatePrivateProperties( IN PFM_GROUP Group, IN PVOID InBuffer, IN DWORD InBufferSize );
DWORD FmpGroupSetPrivateProperties( IN PFM_GROUP Group, IN PVOID InBuffer, IN DWORD InBufferSize );
DWORD FmpGroupGetFlags( IN PFM_GROUP Group, OUT PVOID OutBuffer, IN DWORD OutBufferSize, OUT LPDWORD BytesReturned, OUT LPDWORD Required );
//property parse routines
DWORD FmpGetDiskInfoParseProperties( IN PUCHAR InBuffer, IN DWORD InBufferSize, IN OUT LPWSTR pszPath );
DWORD FmpBroadcastDeleteControl( IN PFM_RESOURCE Resource );
DWORD FmpBroadcastDependencyChange( IN PFM_RESOURCE Resource, IN LPCWSTR DependsOnId, IN BOOL Remove );
BOOL FmpCheckNetworkDependency( IN LPCWSTR DependentNetwork );
DWORD FmpVotePossibleNodeForResType( IN DWORD dwInputBufLength, IN LPCWSTR lpszResType, IN DWORD dwVoteLength, OUT PVOID pVoteBuf );
DWORD FmpUpdatePossibleNodeForResType( IN BOOL SourceNode, IN LPCWSTR lpszResTypeName, IN LPDWORD pdwBufLength, IN PVOID pBuf );
DWORD FmpUpdateChangeResourceNode( IN BOOL SourceNode, IN PFM_RESOURCE pResource, IN PNM_NODE pNode, IN DWORD dwControlCode );
DWORD FmpUpdateChangeResourceGroup( IN BOOL bSourceNode, IN PFM_RESOURCE pResource, IN PFM_GROUP pNewGroup );
DWORD FmpChangeResourceNode( IN PFM_RESOURCE Resource, IN LPCWSTR NodeId, IN BOOL Add
);
DWORD FmpFixupPossibleNodesForResources( BOOL bJoin );
BOOL FmpEnumFixupPossibleNodesForResource( IN PVOID pContext1, IN PVOID pContext2, IN PFM_RESOURCE pResource, IN LPCWSTR pszResName );
DWORD FmpQueueTimerActivity( IN DWORD dwInterval, IN PFN_TIMER_CALLBACK pfnTimerCb, IN PVOID pContext );
DWORD FmpDelayedStartRes( IN PFM_RESOURCE pResource );
//timer callback functions
void WINAPI FmpReslistOnlineRetryCb( IN HANDLE hTimer, IN PVOID pContext );
VOID FmpDelayedRestartCb( IN HANDLE hTimer, IN PVOID pContext );
DWORD FmpDoMoveGroupOnFailure( IN LPVOID pContext );
DWORD FmpSetOwnerForGroup( IN PFM_GROUP pGroup, IN PNM_NODE pNode );
DWORD FmpSetIntendedOwnerForGroup( IN PFM_GROUP pGroup, IN DWORD dwNodeId );
VOID FmpResetGroupIntendedOwner( IN PGROUP_ENUM pGroupEnum );
DWORD FmpGetGroupInNodeGroupList( OUT PGROUP_ENUM *pReturnEnum, IN PFM_GROUP pGroup, IN LPCWSTR pszDeadNodeId, OUT PBOOL pbQuorumGroup ); VOID FmpPrepareGroupEnumForOnline( IN PGROUP_ENUM pGroupEnum );
DWORD FmpRmExceptionFilter( DWORD ExceptionCode );
DWORD FmpBringQuorumGroupListOnline( IN LPVOID pContext );
DWORD FmpHandleNodeDownEvent( IN PVOID pContext );
DWORD FmpEnumerateGroupResources( IN PFM_GROUP pGroup, IN FM_ENUM_GROUP_RESOURCE_ROUTINE pfnEnumerationRoutine, IN PVOID pContext1, IN PVOID pContext2 );
PNM_NODE FmpGetNonLocalPreferredNode( IN PFM_GROUP Group );
DWORD FmpGetResourceCharacteristics( IN PFM_RESOURCE pQuoResource, OUT LPDWORD pdwCharacteristics ); BOOL FmpIsAnyResourcePersistentStateOnline( IN PFM_GROUP pGroup );
PNM_NODE FmpGetNodeNotHostingUndesiredGroups( IN PFM_GROUP pGroup, IN BOOL fRuleOutLocalNode, IN BOOL fChooseMostPreferredNode );
BOOL FmpCheckForAntiAffinityProperty( IN LPCWSTR lpszLimitOneGroupPerName, IN PGROUP_AFFINITY_NODE_INFO pGroupAffinityNodeInfo, IN PFM_GROUP pGroup, IN LPCWSTR lpszGroupName );
DWORD FmpUpgradeResourceDLL( IN PFM_RESOURCE pResource, IN LPWSTR lpszInstallationPath );
DWORD FmpParsePathForFileName( IN LPWSTR lpszPath, IN BOOL fCheckPathExists, OUT LPWSTR *ppszFileName );
DWORD FmpValidateResourceDLLReplacement( IN PFM_RESOURCE pResource, IN LPWSTR lpszNewDllName, OUT LPWSTR *ppszCurrentDllPath );
DWORD FmpReplaceResourceDLL( IN LPWSTR lpszNewDllName, IN LPWSTR lpszCurrentDllPath, IN LPWSTR lpszInstallationPath );
DWORD FmpRecycleMonitors( IN LPCWSTR lpszDllName );
DWORD FmpCreateMonitorList( IN LPCWSTR lpszDllName, OUT PFM_MONITOR_ENUM_HEADER pMonitorHeader );
BOOL FmpFindHostMonitors( IN LPCWSTR lpszDllName, IN OUT PFM_MONITOR_ENUM_HEADER pMonitorEnumHeader, IN PFM_RESOURCE pResource, IN LPCWSTR lpszResourceId );
DWORD FmpRecoverResourceDLLFiles( VOID );
DWORD FmpResetMultiSzValue( IN HKEY hKey, IN LPWSTR lpmszList, IN OUT LPDWORD pcchLen, IN LPCWSTR lpszValueName, IN LPCWSTR lpszString );
DWORD FmpCopyBackupFile( IN LPCWSTR lpszPath );
VOID FmpDeleteBackupFiles( IN LPCWSTR lpszPath OPTIONAL );
PNM_NODE FmpPickNodeFromPreferredListAtRandom( IN PFM_GROUP pGroup, IN PNM_NODE pSuggestedPreferredNode OPTIONAL, IN BOOL fRuleOutLocalNode, IN BOOL fCheckForDisablingRandomization );
BOOL FmpIsNodeUserPreferred( IN PFM_GROUP pGroup, IN PNM_NODE pPreferredNode );
DWORD FmpPrepareGroupNodeList( OUT PFM_GROUP_NODE_LIST *ppGroupNodeList );
DWORD FmpAddGroupNodeToList( IN PFM_GROUP_NODE_LIST *ppGroupNodeList, IN LPDWORD pcbBuffer, IN PFM_GROUP pGroup, IN LPCWSTR lpszGroupId );
PNM_NODE FmpParseGroupNodeListForPreferredOwner( IN PFM_GROUP pGroup, IN PFM_GROUP_NODE_LIST pGroupNodeList, IN PNM_NODE pSuggestedPreferredNode );
DWORD FmpUpdateUseRandomizedNodeListForGroups( IN BOOL SourceNode, IN LPCWSTR pszNodeId, IN PFM_GROUP_NODE_LIST pGroupNodeList );
VOID FmpClusterWideInitializeResource( IN PFM_RESOURCE pResource );
VOID FmpNotifyResourceStateChangeReason( IN PFM_RESOURCE pResource, IN CLUSTER_RESOURCE_STATE_CHANGE_REASON eReason );
VOID FmpNotifyGroupStateChangeReason( IN PFM_GROUP pGroup, IN CLUSTER_RESOURCE_STATE_CHANGE_REASON eReason );
DWORD FmpGetClusterNameChangeParams( IN LPCWSTR lpszNewName, OUT PFM_RESOURCE *ppCoreNetNameResource, OUT PVOID *ppPropList, OUT LPDWORD pdwPropListSize );
DWORD FmpValidateCoreNetNameChange( IN PFM_RESOURCE pResource, IN PVOID pPropList, IN DWORD cbListSize );
DWORD FmpCoreNetNameChange( IN PFM_RESOURCE pResource, IN PVOID pPropList, IN DWORD cbListSize );
VOID FmpHandleNodeEvictEvent( IN PVOID pContext );
DWORD FmpRmDoHandleCriticalResourceStateChange( IN PRM_EVENT pEvent, IN OPTIONAL PFM_RESOURCE pTransitionedResource, IN CLUSTER_RESOURCE_STATE NewState );
BOOL FmpHandleMonitorCrash( IN PRESMON pCrashedMonitor );
VOID FmpHandleResourceRestartOnMonitorCrash( IN PFM_RESOURCE pResource );
VOID FmpCheckAndUpdateMonitorForDeadlockDetection( IN PRESMON pMonitor );
VOID FmpHandleMonitorDeadlock( IN PRESMON pMonitor );
#endif //ifndef _FMP_H
|