Source code of Windows XP (NT5)
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.

736 lines
30 KiB

  1. #ifndef _WRGP_H_
  2. #define _WRGP_H_
  3. #ifdef __TANDEM
  4. #pragma columns 79
  5. #pragma page "wrgp.h - T9050 - internal declarations for Regroup Module"
  6. #endif
  7. /* @@@ START COPYRIGHT @@@
  8. ** Tandem Confidential: Need to Know only
  9. ** Copyright (c) 1995, Tandem Computers Incorporated
  10. ** Protected as an unpublished work.
  11. ** All Rights Reserved.
  12. **
  13. ** The computer program listings, specifications, and documentation
  14. ** herein are the property of Tandem Computers Incorporated and shall
  15. ** not be reproduced, copied, disclosed, or used in whole or in part
  16. ** for any reason without the prior express written permission of
  17. ** Tandem Computers Incorporated.
  18. **
  19. ** @@@ END COPYRIGHT @@@
  20. **/
  21. /*---------------------------------------------------------------------------
  22. * This file (wrgp.h) contains the cluster_t data type and types used for the
  23. * node pruning algorithm and declares the routines exported by the Cluster
  24. * data type and the node pruning algorithm.
  25. *---------------------------------------------------------------------------*/
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif /* __cplusplus */
  29. #include <jrgp.h>
  30. #include <wrgpos.h>
  31. #include <bitset.h>
  32. #define RGP_VERSION 1 /* version # of data structures */
  33. #define RGP_INITSEQNUM 0 /* starting seq# # of regroup */
  34. #define RGPPKTLEN sizeof(rgp_pkt_t) /* byte length of regroup pkts */
  35. #define IAMALIVEPKTLEN sizeof(iamalive_pkt_t)/* byte length of IamAlive pkts */
  36. #define POISONPKTLEN sizeof(poison_pkt_t) /* byte length of poison pkts */
  37. /*-------------------------------------------------------*/
  38. /* The following are the stages of the regroup algorithm */
  39. /*-------------------------------------------------------*/
  40. #define RGP_COLDLOADED 0
  41. #define RGP_ACTIVATED 1
  42. #define RGP_CLOSING 2
  43. #define RGP_PRUNING 3
  44. #define RGP_PHASE1_CLEANUP 4
  45. #define RGP_PHASE2_CLEANUP 5
  46. #define RGP_STABILIZED 6
  47. /*--------------------------------------------------------------------*/
  48. /* Macros to transform node numbers used by the OS to node numbers */
  49. /* used by the Regroup module and vice versa. Regroup's internal node */
  50. /* numbers start at 0 while the OS starts node numbers at */
  51. /* LOWEST_NODENUM. */
  52. /*--------------------------------------------------------------------*/
  53. #define EXT_NODE(int_node) ((node_t)(int_node + LOWEST_NODENUM))
  54. #define INT_NODE(ext_node) ((node_t)(ext_node - LOWEST_NODENUM))
  55. /*----------------------------------------*/
  56. /* Defines for the node pruning algorithm */
  57. /*----------------------------------------*/
  58. /* The data type "cluster_t" is a bit array of size equal to the maximum
  59. * number of nodes in the cluster. The bit array is implemented as an
  60. * array of uint8s.
  61. *
  62. * Given a node#, its bit position in the bit array is computed by first
  63. * locating the byte in the array (node# / BYTEL) and then the bit in
  64. * the byte. Bits in the byte are numbered 0..7 (from left to right).
  65. * Thus, node 0 is placed in byte 0, bit 0, which is the left-most bit
  66. * in the bit array.
  67. */
  68. #define BYTE(cluster, node) ( (cluster)[(node) / BYTEL] ) /* byte# in array */
  69. #define BIT(node) ( (node) % BYTEL ) /* bit# in byte */
  70. /* The connectivity matrix is an array of elements of type cluster_t.
  71. * cluster_t is equivalent to a bit array with one bit per node. Thus the
  72. * matrix is equivalent to a two-dimensional bit array, with each
  73. * dimension being MAX_CLUSTER_SIZE large. A bit value of 1 for matrix[i][j]
  74. * represents a unidirectional connection between nodes i and j (a
  75. * regroup packet received on node i from node j).
  76. */
  77. typedef cluster_t connectivity_matrix_t[MAX_CLUSTER_SIZE];
  78. #define connected(i,j) (ClusterMember(c[(int)i],j) && \
  79. ClusterMember(c[(int)j],i)) /* bidirectional */
  80. /* Should a node that cannot receive its own regroup packets be considered
  81. * dead? Not necessarily. It may be able to send packets to others and
  82. * be considered alive by everyone. There is no real need for the ability
  83. * to send to yourself on the network. Software bugs could result in
  84. * such a situation. Therefore, the correct way to check if a node is
  85. * alive would be to check if there is a non-zero bit in either the row
  86. * or column corresponding to the node; that is, if the node has
  87. * received regroup packets from or sent regroup packets to any node,
  88. * it may be considered alive. But for simplicity, we will assume in
  89. * the following macro that a node that does not receive its own
  90. * regroup packets will be considered dead.
  91. */
  92. #define node_considered_alive(i) ClusterMember(c[(int)i],i)
  93. /* The upper bound on the number of potential fully-connected groups is
  94. * the lower of 2**N and 2**D where N is the number of live nodes and
  95. * D is the number of disconnects. If this number exceeds MAX_GROUPS,
  96. * do not attempt to exhaustively generate all possible groups;
  97. * just return an arbitrary fully-connected group which includes a
  98. * node selected by the cluster manager.
  99. */
  100. #define MAX_GROUPS 256 /* if more than these, pick arbitrary group */
  101. #define LOG2_MAX_GROUPS 8 /* log (base 2) of MAX_GROUPS */
  102. #define too_many_groups(nodes, disconnects) \
  103. ((nodes > LOG2_MAX_GROUPS) && (disconnects > LOG2_MAX_GROUPS))
  104. /* The disconnect array is an array of (i,j) pairs which represent a
  105. * break in connectivity between nodes i and j.
  106. */
  107. typedef node_t disconnect_array [LOG2_MAX_GROUPS * (LOG2_MAX_GROUPS-1)/2] [2];
  108. /*---------------------------------------------------------------------------*/
  109. /* Following are templates for three kinds of unacknowledged datagrams sent */
  110. /* by the regroup module (regroup pkts, IamAlive pkts and poison pkts). */
  111. /*---------------------------------------------------------------------------*/
  112. //
  113. // We already hand packed all on the wire structures.
  114. // packon will instruct the compiler not to mess with field alignment (kind of)
  115. //
  116. #include <packon.h>
  117. /************************************************************************
  118. * rgp_pkt_t (regroup status packet)
  119. * ---------------------------------
  120. * This structure is used to send the current state of the regroup state
  121. * machine to other nodes.
  122. *
  123. * ___________________________________________________________
  124. * wd0 | pktsubtype | stage | reason | Low8 ignscr |
  125. * |_____________|_______________|_____________________________|
  126. * wd1 | seqno |
  127. * |_____________________________|_____________________________|
  128. * wd2 | activa- | causingnode | quorumowner |
  129. * | tingnode | Hi8 ignscr | (was hadpowerfail) |
  130. * |_____________|_______________|_____________________________|
  131. * wd3 | knownstage1 | knownstage2 |
  132. * |_____________________________|_____________________________|
  133. * wd4 | knownstage3 | knownstage4 |
  134. * |_____________________________|_____________________________|
  135. * wd5 | knownstage5 | pruning_result |
  136. * |_____________________________|_____________________________|
  137. * wd6 : :
  138. * | connectivity_matrix |
  139. * : :
  140. * wd13|___________________________________________________________|
  141. *
  142. *
  143. * pktsubtype - packet subtype = RGP_UNACK_REGROUP
  144. * stage - current stage (state) of the regroup algorithm
  145. * reason - reason for the activation of regroup
  146. * seqno - sequence number of current regroup incident
  147. * activatingnode - node that calls for a regroup incident
  148. * causingnode - node whose poll packet was missed or which
  149. * had a power failure or otherwise caused
  150. * a regroup incident being called for
  151. * quorumowner - mask of nodes that think they own the quorum resrc
  152. * knownstage1 - mask of nodes known to have entered stage 1
  153. * knownstage2 - mask of nodes known to have entered stage 2
  154. * knownstage3 - mask of nodes known to have entered stage 3
  155. * knownstage4 - mask of nodes known to have entered stage 4
  156. * knownstage5 - mask of nodes known to have entered stage 5
  157. * pruning_result - result of node pruning by tie-breaker node
  158. * connectivity_matrix - current connectivity info for entire cluster
  159. *
  160. */
  161. #ifdef __TANDEM
  162. #pragma fieldalign shared8 rgp_pkt
  163. #endif /* __TANDEM */
  164. typedef struct rgp_pkt
  165. {
  166. uint8 pktsubtype;
  167. uint8 stage;
  168. uint16 reason;
  169. uint32 seqno;
  170. uint8 activatingnode;
  171. uint8 causingnode;
  172. cluster_t quorumowner;
  173. cluster_t knownstage1;
  174. cluster_t knownstage2;
  175. cluster_t knownstage3;
  176. cluster_t knownstage4;
  177. cluster_t knownstage5;
  178. cluster_t pruning_result;
  179. connectivity_matrix_t connectivity_matrix;
  180. } rgp_pkt_t;
  181. /************************************************************************
  182. * iamalive_pkt_t
  183. * --------------
  184. * This structure is used by a node to indicate to another node that it
  185. * is alive and well.
  186. *
  187. * ___________________________________________________________
  188. * wd0 | pktsubtype | filler |
  189. * |_____________|_____________________________________________|
  190. * wd1 : :
  191. * | testpattern |
  192. * : :
  193. * wd13|___________________________________________________________|
  194. *
  195. *
  196. * pktsubtype - packet subtype = RGP_UNACK_IAMALIVE
  197. * testpattern - a bit pattern used for testing
  198. *
  199. */
  200. #ifdef __TANDEM
  201. #pragma fieldalign shared8 iamalive_pkt
  202. #endif /* __TANDEM */
  203. typedef struct iamalive_pkt
  204. {
  205. uint8 pktsubtype;
  206. uint8 filler[3];
  207. union
  208. {
  209. uint8 bytes[RGP_UNACK_PKTLEN - 4];
  210. uint32 words[(RGP_UNACK_PKTLEN - 4)/4];
  211. } testpattern;
  212. } iamalive_pkt_t;
  213. /************************************************************************
  214. * poison_pkt_t
  215. * ------------
  216. * This structure is used to send a poison packet to another node to
  217. * force the other node to halt.
  218. *
  219. * ___________________________________________________________
  220. * wd0 | pktsubtype | unused1 | reason |
  221. * |_____________|_______________|_____________________________|
  222. * wd1 | seqno |
  223. * |_____________________________|_____________________________|
  224. * wd2 | activa- | causingnode | |
  225. * | tingnode | | unused2 |
  226. * |_____________|_______________|_____________________________|
  227. * wd3 | initnodes | endnodes |
  228. * |_____________________________|_____________________________|
  229. *
  230. *
  231. * pktsubtype - packet subtype = RGP_UNACK_POISON
  232. * reason - reason for the last activation of regroup
  233. * seqno - current regroup sequence number
  234. * (sequence number of last regroup incident)
  235. * activatingnode - node which called for last regroup incident
  236. * causingnode - node whose poll packet was missed or which
  237. * had a power failure or otherwise caused
  238. * the last regroup incident being called for
  239. * initnodes - mask of nodes at beginning of last regroup
  240. * endnodes - mask of nodes at end of last regroup
  241. *
  242. */
  243. #ifdef __TANDEM
  244. #pragma fieldalign shared8 poison_pkt
  245. #endif /* __TANDEM */
  246. typedef struct poison_pkt
  247. {
  248. uint8 pktsubtype;
  249. uint8 unused1;
  250. uint16 reason;
  251. uint32 seqno;
  252. uint8 activatingnode;
  253. uint8 causingnode;
  254. uint16 unused2;
  255. cluster_t initnodes;
  256. cluster_t endnodes;
  257. } poison_pkt_t;
  258. #include <packoff.h>
  259. //
  260. // There is no room for a 16 bit ignorescreen mask
  261. // in rgp_pkt_t structure. We use a few bit from several
  262. // fields to store the ignore screen.
  263. // The following routines do packing and unpacking
  264. // of ignorescreen from/into the packet
  265. //
  266. extern void PackIgnoreScreen(rgp_pkt_t* to, cluster_t from);
  267. extern void UnpackIgnoreScreen(rgp_pkt_t* from, cluster_t to);
  268. extern void SetMulticastReachable(uint32 mask);
  269. /*---------------------------------------------------------------------------*/
  270. /* This struct is keeps track of the state of each node in the cluster. */
  271. /*---------------------------------------------------------------------------*/
  272. typedef struct
  273. {
  274. uint16 status; /* state of node - alive, dead etc. */
  275. uint16 pollstate; /* whether I'm alives have been received */
  276. uint16 lostHBs; /* tracks the number of consecutive I'm alives lost */
  277. } node_state_t;
  278. /* The status and pollstate fields of the node_state_t struct can have the
  279. * following values.
  280. */
  281. /* Node status of nodes */
  282. #define RGP_NODE_ALIVE 1 /* node is considered alive */
  283. #define RGP_NODE_COMING_UP 2 /* node is coming up */
  284. #define RGP_NODE_DEAD 3 /* node has failed */
  285. #define RGP_NODE_NOT_CONFIGURED 4 /* node is not even configured */
  286. /* IamAlive status codes of nodes */
  287. #define AWAITING_IAMALIVE 1 /* awaiting IamAlives */
  288. #define IAMALIVE_RECEIVED 2 /* got IamAlive */
  289. #define RGP_IAMALIVE_THRESHOLD 100 /* after getting this many Iam- *
  290. * Alives, we check if every *
  291. * node has sent at least one */
  292. /************************************************************************
  293. * rgp_control_t (regroup's only global data structure)
  294. * ----------------------------------------------------
  295. * This structure holds all the Regroup state and other info.
  296. * This is the only global data structure used by Regroup.
  297. *
  298. * NOTE: The word offsets shown in this picture assume that
  299. * MAX_CLUSTER_SIZE is 16.
  300. *
  301. * ___________________________________________________________
  302. * wd0 | |
  303. * : rgpinfo structure :
  304. * : :
  305. * |___________________________________________________________|
  306. * wd3 | mynode | tiebreaker |
  307. * |_____________________________|_____________________________|
  308. * wd4 | num_nodes |
  309. * |___________________________________________________________|
  310. * wd5 | clock_ticks | rgpcounter |
  311. * |_____________________________|_____________________________|
  312. * wd6 | restartcount | pruning_ticks |
  313. * |_____________________________|_____________________________|
  314. * wd7 | pfail_state | flags |
  315. * |_____________________________|_____________________________|
  316. * wd8 | outerscreen | innerscreen |
  317. * |_____________________________|_____________________________|
  318. * wd9 | status_targets | poison_targets |
  319. * |_____________________________|_____________________________|
  320. * wd10| initnodes | endnodes |
  321. * |_____________________________|_____________________________|
  322. * wd11| unreachable_nodes | arbitration_ticks |
  323. * |_____________________________|_____________________________|
  324. * wd12| ignorescreen | filler[0] |
  325. * |_____________________________|_____________________________|
  326. * wd13| filler[1] | filler[2] |
  327. * |_____________________________|_____________________________|
  328. * wd14| |
  329. * : node_states[MAX_CLUSTER_SIZE] :
  330. * : :
  331. * |___________________________________________________________|
  332. * wd30| *nodedown_callback() |
  333. * |___________________________________________________________|
  334. * wd31| *select_cluster() |
  335. * |___________________________________________________________|
  336. * wd32| *rgp_msgsys_p |
  337. * |___________________________________________________________|
  338. * wd33| *received_pktaddr |
  339. * |___________________________________________________________|
  340. * wd34| |
  341. * : rgppkt :
  342. * : :
  343. * |___________________________________________________________|
  344. * wd48| |
  345. * : rgppkt_to_send :
  346. * : :
  347. * |___________________________________________________________|
  348. * wd62| |
  349. * : iamalive_pkt :
  350. * : :
  351. * |___________________________________________________________|
  352. * wd76| |
  353. * : poison_pkt :
  354. * |___________________________________________________________|
  355. * wd80| |
  356. * : :
  357. * : potential_groups[MAX_GROUPS] :
  358. * : :
  359. * |___________________________________________________________|
  360. *wd208| |
  361. * : last_stable_seqno :
  362. * |___________________________________________________________|
  363. *wd212| |
  364. * : internal_connectivity_matrix :
  365. * |___________________________________________________________|
  366. *wdyyy| |
  367. * : OS_specific_control :
  368. *wdxxx|___________________________________________________________|
  369. *
  370. *
  371. * rgpinfo - contains regroup timing parameters and mask of
  372. * fully-integrated cluster (to send IamAlives and monitor)
  373. *
  374. * mynode - node number of local node
  375. *
  376. * tiebreaker - node selected to act as a tie-breaker in the
  377. * split-brain avoidance algorithm and to run the
  378. * pruning algorithm
  379. *
  380. * num_nodes - number of nodes configured in the system, including
  381. * any unused node numbers in the middle; this is equal
  382. * to (the largest configured node# in the system -
  383. * lowest possible node # + 1).
  384. *
  385. * clock_ticks- regroup's internal clock used for checking if it is
  386. * time to send IamAlive packets and to check if IamAlives
  387. * have been received. It is incremented every
  388. * RGP_CLOCK_PERIOD and reset to 0 after checking
  389. * for IamAlives.
  390. *
  391. * rgpcounter - counts regroup clock ticks in a regroup incident in
  392. * order to detect if the algorithm is stalling.
  393. * This is reset when a new regroup incident begins and
  394. * is incremented at each regroup clock tick while
  395. * regroup is perturbed.
  396. *
  397. * restartcount - counts # of regroup algorithm restarts in each regroup
  398. * incident; the node is halted if there are too many
  399. * restarts.
  400. *
  401. * pruning_ticks - number of regroup clock ticks after the tie-breaker
  402. * has been selected; if there are disconnects, the
  403. * tie-breaker should wait a fixed number of ticks
  404. * before running the pruning algorithm.
  405. *
  406. * pfail_state - set to a +ve value when a pfail event is reported
  407. * to regroup. It is decremented at every regroup
  408. * clock tick till it reaches zero. While this number
  409. * is +ve, missing self IamAlives are ignored and
  410. * do not cause the node to halt. This gives the
  411. * sending hardware some time to recover from power
  412. * failures before self IamAlives are checked.
  413. *
  414. * outerscreen - outer recognition mask: nodes not in this mask are
  415. * considered dead or outcasts; if they try to contact
  416. * us, send them poison packets to make sure they stay down
  417. *
  418. * innerscreen - inner recognition mask: nodes not in this mask are
  419. * considered tardy. Regroup packts from them will be
  420. * ignored. They may survive if they can find some
  421. * node which hasn't eliminated them from this screen.
  422. *
  423. * status_targets - nodes to send regroup status packets to
  424. *
  425. * poison_targets - nodes to send poison packets to
  426. *
  427. * initnodes - nodes alive at the beginning of last regroup incident
  428. *
  429. * endnodes - nodes alive at the end of last regroup incident
  430. *
  431. * unreachable_nodes - stores unreachable_node events till the events
  432. * can be processed
  433. *
  434. * arbitration_ticks - number of regroup clock ticks after the arbitration
  435. * started. If arbitration_ticks counter exceeds
  436. * RGP_ARBITRATION_TIMEOUT number of ticks,
  437. * the arbitrating node will shoot itself, and the rest
  438. * of the group will restart the regroup ignoring stalled
  439. * arbitrator
  440. *
  441. * ignorescreen - this is a local copy of ignorescreen passed as
  442. * a part of the regroup packet. The packets from
  443. * the nodes in this screen are ignored and no wait
  444. * for the nodes in ignorescreen is performed in stage 1
  445. *
  446. * last_stable_seqno - this is a sequence number of the last successful regroup.
  447. * It allows to detect really outdated packets
  448. *
  449. * flags:
  450. *
  451. * cautiousmode - need to be "cautious"; wait longer in stage 1
  452. *
  453. * sendstage - This flag is used to indicate whether the
  454. * regroup status packets should indicate we
  455. * are in the current stage. When we enter the
  456. * cleanup stages, we don't let others know we
  457. * are in the stage until the cleanup actions
  458. * are completed.
  459. *
  460. * This flag is set when a new regroup incident
  461. * is started. It is then cleared when we enter
  462. * a cleanup stage and set again when the
  463. * cleanup operations are completed.
  464. *
  465. * tiebreaker_selected - set in stage 2 after tie-breaker is selected
  466. *
  467. * has_unreachable_nodes - set when a node_unreachable event is detected
  468. * in stages 1 or 2. checked in stage 3.
  469. *
  470. * flags_unused - 11 unused bits
  471. *
  472. * node_states[MAX_CLUSTER_SIZE] - state of all the nodes
  473. *
  474. * *nodedown_callback() - registered callback routine to be invoked
  475. * to report node failure
  476. *
  477. * *select_cluster() - registered callback routine to be invoked
  478. * when multiple cluster options exist
  479. *
  480. * *rgp_msgsys_p - pointer to struct shared by regroup and message system
  481. *
  482. * *received_pktaddr - address of rgp packet received
  483. *
  484. * rgp_lock - lock to serialize access to this struct
  485. *
  486. * rgppkt - regroup status in the form of a packet
  487. *
  488. * rgppkt_to_send - regroup packet to be broadcast
  489. *
  490. * iamalive_pkt - I am alive packet to be broadcast
  491. *
  492. * poison_pkt - poison packet to be sent
  493. *
  494. * potential_groups[MAX_GROUPS] - scratch pad for pruning algorithm
  495. *
  496. */
  497. #ifdef __TANDEM
  498. #pragma fieldalign shared8 rgp_control
  499. #endif /* __TANDEM */
  500. typedef struct rgp_control
  501. {
  502. /* timing parameters and cluster membership */
  503. rgpinfo_t rgpinfo;
  504. /* node numbers */
  505. node_t mynode;
  506. node_t tiebreaker;
  507. uint32 num_nodes;
  508. /* various counters counting clock ticks */
  509. uint16 clock_ticks;
  510. uint16 rgpcounter;
  511. uint16 restartcount;
  512. uint16 pruning_ticks;
  513. uint16 pfail_state;
  514. /* rgpflags */
  515. uint16 cautiousmode : 1;
  516. uint16 sendstage : 1;
  517. uint16 tiebreaker_selected : 1;
  518. uint16 has_unreachable_nodes : 1;
  519. uint16 arbitration_started : 1;
  520. uint16 flags_unused : 11;
  521. /* cluster masks */
  522. cluster_t outerscreen;
  523. cluster_t innerscreen;
  524. cluster_t status_targets;
  525. cluster_t poison_targets;
  526. cluster_t initnodes;
  527. cluster_t endnodes;
  528. cluster_t unreachable_nodes;
  529. uint16 arbitration_ticks;
  530. cluster_t ignorescreen;
  531. uint16 filler[3]; /* for alignment and future use */
  532. /* node states */
  533. node_state_t node_states[MAX_CLUSTER_SIZE];
  534. /* callback routines */
  535. void (*nodedown_callback)(cluster_t failed_nodes);
  536. int (*select_cluster)(cluster_t cluster_choices[], int num_clusters);
  537. /* pointers to other structures */
  538. rgp_msgsys_p rgp_msgsys_p;
  539. rgp_pkt_t *received_pktaddr;
  540. /* current status in the form of a regroup packet */
  541. rgp_pkt_t rgppkt;
  542. /* packets to be sent */
  543. rgp_pkt_t rgppkt_to_send;
  544. iamalive_pkt_t iamalive_pkt;
  545. poison_pkt_t poison_pkt;
  546. /* scratch pad for node pruning algorithm */
  547. cluster_t potential_groups[MAX_GROUPS];
  548. /* The rest of the struct is an OS-specific substruct
  549. * (defined in wrgpos.h).
  550. */
  551. uint32 last_stable_seqno;
  552. /* temporary place to collect connectivity information
  553. * while send_stage = 0. (Can't use rgp_pkt conn.matrix,
  554. * because we don't want to see our info until we get
  555. * the first timer tick */
  556. connectivity_matrix_t internal_connectivity_matrix;
  557. OS_specific_rgp_control_t OS_specific_control;
  558. } rgp_control_t;
  559. /*---------------------------------------------------------------------------*/
  560. /* Procedures exported by the Cluster type implementation */
  561. _priv _resident extern void
  562. ClusterInit(cluster_t c);
  563. _priv _resident extern void
  564. ClusterUnion(cluster_t dst, cluster_t src1, cluster_t src2);
  565. _priv _resident extern void
  566. ClusterIntersection(cluster_t dst, cluster_t src1, cluster_t src2);
  567. _priv _resident extern void
  568. ClusterDifference(cluster_t dst, cluster_t src1, cluster_t src2);
  569. _priv _resident extern int
  570. ClusterCompare(cluster_t c1, cluster_t c2);
  571. _priv _resident extern int
  572. ClusterSubsetOf(cluster_t big, cluster_t small);
  573. _priv _resident extern void
  574. ClusterComplement(cluster_t dst, cluster_t src);
  575. _priv _resident extern int
  576. ClusterMember(cluster_t c, node_t i);
  577. _priv _resident extern void
  578. ClusterInsert(cluster_t c, node_t i);
  579. _priv _resident extern void
  580. ClusterDelete(cluster_t c, node_t i);
  581. _priv _resident extern void
  582. ClusterCopy(cluster_t dst, cluster_t src);
  583. _priv _resident extern void
  584. ClusterSwap(cluster_t c1, cluster_t c2);
  585. _priv _resident extern int
  586. ClusterNumMembers(cluster_t c);
  587. extern int
  588. ClusterEmpty(cluster_t c);
  589. /*---------------------------------------------------------------------------*/
  590. /* Function to select the tie-breaker node used in both the split-brain
  591. * avoidance and node pruning algorithms
  592. */
  593. _priv _resident extern node_t
  594. rgp_select_tiebreaker(cluster_t cluster);
  595. /*---------------------------------------------------------------------------*/
  596. /* Procedures exported by the node pruning algorithm */
  597. _priv _resident extern void MatrixInit(connectivity_matrix_t c);
  598. /* Initialize the matrix c to show 0 connectivity. */
  599. _priv _resident extern void
  600. MatrixSet(connectivity_matrix_t c, int row, int column);
  601. /* Set c[row,column] to 1. */
  602. _priv _resident extern void
  603. MatrixOr(connectivity_matrix_t t, connectivity_matrix_t s);
  604. /* OR in s into t. */
  605. _priv _resident extern int connectivity_complete(connectivity_matrix_t c);
  606. /* Returns 1 if all live nodes are connected to all other live nodes
  607. * and 0 if there is at least one disconnect.
  608. */
  609. _priv _resident extern int
  610. find_all_fully_connected_groups(connectivity_matrix_t c,
  611. node_t selected_node,
  612. cluster_t groups[]);
  613. /* Analyzes the connectivity matrix and comes up with the list of
  614. * all maximal, fully-connected groups. Returns the number of
  615. * such groups found. 0 is returned iff there are no live nodes.
  616. */
  617. /*---------------------------------------------------------------------------*/
  618. /* Declaration of Regroup's global data structure */
  619. #ifdef NSK
  620. #include <wmsgsac.h>
  621. #define rgp ((rgp_control_t *) MSGROOT->RegroupControlAddr)
  622. #else
  623. extern rgp_control_t *rgp;
  624. #endif /* NSK */
  625. /*---------------------------------------------------------------------------*/
  626. #ifdef __cplusplus
  627. }
  628. #endif /* __cplusplus */
  629. #if 0
  630. History of changes to this file:
  631. -------------------------------------------------------------------------
  632. 1995, December 13 F40:KSK0610 /*F40:KSK06102.1*/
  633. This file is part of the portable Regroup Module used in the NonStop
  634. Kernel (NSK) and Loosely Coupled UNIX (LCU) operating systems. There
  635. are 10 files in the module - jrgp.h, jrgpos.h, wrgp.h, wrgpos.h,
  636. srgpif.c, srgpos.c, srgpsm.c, srgputl.c, srgpcli.c and srgpsvr.c.
  637. The last two are simulation files to test the Regroup Module on a
  638. UNIX workstation in user mode with processes simulating processor nodes
  639. and UDP datagrams used to send unacknowledged datagrams.
  640. This file was first submitted for release into NSK on 12/13/95.
  641. ------------------------------------------------------------------------------
  642. #endif /* 0 - change descriptions */
  643. #endif /* _WRGP_H_ defined */