2 Copyright Red Hat, Inc. 2002-2003
4 This program is free software; you can redistribute it and/or modify it
5 under the terms of the GNU General Public License as published by the
6 Free Software Foundation; either version 2, or (at your option) any
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to the
16 Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
20 * User API include file.
22 * Author: Lon Hohberger <lhh at redhat.com>
28 #include <platform.h> /** swab32/etc. */
31 * If you change these, be sure to change the others in RHCM!
33 #define CM_MEMB_PORT 34001
34 #define CM_QUORUM_PORT 34003
37 * Membership type definition. Just a bitmask for now.
41 #define MAX_NODES 16 /** At ship date, this will be 16 */
42 #define MAX_NODES_DISK 2 /** Max # of nodes for disk
44 #define MAX_PARTS_DISK 2
45 #define MAX_NODE_ID (MAX_NODES - 1)
46 #define MEMB_MASK_LEN ((MAX_NODES / 32) + (!!(MAX_NODES % 32)))
48 /** The membership bitmask type */
49 typedef uint32_t memb_mask_t
[MEMB_MASK_LEN
];
52 * APIs for manipulating membership masks. These don't actually do anything
53 * special; they manipulate bitmasks.
57 * Is a specified member online?
59 int memb_online(memb_mask_t mask
, int member
);
62 * Lowest member ID# online.
64 int memb_low_id(memb_mask_t mask
);
67 * Highest member ID# online.
69 int memb_high_id(memb_mask_t mask
);
72 * Number of members online in a given membership mask.
74 int memb_count(memb_mask_t mask
);
79 int memb_local_id(void);
82 * Convert a nodemask into a static string, suitable for printf/syslog/etc.
83 * Destroys previous contents (think strerror()).
84 * XXX Not thread safe.
86 char *memb_mask_str(memb_mask_t mask
);
89 * Mark a member online in a bitmask... This, of course, only modifies an
90 * application's private view of the membership mask - and doesn't cause
91 * member transitions, etc.
93 #define memb_mark_down(mask, member) \
94 clear_bit((uint32_t *)mask, member, MEMB_MASK_LEN)
97 * Mark a member offline in a bitmask. Same rule as above.
99 #define memb_mark_up(mask, member) \
100 set_bit((uint32_t *)mask, member, MEMB_MASK_LEN)
104 * What members were lost between an old view and a new (more recent) view?
106 * @param dest Destination membership mask.
107 * @param old_view Current membership mask.
108 * @param new_view New membership mask.
110 int memb_mask_lost(memb_mask_t dest
, memb_mask_t old_view
,
111 memb_mask_t new_view
);
114 * What members were gained between an old view and a new (more recent) view?
116 * @param dest Destination membership mask.
117 * @param old_view Current membership mask.
118 * @param new_view New membership mask.
120 int memb_mask_gained(memb_mask_t dest
, memb_mask_t old_view
,
121 memb_mask_t new_view
);
125 * Register for events. Returns a file descriptor, or -1 with
126 * errno set appropriately. If errno == ECONNREFUSED, it generally means
127 * that the cluster software isn't running.
129 * Registration for events may not be changed. Unregister and reregister.
130 * This is because membership messages without quorum messages may sometimes
131 * be desired (by, for instance, the quorum daemon ;) ), and will then bypass
132 * the quorum daemon (alleviating the quorum daemon from being the sole
133 * provider of messages) - whereas with both membership messages and quorum
134 * messages (or simply quorum messages), events are passed from the quorum
137 * @param event_class The class of events to which we would like to
139 * @return -1 on failure, or a file descriptor (>= 0) on success.
141 int cm_ev_register(int event_class
);
144 * Close a registration descriptor.
146 * @param fd File descriptor to close.
147 * @return See man close (2)
149 int cm_ev_unregister(int fd
);
152 * Cluster event magic #
154 #define CLUSTER_MAGIC 0x0bad0ace
157 * Event classes: Important(tm) cluster events. Membership changes, quorum
158 * changes, and of course - local-member shutdown events.
160 #define EC_NONE 0 /** ... */
161 #define EC_MEMBERSHIP 1 /** Membership change events */
162 #define EC_QUORUM 2 /** Quorum events */
164 /** You can't actually register for these... */
165 #define EC_QUORUM_TB 4 /** Quorum tiebreaker events */
169 * Important(tm) cluster events.
171 #define EV_NULL 0xCC00 /* Debug... */
172 #define EV_REGISTER 0xCC01 /** Register for events. */
173 #define EV_UNREGISTER 0xCC02 /**
174 * Kill registration for events.
175 * ... this is currently not
176 * implemented, as close(2) works
180 #define EV_MEMB_UPDATE 0xCC04 /** [Committed] change in membership */
181 #define EV_NACK 0xCC05 /** NACK. */
182 #define EV_ACK 0xCC06 /** ACK. */
184 #define EV_QUORUM_GAINED 0x600D /** Quorum gained. Good. */
185 #define EV_QUORUM_LOST 0x0BAD /** Quorum lost. Bad. */
186 #define EV_QUORUM 0xCC07 /** Quorum maintained */
187 #define EV_NO_QUORUM 0xCC08 /** Quorum still not reached */
188 #define EV_SHUTDOWN 0xDEAD /** Local member going down (cleanly) */
191 * Synchronous query messages.
193 #define MEMB_QUERY 0x1313 /** Local membership query req. */
194 #define MEMB_QUERY_NODEID 0x1314 /** Local member ID query */
195 #define QUORUM_QUERY 0x1413 /** Local quorum query */
196 #define QUORUM_QUERY_TB 0x1414 /** Local tiebreaker query */
200 * Results of quorum_tb_query
202 #define EV_TBF_ONLINE (1<<0) /** Flagged as online */
203 #define EV_TBF_NONE (1<<1) /** No tiebreaker in use */
204 #define EV_TBF_DISK (1<<4) /** Disk in use */
205 #define EV_TBF_DISK_OTHER (1<<5) /** Other online, disk only */
206 #define EV_TBF_NET (1<<8) /** Net in use */
207 #define EV_TBF_NET_SOFT (1<<9) /** Soft quorum, net only */
211 * Internal structure defining the header of a cluster manager event.
212 * This should be the same size as generic_msg_hdr for now.
214 typedef struct __attribute__ ((packed
)) _event_hdr
{
216 uint32_t eh_length
; /**< Payload length */
217 uint32_t eh_type
; /**< Event type. */
218 uint32_t eh_event
; /**< Actual event */
219 uint32_t eh_memberid
; /**< Member ID of sender */
222 #define swab_cm_event_hdr_t(ptr) {\
223 swab32((ptr)->eh_magic);\
224 swab32((ptr)->eh_length);\
225 swab32((ptr)->eh_type);\
226 swab32((ptr)->eh_event);\
227 swab32((ptr)->eh_memberid);\
232 * Membership event (data only).
234 typedef struct __attribute__ ((packed
)) _membership_msg
{
241 * cm_ev_read() handles un-swabbing of membership events for us, but
242 * here is what it does (for completeness):
244 #define swab_cm_memb_event_t(ptr, c) {\
245 swab64((ptr)->mm_view);\
246 for (c=0; c<MEMB_MASK_LEN; c++)\
247 swab32((ptr)->mm_mask[c]);\
252 * Quorum event (data only; requires a header)
254 typedef struct __attribute__ ((packed
)) _quorum_msg
{
255 uint64_t qm_view
; /**< View number */
256 memb_mask_t qm_mask
; /**< Membership mask */
257 memb_mask_t qm_mask_panic
; /**< Mask of members in panic
263 * cm_ev_read() handles un-swabbing of quorum events for us, but
264 * here is what it does (for completeness):
266 #define swab_cm_quorum_event_t(ptr, c) {\
267 swab64((ptr)->qm_view);\
268 for (c=0; c<MEMB_MASK_LEN; c++)\
269 swab32((ptr)->qm_mask[c]);\
270 for (c=0; c<MEMB_MASK_LEN; c++)\
271 swab32((ptr)->qm_mask_panic[c]);\
276 * API Event (all types). Any new event types should be included in the
277 * union. This is subject to change; use the macros and such to handle
280 typedef struct __attribute__ ((packed
)) _event_msg
{
281 cm_event_hdr_t em_header
;
283 cm_memb_event_t ev_memb
;
284 cm_quorum_event_t ev_quorum
;
288 cm_event_t
*cm_ev_read(int fd
);
289 void cm_ev_free(cm_event_t
*eventp
);
292 * Handy macros for getting at our data when we receive an event. These
293 * should not be assumed to be macros; and may be functions at some point.
294 * The structure of cm_event_t is subject to change, so do not access
295 * its members directly.
299 * Determine the event type of the message.
301 #define cm_ev_type(msgp) ((cm_event_t *)(msgp))->em_header.eh_type
304 * Determine the actual event of the message
306 #define cm_ev_event(msgp) ((cm_event_t *)(msgp))->em_header.eh_event
309 * Find out the member ID of the sender (for now, this is always the local
312 #define cm_ev_memberid(msgp) ((cm_event_t *)(msgp))->em_header.eh_memberid
315 * ... event specific stuff ...
319 * Point to the memb_mask_t membership view contained within a
322 #define cm_memb_mask(msgp) ((cm_event_t *)(msgp))->u.ev_memb.mm_mask
325 * Point to the membership view number contained within a
328 #define cm_memb_view(msgp) ((cm_event_t *)(msgp))->u.ev_memb.mm_view
332 * Point to the memb_mask_t membership view contained within a
335 #define cm_quorum_mask(msgp) ((cm_event_t *)(msgp))->u.ev_quorum.qm_mask
336 #define cm_quorum_mask_panic(msgp) \
337 ((cm_event_t *)(msgp))->u.ev_quorum.qm_mask_panic
340 * Point to the quorum view number contained within a quorum event.
342 #define cm_quorum_view(msgp) ((cm_event_t *)(msgp))->u.ev_quorum.qm_view
344 /** Synchronous local query for membership */
345 int memb_query(cm_event_t
**result
);
347 /** Synchronous local query for quorum status */
348 int quorum_query(cm_event_t
**result
);
350 /** Synchronous local tiebreaker query for TB status */
351 int quorum_query_tb(cm_event_t
**result
);
353 #endif /* _CM_API_H */