#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