Leaked source code of windows server 2003
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.

1228 lines
27 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. fmclient.c
  5. Abstract:
  6. Cluster client side routines for RPC remote calls.
  7. Author:
  8. Rod Gamache (rodga) 8-Mar-1996
  9. Revision History:
  10. --*/
  11. #include "fmp.h"
  12. #define LOG_MODULE FMCLIENT
  13. DWORD
  14. FmcOnlineGroupRequest(
  15. IN PFM_GROUP Group
  16. )
  17. /*++
  18. Routine Description:
  19. This routine requests (THE) remote system to bring the Group Online.
  20. Arguments:
  21. Group - The Group to bring online.
  22. Returns:
  23. ERROR_SUCCESS if successful.
  24. Win32 error code on failure.
  25. --*/
  26. {
  27. DWORD status;
  28. DWORD OwnerId;
  29. CL_ASSERT(Group->OwnerNode != NmLocalNode);
  30. CL_ASSERT(Group->OwnerNode != NULL);
  31. OwnerId = NmGetNodeId(Group->OwnerNode);
  32. status = FmsOnlineGroupRequest( Session[OwnerId],
  33. OmObjectId(Group) );
  34. return(status);
  35. } // FmcOnlineGroupRequest
  36. DWORD
  37. FmcOfflineGroupRequest(
  38. IN PFM_GROUP Group
  39. )
  40. /*++
  41. Routine Description:
  42. This routine requests a remote system to take the Group Offline.
  43. Arguments:
  44. Group - The Group to take online.
  45. Returns:
  46. ERROR_SUCCESS if successful.
  47. Win32 error code on failure.
  48. --*/
  49. {
  50. DWORD status;
  51. DWORD OwnerId;
  52. CL_ASSERT(Group->OwnerNode != NmLocalNode);
  53. CL_ASSERT(Group->OwnerNode != NULL);
  54. OwnerId = NmGetNodeId(Group->OwnerNode);
  55. CL_ASSERT(Session[OwnerId] != NULL);
  56. status = FmsOfflineGroupRequest( Session[OwnerId],
  57. OmObjectId(Group) );
  58. return(status);
  59. } // FmcOfflineGroupRequest
  60. DWORD
  61. FmcMoveGroupRequest(
  62. IN PFM_GROUP Group,
  63. IN PNM_NODE DestinationNode OPTIONAL
  64. )
  65. /*++
  66. Routine Description:
  67. This routine requests (THE) remote system to move the Group there.
  68. Arguments:
  69. Group - The Group to bring online.
  70. DestinationNode - The node to move the Group to.
  71. Returns:
  72. ERROR_SUCCESS if successful.
  73. Win32 error code on failure.
  74. Notes:
  75. The Group lock must be held on entry.
  76. The Group lock is releaseed before returning.
  77. --*/
  78. {
  79. DWORD status;
  80. DWORD OwnerId;
  81. CL_ASSERT(Group->OwnerNode != NmLocalNode);
  82. #if 1
  83. if ( Group ->OwnerNode == NULL ) {
  84. ClRtlLogPrint(LOG_ERROR,
  85. "[FM] MoveRequest for group with no owner!\n");
  86. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  87. }
  88. #endif
  89. CL_ASSERT(Group->OwnerNode != NULL);
  90. OwnerId = NmGetNodeId(Group->OwnerNode);
  91. FmpReleaseLocalGroupLock( Group );
  92. if (DestinationNode != NULL) {
  93. status = FmsMoveGroupRequest( Session[OwnerId],
  94. OmObjectId(Group ),
  95. OmObjectId(DestinationNode));
  96. } else {
  97. status = FmsMoveGroupRequest( Session[OwnerId],
  98. OmObjectId(Group ),
  99. NULL);
  100. }
  101. return(status);
  102. } // FmcMoveGroupRequest
  103. DWORD
  104. FmcTakeGroupRequest(
  105. IN PNM_NODE DestinationNode,
  106. IN LPCWSTR GroupId,
  107. IN PRESOURCE_ENUM ResourceList
  108. )
  109. /*++
  110. Routine Description:
  111. This routine requests a remote system to move the Group there.
  112. Arguments:
  113. DestinationNode - The destination node
  114. GroupId - The Id of the Group to be moved.
  115. ResourceList - The list of the resources and their states.
  116. Returns:
  117. ERROR_SUCCESS if successful.
  118. Win32 error code on failure.
  119. --*/
  120. {
  121. DWORD status=ERROR_SUCCESS;
  122. RPC_BINDING_HANDLE Binding;
  123. PFM_GROUP group = NULL;
  124. DWORD nodeId;
  125. //
  126. // If the remote session is not established, then return failure.
  127. //
  128. if ( gpQuoResource == NULL ) {
  129. CsInconsistencyHalt(ERROR_INVALID_OPERATION_ON_QUORUM);
  130. }
  131. group = OmReferenceObjectById( ObjectTypeGroup, GroupId );
  132. if ( group == NULL ) {
  133. CsInconsistencyHalt(ERROR_GROUP_NOT_AVAILABLE);
  134. }
  135. if ( gpQuoResource->Group == group ) {
  136. // Quorum group
  137. // We don't need a lock on this usage, since there is only one
  138. Binding = FmpRpcQuorumBindings[NmGetNodeId(DestinationNode)];
  139. if ( Binding == NULL ) {
  140. ClRtlLogPrint(LOG_ERROR,"[FM] TakeRequest and no remote binding available\n");
  141. OmDereferenceObject( group );
  142. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  143. }
  144. OmDereferenceObject( group );
  145. nodeId = NmGetNodeId(DestinationNode);
  146. try {
  147. NmStartRpc(nodeId);
  148. status = FmsTakeGroupRequest( Binding,
  149. GroupId,
  150. ResourceList );
  151. } finally {
  152. NmEndRpc(nodeId);
  153. if( status != RPC_S_OK ) {
  154. NmDumpRpcExtErrorInfo(status);
  155. }
  156. }
  157. } else {
  158. // Non-quorum group
  159. OmDereferenceObject( group );
  160. Binding = FmpRpcBindings[NmGetNodeId(DestinationNode)];
  161. if ( Binding == NULL ) {
  162. ClRtlLogPrint(LOG_ERROR,"[FM] TakeRequest and no remote binding available\n");
  163. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  164. }
  165. // This is a shared binding, so serialize usage.
  166. //
  167. // Charlie Wickham (charlwi) - 10/30/00
  168. //
  169. // 185575: removing use of unique RPC binding handles hence no longer
  170. // any need to serialize take group requests.
  171. //
  172. // FmpAcquireBindingLock();
  173. //
  174. // Chittur Subbaraman (chitturs) - 9/30/99
  175. //
  176. // Enclose the RPC within a "try-finally" block so that the
  177. // lock is released regardless of whether the RPC succeeds.
  178. // Note that the caller of FmcTakeGroupRequest encloses
  179. // that function in a "try-except" block.
  180. //
  181. nodeId = NmGetNodeId(DestinationNode);
  182. try {
  183. NmStartRpc(nodeId);
  184. status = FmsTakeGroupRequest( Binding,
  185. GroupId,
  186. ResourceList );
  187. } finally {
  188. NmEndRpc(nodeId);
  189. if( status != RPC_S_OK ) {
  190. NmDumpRpcExtErrorInfo(status);
  191. }
  192. // FmpReleaseBindingLock();
  193. }
  194. }
  195. return(status);
  196. } // FmcTakeGroupRequest
  197. DWORD
  198. FmcOnlineResourceRequest(
  199. IN PFM_RESOURCE Resource
  200. )
  201. /*++
  202. Routine Description:
  203. This routine requests (THE) remote system to bring the Resource Online.
  204. Arguments:
  205. Resource - The resource to bring online.
  206. Returns:
  207. ERROR_SUCCESS if successful.
  208. Win32 error code on failure.
  209. --*/
  210. {
  211. DWORD status;
  212. DWORD NodeId;
  213. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  214. NodeId = NmGetNodeId(Resource->Group->OwnerNode);
  215. CL_ASSERT(Session[NodeId] != NULL);
  216. status = FmsOnlineResourceRequest( Session[NodeId],
  217. OmObjectId(Resource) );
  218. return(status);
  219. } // FmcOnlineResourceRequest
  220. DWORD
  221. FmcOfflineResourceRequest(
  222. IN PFM_RESOURCE Resource
  223. )
  224. /*++
  225. Routine Description:
  226. This routine requests (THE) remote system to take the Resource Offline.
  227. Arguments:
  228. Resource - The resource to take offline.
  229. Returns:
  230. ERROR_SUCCESS if successful.
  231. Win32 error code on failure.
  232. --*/
  233. {
  234. DWORD status;
  235. DWORD NodeId;
  236. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  237. NodeId = NmGetNodeId(Resource->Group->OwnerNode);
  238. CL_ASSERT(Session[NodeId] != NULL);
  239. status = FmsOfflineResourceRequest( Session[NodeId],
  240. OmObjectId(Resource) );
  241. return(status);
  242. } // FmcOfflineResourceRequest
  243. DWORD
  244. FmcChangeResourceNode(
  245. IN PFM_RESOURCE Resource,
  246. IN PNM_NODE Node,
  247. IN BOOL Add
  248. )
  249. /*++
  250. Routine Description:
  251. This routine requests the owner of the resource to perform the change
  252. resource node operation.
  253. Arguments:
  254. Resource - The resource to change the resource node.
  255. Node - The node to be added/removed from the resource list.
  256. Add - Specifies whether to add or remove the given node.
  257. Returns:
  258. ERROR_SUCCESS if successful.
  259. Win32 error code on failure.
  260. Note:
  261. The resource's lock must be held on entry. It is released prior to
  262. returning.
  263. --*/
  264. {
  265. DWORD status;
  266. DWORD NodeId;
  267. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  268. NodeId = NmGetNodeId(Resource->Group->OwnerNode);
  269. CL_ASSERT(Session[NodeId] != NULL);
  270. FmpReleaseLocalResourceLock( Resource );
  271. status = FmsChangeResourceNode( Session[NodeId],
  272. OmObjectId(Resource),
  273. OmObjectId(Node),
  274. Add );
  275. return(status);
  276. } // FmcChangeResourceNode
  277. DWORD
  278. FmcArbitrateResource(
  279. IN PFM_RESOURCE Resource
  280. )
  281. /*++
  282. Routine Description:
  283. This routine requests a remote system to arbitrate a resource.
  284. Arguments:
  285. Resource - The resource to arbitrate.
  286. Returns:
  287. ERROR_SUCCESS if successful.
  288. Win32 error code on failure.
  289. --*/
  290. {
  291. DWORD status;
  292. DWORD nodeId;
  293. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  294. nodeId = NmGetNodeId(Resource->Group->OwnerNode);
  295. CL_ASSERT(Session[nodeId] != NULL);
  296. status = FmsArbitrateResource( Session[nodeId],
  297. OmObjectId(Resource) );
  298. return(status);
  299. } // FmcArbitrateResource
  300. VOID
  301. FmcDeleteEnum(
  302. IN PGROUP_ENUM Enum
  303. )
  304. /*++
  305. Routine Description:
  306. This routine deletes an GROUP_ENUM and associated name strings.
  307. Arguments:
  308. Enum - The GROUP_ENUM to delete. This pointer can be NULL.
  309. Returns:
  310. None.
  311. Notes:
  312. This routine will take a NULL input pointer and just return.
  313. --*/
  314. {
  315. DWORD i;
  316. if ( Enum == NULL ) {
  317. return;
  318. }
  319. for ( i = 0; i < Enum->EntryCount; i++ ) {
  320. MIDL_user_free(Enum->Entry[i].Id);
  321. }
  322. MIDL_user_free(Enum);
  323. return;
  324. } // FmcDeleteEnum
  325. DWORD
  326. FmcFailResource(
  327. IN PFM_RESOURCE Resource
  328. )
  329. /*++
  330. Routine Description:
  331. This routine requests a remote system to fail a resource.
  332. Arguments:
  333. Resource - The resource to fail.
  334. Returns:
  335. ERROR_SUCCESS if successful.
  336. Win32 error code on failure.
  337. --*/
  338. {
  339. DWORD status;
  340. DWORD nodeId;
  341. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  342. nodeId = NmGetNodeId(Resource->Group->OwnerNode);
  343. CL_ASSERT(Session[nodeId] != NULL);
  344. status = FmsFailResource( Session[nodeId],
  345. OmObjectId(Resource) );
  346. return(status);
  347. } // FmcFailResource
  348. PFM_RESOURCE
  349. FmcCreateResource(
  350. IN PFM_GROUP Group,
  351. IN LPWSTR ResourceId,
  352. IN LPCWSTR ResourceName,
  353. IN LPCWSTR ResourceType,
  354. IN DWORD dwFlags
  355. )
  356. /*++
  357. Routine Description:
  358. This routine requests a remote system to create a resource. The
  359. remote system should 'own' the group.
  360. Arguments:
  361. Group - The group that the resource should be created inside.
  362. ResourceId - The id of the resource to create.
  363. ResourceName - The name of the resource to create.
  364. ResourceType - Resource type name
  365. dwFlags - Flags for the resource.
  366. Returns:
  367. ERROR_SUCCESS if successful.
  368. Win32 error code on failure.
  369. Notes:
  370. The Group lock should be held... and is released by this routine.
  371. --*/
  372. {
  373. DWORD status;
  374. DWORD nodeId;
  375. PFM_RESOURCE resource = NULL;
  376. DWORD dwClusterHighestVersion;
  377. CL_ASSERT(Group->OwnerNode != NULL);
  378. nodeId = NmGetNodeId(Group->OwnerNode);
  379. CL_ASSERT(Session[nodeId] != NULL);
  380. FmpReleaseLocalGroupLock( Group );
  381. NmGetClusterOperationalVersion( &dwClusterHighestVersion,
  382. NULL,
  383. NULL );
  384. if ( CLUSTER_GET_MAJOR_VERSION( dwClusterHighestVersion ) <
  385. NT51_MAJOR_VERSION )
  386. {
  387. status = FmsCreateResource( Session[nodeId],
  388. OmObjectId(Group),
  389. ResourceId,
  390. ResourceName );
  391. } else
  392. {
  393. status = FmsCreateResource2( Session[nodeId],
  394. OmObjectId(Group),
  395. ResourceId,
  396. ResourceName,
  397. ResourceType,
  398. dwFlags );
  399. }
  400. if ( status == ERROR_SUCCESS ) {
  401. resource = OmReferenceObjectById( ObjectTypeResource,
  402. ResourceId );
  403. if ( resource != NULL ) {
  404. OmDereferenceObject( resource );
  405. }
  406. } else {
  407. SetLastError(status);
  408. }
  409. return(resource);
  410. } // FmcCreateResource
  411. DWORD
  412. FmcDeleteResource(
  413. IN PFM_RESOURCE Resource
  414. )
  415. /*++
  416. Routine Description:
  417. This routine requests a remote system to delete a resource.
  418. Arguments:
  419. Resource - The resource to delete.
  420. Returns:
  421. ERROR_SUCCESS if successful.
  422. Win32 error code on failure.
  423. Notes:
  424. The Resource lock should be held... and is released by this routine.
  425. --*/
  426. {
  427. DWORD status;
  428. DWORD nodeId;
  429. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  430. nodeId = NmGetNodeId(Resource->Group->OwnerNode);
  431. CL_ASSERT(Session[nodeId] != NULL);
  432. FmpReleaseLocalResourceLock( Resource );
  433. status = FmsDeleteResource( Session[nodeId],
  434. OmObjectId(Resource) );
  435. return(status);
  436. } // FmcDeleteResource
  437. DWORD
  438. FmcResourceControl(
  439. IN PNM_NODE Node,
  440. IN PFM_RESOURCE Resource,
  441. IN DWORD ControlCode,
  442. IN PUCHAR InBuffer,
  443. IN DWORD InBufferSize,
  444. OUT PUCHAR OutBuffer,
  445. IN DWORD OutBufferSize,
  446. OUT LPDWORD BytesReturned,
  447. OUT LPDWORD Required
  448. )
  449. /*++
  450. Routine Description:
  451. This routine passes a resource control request to a remote system.
  452. Arguments:
  453. Node - the remote node to send the request to.
  454. Resource - the resource to handle the request.
  455. ControlCode - the control code for this request.
  456. InBuffer - the input buffer.
  457. InBufferSize - the size of the input buffer.
  458. OutBuffer - the output buffer.
  459. OutBuffer - the size of the output buffer.
  460. BytesReturned - the length of the returned data.
  461. Required - the number of bytes required if OutBuffer is not big enough.
  462. Returns:
  463. ERROR_SUCCESS if successful.
  464. Win32 error code on failure.
  465. --*/
  466. {
  467. DWORD status;
  468. DWORD NodeId;
  469. DWORD Dummy;
  470. DWORD dwTmpBytesReturned;
  471. DWORD dwTmpBytesRequired;
  472. NodeId = NmGetNodeId(Node);
  473. if ((NmGetNodeState(Node) != ClusterNodeUp) &&
  474. ( NmGetNodeState(Node) != ClusterNodePaused))
  475. {
  476. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  477. }
  478. CL_ASSERT(Session[NodeId] != NULL);
  479. //to take care of the output reference pointer which cannot be NULL.
  480. if (!OutBuffer)
  481. {
  482. OutBuffer = (PUCHAR)&Dummy;
  483. OutBufferSize = 0;
  484. }
  485. if (!BytesReturned)
  486. BytesReturned = &dwTmpBytesReturned;
  487. if (!Required)
  488. Required = &dwTmpBytesRequired;
  489. status = FmsResourceControl( Session[NodeId],
  490. OmObjectId(Resource),
  491. ControlCode,
  492. InBuffer,
  493. InBufferSize,
  494. OutBuffer,
  495. OutBufferSize,
  496. BytesReturned,
  497. Required );
  498. return(status);
  499. } // FmcResourceControl
  500. DWORD
  501. FmcResourceTypeControl(
  502. IN PNM_NODE Node,
  503. IN LPCWSTR ResourceTypeName,
  504. IN DWORD ControlCode,
  505. IN PUCHAR InBuffer,
  506. IN DWORD InBufferSize,
  507. OUT PUCHAR OutBuffer,
  508. IN DWORD OutBufferSize,
  509. OUT LPDWORD BytesReturned,
  510. OUT LPDWORD Required
  511. )
  512. /*++
  513. Routine Description:
  514. This routine passes a resource type control request to a remote system.
  515. Arguments:
  516. Node - the remote node to send the request to.
  517. ResourceTypeName - the name of the resource type to handle the request.
  518. ControlCode - the control code for this request.
  519. InBuffer - the input buffer.
  520. InBufferSize - the size of the input buffer.
  521. OutBuffer - the output buffer.
  522. OutBuffer - the size of the output buffer.
  523. BytesReturned - the length of the returned data.
  524. Required - the number of bytes required if OutBuffer is not big enough.
  525. Returns:
  526. ERROR_SUCCESS if successful.
  527. Win32 error code on failure.
  528. --*/
  529. {
  530. DWORD status;
  531. DWORD NodeId;
  532. NodeId = NmGetNodeId(Node);
  533. if (( NmGetNodeState(Node) != ClusterNodeUp ) &&
  534. ( NmGetNodeState(Node) != ClusterNodePaused )) {
  535. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  536. }
  537. CL_ASSERT(Session[NodeId] != NULL);
  538. status = FmsResourceTypeControl( Session[NodeId],
  539. ResourceTypeName,
  540. ControlCode,
  541. InBuffer,
  542. InBufferSize,
  543. OutBuffer,
  544. OutBufferSize,
  545. BytesReturned,
  546. Required );
  547. return(status);
  548. } // FmcResourceTypeControl
  549. DWORD
  550. FmcGroupControl(
  551. IN PNM_NODE Node,
  552. IN PFM_GROUP Group,
  553. IN DWORD ControlCode,
  554. IN PUCHAR InBuffer,
  555. IN DWORD InBufferSize,
  556. OUT PUCHAR OutBuffer,
  557. IN DWORD OutBufferSize,
  558. OUT LPDWORD BytesReturned,
  559. OUT LPDWORD Required
  560. )
  561. /*++
  562. Routine Description:
  563. This routine passes a resource control request to a remote system.
  564. Arguments:
  565. Node - the remote node to send the request to.
  566. Group - the group to handle the request.
  567. ControlCode - the control code for this request.
  568. InBuffer - the input buffer.
  569. InBufferSize - the size of the input buffer.
  570. OutBuffer - the output buffer.
  571. OutBuffer - the size of the output buffer.
  572. BytesReturned - the length of the returned data.
  573. Required - the number of bytes required if OutBuffer is not big enough.
  574. Returns:
  575. ERROR_SUCCESS if successful.
  576. Win32 error code on failure.
  577. --*/
  578. {
  579. DWORD status;
  580. DWORD NodeId;
  581. NodeId = NmGetNodeId(Node);
  582. if (( NmGetNodeState(Node) != ClusterNodeUp ) &&
  583. ( NmGetNodeState(Node) != ClusterNodePaused )) {
  584. return(ERROR_HOST_NODE_NOT_AVAILABLE);
  585. }
  586. CL_ASSERT(Session[NodeId] != NULL);
  587. status = FmsGroupControl( Session[NodeId],
  588. OmObjectId(Group),
  589. ControlCode,
  590. InBuffer,
  591. InBufferSize,
  592. OutBuffer,
  593. OutBufferSize,
  594. BytesReturned,
  595. Required );
  596. return(status);
  597. } // FmcGroupControl
  598. DWORD
  599. FmcPrepareQuorumResChange(
  600. IN PFM_RESOURCE Resource,
  601. IN LPCWSTR lpszQuoLogPath,
  602. IN DWORD dwMaxQuoLogSize
  603. )
  604. /*++
  605. Routine Description:
  606. This routine requests a the owner of a potential quorum resource
  607. to prepare for quorum logging and registry replication.
  608. Arguments:
  609. Resource - The resource to on which we want to start logging.
  610. lpszQuoLogPath - The Path where the cluster log files should be created.
  611. dwMaxQuoLogSize - The new max Quorum Log Size.
  612. Returns:
  613. ERROR_SUCCESS if successful.
  614. Win32 error code on failure.
  615. --*/
  616. {
  617. DWORD status;
  618. DWORD nodeId;
  619. CL_ASSERT(Resource->Group->OwnerNode != NULL);
  620. nodeId = NmGetNodeId(Resource->Group->OwnerNode);
  621. CL_ASSERT(Session[nodeId] != NULL);
  622. status = FmsPrepareQuorumResChange( Session[nodeId],
  623. OmObjectId(Resource),
  624. lpszQuoLogPath,
  625. dwMaxQuoLogSize );
  626. return(status);
  627. } // FmcPrepareQuorumResChange
  628. DWORD
  629. FmcCompleteQuorumResChange(
  630. IN PFM_RESOURCE pOldQuoRes,
  631. IN LPCWSTR lpszOldQuoLogPath
  632. )
  633. /*++
  634. Routine Description:
  635. This routine requests a the owner of the previous quorum resource
  636. to clean up after quorum resource change is complete.
  637. Arguments:
  638. pOldQuoRes - The resource to on which we want to start logging.
  639. lpszOldQuoLogPath - The Path where the cluster log files should be created.
  640. Returns:
  641. ERROR_SUCCESS if successful.
  642. Win32 error code on failure.
  643. --*/
  644. {
  645. DWORD status;
  646. DWORD nodeId;
  647. CL_ASSERT(pOldQuoRes->Group->OwnerNode != NULL);
  648. nodeId = NmGetNodeId(pOldQuoRes->Group->OwnerNode);
  649. CL_ASSERT(Session[nodeId] != NULL);
  650. status = FmsCompleteQuorumResChange( Session[nodeId],
  651. OmObjectId(pOldQuoRes),
  652. lpszOldQuoLogPath);
  653. return(status);
  654. } // FmcCompleteQuorumResChange
  655. DWORD
  656. FmcChangeResourceGroup(
  657. IN PFM_RESOURCE pResource,
  658. IN PFM_GROUP pNewGroup
  659. )
  660. /*++
  661. Routine Description:
  662. This routine requests the owner of the resource to move the resource
  663. from one group to another.
  664. Arguments:
  665. Resource - The resource whose group is to be changed.
  666. pNewGroup - The group to which the resource should be moved to.
  667. Returns:
  668. ERROR_SUCCESS if successful.
  669. Win32 error code on failure.
  670. Note:
  671. The group locks for both the old and the new group must be held on entry.
  672. They are release before making the rpc call.
  673. --*/
  674. {
  675. DWORD status;
  676. DWORD NodeId;
  677. CL_ASSERT(pResource->Group->OwnerNode != NULL);
  678. NodeId = NmGetNodeId(pResource->Group->OwnerNode);
  679. CL_ASSERT(Session[NodeId] != NULL);
  680. FmpReleaseLocalGroupLock( pResource->Group );
  681. FmpReleaseLocalGroupLock( pNewGroup );
  682. status = FmsChangeResourceGroup( Session[NodeId],
  683. OmObjectId(pResource),
  684. OmObjectId(pNewGroup));
  685. return(status);
  686. } // FmcChangeResourceNode
  687. DWORD
  688. FmcBackupClusterDatabase(
  689. IN PFM_RESOURCE pQuoResource,
  690. IN LPCWSTR lpszPathName
  691. )
  692. /*++
  693. Routine Description:
  694. This routine requests the owner of a potential quorum resource
  695. to backup the quorum log and the checkpoint file to the
  696. specified path. This function is called with the resource lock
  697. held.
  698. Arguments:
  699. pQuoResource - The quorum resource.
  700. lpszPathName - The directory path name where the files have to be
  701. backed up. This path must be visible to the node
  702. on which the quorum resource is online.
  703. Returns:
  704. ERROR_SUCCESS if successful.
  705. Win32 error code on failure.
  706. --*/
  707. {
  708. DWORD status;
  709. DWORD nodeId;
  710. CL_ASSERT( pQuoResource->Group->OwnerNode != NULL );
  711. nodeId = NmGetNodeId( pQuoResource->Group->OwnerNode );
  712. CL_ASSERT( Session[nodeId] != NULL );
  713. //
  714. // Chittur Subbaraman (chitturs) - 10/16/98
  715. //
  716. // Release the resource lock. Releasing the resource lock
  717. // here can create a window during which this node thinks
  718. // the other node is the owner and the other node thinks
  719. // this node is the owner. But, unfortunately we've to treat
  720. // this as an error case so that we don't run into deadlocks
  721. // across multiple machines due to the lock being held while
  722. // making the RPC.
  723. //
  724. FmpReleaseLocalResourceLock( pQuoResource );
  725. status = FmsBackupClusterDatabase( Session[nodeId],
  726. OmObjectId( pQuoResource ),
  727. lpszPathName );
  728. return( status );
  729. } // FmcBackupClusterDatabase
  730. /****
  731. @func DWORD | FmcDeleteGroup| This makes a rpc call to the owner
  732. of the group to handle the delete group request.
  733. @parm IN PFM_GROUB | pGroup | The group that must be deleted.
  734. @comm The owner node should make the GUM request to avoid deadlocks.
  735. @rdesc Returns a result code. ERROR_SUCCESS on success.
  736. ****/
  737. DWORD
  738. FmcDeleteGroupRequest(
  739. IN PFM_GROUP pGroup
  740. )
  741. {
  742. DWORD dwOwnerId;
  743. DWORD dwStatus;
  744. dwOwnerId = NmGetNodeId(pGroup->OwnerNode);
  745. CL_ASSERT(dwOwnerId != NmLocalNodeId);
  746. //release the lock before making the rpc call
  747. FmpReleaseLocalGroupLock( pGroup );
  748. dwStatus = FmsDeleteGroupRequest( Session[dwOwnerId],
  749. OmObjectId(pGroup)
  750. );
  751. return(dwStatus);
  752. }
  753. /****
  754. @func DWORD | FmcAddResourceDependency | This makes an RPC to the
  755. owner of the resource to handle the dependency addition.
  756. @parm IN PFM_RESOURCE | pResource | The resource to add the
  757. dependent resource.
  758. @parm IN PFM_RESOURCE | pDependentResource | The dependent resource.
  759. @comm The owner node should make the GUM request to avoid deadlocks.
  760. @rdesc Returns an error code. ERROR_SUCCESS on success.
  761. ****/
  762. DWORD
  763. FmcAddResourceDependency(
  764. IN PFM_RESOURCE pResource,
  765. IN PFM_RESOURCE pDependentResource
  766. )
  767. {
  768. DWORD dwOwnerId;
  769. DWORD dwStatus;
  770. dwOwnerId = NmGetNodeId( pResource->Group->OwnerNode );
  771. CL_ASSERT( dwOwnerId != NmLocalNodeId );
  772. //
  773. // Release the lock before making the RPC call
  774. //
  775. FmpReleaseLocalResourceLock( pResource );
  776. dwStatus = FmsAddResourceDependency( Session[dwOwnerId],
  777. OmObjectId( pResource ),
  778. OmObjectId( pDependentResource )
  779. );
  780. return( dwStatus );
  781. }
  782. /****
  783. @func DWORD | FmcRemoveResourceDependency | This makes an RPC to the
  784. owner of the resource to handle the dependency removal.
  785. @parm IN PFM_RESOURCE | pResource | The resource to remove the
  786. dependent resource from.
  787. @parm IN PFM_RESOURCE | pDependentResource | The dependent resource.
  788. @comm The owner node should make the GUM request to avoid deadlocks.
  789. @rdesc Returns an error code. ERROR_SUCCESS on success.
  790. ****/
  791. DWORD
  792. FmcRemoveResourceDependency(
  793. IN PFM_RESOURCE pResource,
  794. IN PFM_RESOURCE pDependentResource
  795. )
  796. {
  797. DWORD dwOwnerId;
  798. DWORD dwStatus;
  799. dwOwnerId = NmGetNodeId( pResource->Group->OwnerNode );
  800. CL_ASSERT( dwOwnerId != NmLocalNodeId );
  801. //
  802. // Release the lock before making the RPC call
  803. //
  804. FmpReleaseLocalResourceLock( pResource );
  805. dwStatus = FmsRemoveResourceDependency( Session[dwOwnerId],
  806. OmObjectId( pResource ),
  807. OmObjectId( pDependentResource )
  808. );
  809. return( dwStatus );
  810. }