/usr/include/libcman.h is in libcman-dev 3.1.7-0ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | #ifndef _LIBCMAN_H_
#define _LIBCMAN_H_
#include <netinet/in.h>
#define LIBCMAN_VERSION 3
/*
* Some maxima
*/
#define CMAN_MAX_ADDR_LEN sizeof(struct sockaddr_in6)
#define CMAN_MAX_NODENAME_LEN 255
#define MAX_CLUSTER_NAME_LEN 16
#define CMAN_MAX_FENCE_AGENT_NAME_LEN 255
/*
* Pass this into cman_get_node() as the nodeid to get local node information
*/
#define CMAN_NODEID_US 0
/*
* Pass this into cman_get_node() as the nodeid to get quorum device information
*/
#define CMAN_NODEID_QDISK -1
/* Pass this into cman_send_data to send a message to all nodes */
#define CMAN_NODEID_ALL 0
/*
* Hang onto this, it's your key into the library. get one from cman_init() or
* cman_admin_init()
*/
typedef void *cman_handle_t;
/*
* Reasons we get an event callback.
* PORTOPENED & TRY_SHUTDOWN only exist when LIBCMAN_VERSION >= 2
*
* The 'arg' parameter varies depending on the callback type.
* for PORTCLOSED/PORTOPENED arg == the port opened/closed
* for STATECHANGE arg is quorum state (1=quorate, 0=not)
* for TRY_SHUTDOWN arg == 1 for ANYWAY, otherwise 0 (ie if arg == 1
* then cman WILL shutdown regardless
* of your response, think of this as advance warning)
* for CONFIG_UPDATE arg will be the new config version
*/
typedef enum {CMAN_REASON_PORTCLOSED,
CMAN_REASON_STATECHANGE,
CMAN_REASON_PORTOPENED,
CMAN_REASON_TRY_SHUTDOWN,
CMAN_REASON_CONFIG_UPDATE} cman_call_reason_t;
/*
* Reason flags for cman_leave
*/
#define CMAN_LEAVEFLAG_DOWN 0
#define CMAN_LEAVEFLAG_REMOVED 3
#define CMAN_LEAVEFLAG_FORCE 0x10
/*
* Flags for cman_shutdown
* ANYWAY - cman will shutdown regardless of clients' responses (but they
* will still get told)
* REMOVED - the rest of the cluster will adjust quorum to stay quorate
*/
#define CMAN_SHUTDOWN_ANYWAY 1
#define CMAN_SHUTDOWN_REMOVED 2
/*
* Flags passed to cman_dispatch():
* CMAN_DISPATCH_ONE dispatches a single message then returns,
* CMAN_DISPATCH_ALL dispatches all outstanding messages (ie till EAGAIN) then
* returns,
* CMAN_DISPATCH_BLOCKING forces it to wait for a message (clears MSG_DONTWAIT
* in recvmsg)
* CMAN_DISPATCH_IGNORE_* allows the caller to select which messages to process.
*/
#define CMAN_DISPATCH_ONE 0
#define CMAN_DISPATCH_ALL 1
#define CMAN_DISPATCH_BLOCKING 2
#define CMAN_DISPATCH_IGNORE_REPLY 4
#define CMAN_DISPATCH_IGNORE_DATA 8
#define CMAN_DISPATCH_IGNORE_EVENT 16
#define CMAN_DISPATCH_TYPE_MASK 3
#define CMAN_DISPATCH_IGNORE_MASK 46
/*
* A node address. This is a complete sockaddr_in[6]
* To explain:
* If you cast cna_address to a 'struct sockaddr', the sa_family field
* will be AF_INET or AF_INET6. Armed with that knowledge you can then
* cast it to a sockaddr_in or sockaddr_in6 and pull out the address.
* No other sockaddr fields are valid.
* Also, you must ignore any part of the sockaddr beyond the length supplied
*/
typedef struct cman_node_address
{
int cna_addrlen;
char cna_address[CMAN_MAX_ADDR_LEN];
} cman_node_address_t;
/*
* Return from cman_get_node()
*/
typedef struct cman_node
{
int cn_nodeid;
cman_node_address_t cn_address;
char cn_name[CMAN_MAX_NODENAME_LEN+1];
int cn_member;
int cn_incarnation;
struct timeval cn_jointime;
} cman_node_t;
/*
* Return from cman_get_node_extra()
*/
typedef struct cman_node_extra
{
int cnx_nodeid;
int cnx_state;
int cnx_votes;
int cnx_expected_votes;
int cnx_leave_reason;
} cman_node_extra_t;
#define CLUSTER_LEAVEREASON_DOWN 0 /* Normal shutdown */
#define CLUSTER_LEAVEREASON_KILLED 1 /* probably buy cman_tool */
#define CLUSTER_LEAVEREASON_PANIC 2 /* Just disappeared */
#define CLUSTER_LEAVEREASON_REMOVED 3 /* This one can reduce quorum */
#define CLUSTER_LEAVEREASON_REJECTED 4 /* Not allowed into the cluster in the first place */
#define CLUSTER_LEAVEREASON_INCONSISTENT 5 /* Our view of the cluster is in a minority */
#define CLUSTER_LEAVEREASON_DEAD 6 /* Discovered to be dead */
#define CLUSTER_LEAVEREASON_NORESPONSE 7 /* Didn't ACK message */
#define CLUSTER_NODESTATE_JOINING 1
#define CLUSTER_NODESTATE_MEMBER 2
#define CLUSTER_NODESTATE_DEAD 3
#define CLUSTER_NODESTATE_LEAVING 4
#define CLUSTER_NODESTATE_DISALLOWED 5
/*
* Returned from cman_get_version(),
* input to cman_set_version(), though only cv_config can be changed
*/
typedef struct cman_version
{
unsigned int cv_major;
unsigned int cv_minor;
unsigned int cv_patch;
unsigned int cv_config;
} cman_version_t;
/*
* Return from cman_get_cluster()
*/
typedef struct cman_cluster
{
char ci_name[MAX_CLUSTER_NAME_LEN+1];
uint16_t ci_number;
uint32_t ci_generation;
} cman_cluster_t;
/*
* This is returned from cman_get_extra_info - it's really
* only for use by cman_tool, don't depend on this not changing
*/
/* Flags in ei_flags */
#define CMAN_EXTRA_FLAG_2NODE 1
#define CMAN_EXTRA_FLAG_ERROR 2
#define CMAN_EXTRA_FLAG_SHUTDOWN 4
#define CMAN_EXTRA_FLAG_DISALLOWED 8
#define CMAN_EXTRA_FLAG_DIRTY 16
#define CMAN_EXTRA_FLAG_DISALLOWED_ENABLED 32
typedef struct cman_extra_info {
int ei_node_state;
int ei_flags;
int ei_node_votes;
int ei_total_votes;
int ei_expected_votes;
int ei_quorum;
int ei_members;
char ei_ports[32];
int ei_num_addresses;
char ei_addresses[1]; /* Array of num_addresses*sockaddr_storage*2
First batch is the multicast address list */
} cman_extra_info_t;
/* Quorum device info, returned from cman_get_quorum_device() */
typedef struct cman_qdev_info {
char qi_name[CMAN_MAX_NODENAME_LEN+1];
int qi_state;
int qi_votes;
} cman_qdev_info_t;
/*
* NOTE: Apart from cman_replyto_shutdown(), you must not
* call other cman_* functions while in these two callbacks:
*/
/* Callback routine for a membership or other event */
typedef void (*cman_callback_t)(cman_handle_t handle, void *privdata, int reason, int arg);
/* Callback routine for data received */
typedef void (*cman_datacallback_t)(cman_handle_t handle, void *privdata,
char *buf, int len, uint8_t port, int nodeid);
/* Callback for nodes joining/leaving */
typedef void (*cman_confchgcallback_t)(cman_handle_t handle, void *privdata,
unsigned int *member_list, int member_list_entries,
unsigned int *left_list, int left_list_entries,
unsigned int *joined_list, int joined_list_entries);
/*
* cman_init returns the handle you need to pass to the other API calls.
* cman_admin_init opens admin socket for privileged operations.
* cman_finish destroys that handle.
*
* Note that admin sockets can't send data messages or receive callbacks.
*/
cman_handle_t cman_init(void *privdata);
cman_handle_t cman_admin_init(void *privdata);
int cman_finish(cman_handle_t handle);
/* Update/retrieve the private data */
int cman_setprivdata(cman_handle_t h, void *privdata);
int cman_getprivdata(cman_handle_t h, void **privdata);
/*
* Notification of membership change events. Note that these are sent after
* a transition, so multiple nodes may have left or joined the cluster.
*/
int cman_start_notification(cman_handle_t handle, cman_callback_t callback);
int cman_stop_notification(cman_handle_t handle);
/*
* Start/stop AIS-style confchg callbacks. These are less racy than the
* old cman callbacks in that the caller will get one for each AIS
* confchg message and it will contain all of the nodes that joined &
* left in that transition.
*/
int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback);
int cman_stop_confchg(cman_handle_t handle);
/* Call this if you get a TRY_SHUTDOWN event to signal whether you
* will let cman shutdown or not.
* Note that getting this callback does not mean that cman WILL shutdown,
* only that it might. To detect a cman shutdown see cman_dispatch() below.
*/
int cman_replyto_shutdown(cman_handle_t, int yesno);
/*
* Get the internal CMAN fd so you can pass it into poll() or select().
* When it's active then call cman_dispatch() on the handle to process the event
* NOTE: This fd can change between calls to cman_dispatch() so always call this
* routine to get the latest one. (This is mainly due to message caching).
* One upshot of this is that you must never read or write this FD (it may on
* occasion point to /dev/zero if you have messages cached!)
*/
int cman_get_fd(cman_handle_t handle);
/*
* cman_dispatch() will return -1 with errno == EHOSTDOWN if the cluster is
* shut down, 0 if nothing was read, or a positive number if something was
* dispatched.
*/
int cman_dispatch(cman_handle_t handle, int flags);
/*
* -----------------------------------------------------------------------------
* Get info calls.
*/
/* Return the number of nodes we know about. This will normally
* be the number of nodes in CCS
*/
int cman_get_node_count(cman_handle_t handle);
/* Returns the number of connected clients. This isn't as useful as a it used to
* be as a count >1 does not automatically mean cman won't shut down. Subsystems
* can decide for themselves whether a clean shutdown is possible.
*/
int cman_get_subsys_count(cman_handle_t handle);
/* Returns an array of node info structures. Call cman_get_node_count() first
* to determine how big your array needs to be
*/
int cman_get_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes);
/* Returns a list of nodes that are known to AIS but blocked from joining the
* CMAN cluster because they rejoined with cluster without a cman_tool join
*/
int cman_get_disallowed_nodes(cman_handle_t handle, int maxnodes, int *retnodes, cman_node_t *nodes);
/*
* cman_get_node() can get node info by nodeid OR by name. If the first
* char of node->cn_name is zero then the nodeid will be used, otherwise
* the name will be used. I'll say this differently: If you want to look
* up a node by nodeid, you MUST clear out the cman_node_t structure passed
* into cman_get_node(). nodeid can be CMAN_NODEID_US.
*/
int cman_get_node(cman_handle_t handle, int nodeid, cman_node_t *node);
/*
* This always gets info by nodeid.
*/
int cman_get_node_extra(cman_handle_t handle, int nodeid, cman_node_extra_t *node);
/* cman_get_node() only returns the first address of a node (whatever /that/
* may mean). If you want to know all of them you need to call this.
* max_addrs is the size of the 'addrs' array. num_addrs will be filled in by
* the number of addresses the node has, regardless of the size of max_addrs.
* So if you don't allocate enough space for the first call, you should know how
* much is needed for a second!
*/
int cman_get_node_addrs(cman_handle_t handle, int nodeid, int max_addrs, int *num_addrs, struct cman_node_address *addrs);
/* Returns 1 if cman has completed initialisation and aisexec is running */
int cman_is_active(cman_handle_t handle);
/*
* Returns 1 if a client is registered for data callbacks on a particular
* port on a particular node. if cman returns -1 (errno==EBUSY) then it
* doesn't currently know the status but has requested it, so try again
* later or wait for a PORTOPENED notification.
* nodeid can be CMAN_NODEID_US
*/
int cman_is_listening(cman_handle_t handle, int nodeid, uint8_t port);
/* Do we have quorum? */
int cman_is_quorate(cman_handle_t handle);
/* Return software & config (cluster.conf file) version */
int cman_get_version(cman_handle_t handle, cman_version_t *version);
/* Get cluster name and number */
int cman_get_cluster(cman_handle_t handle, cman_cluster_t *clinfo);
/*
* These two fencing-related API calls are DEPRECATED from cluster3.
* libfenced should be used instead.
*/
int cman_get_fenceinfo(cman_handle_t handle, int nodeid, uint64_t *fence_time, int *fenced, char *agent);
int cman_node_fenced(cman_handle_t handle, int nodeid, uint64_t fence_time, char *agent);
/* Get stuff for cman_tool. Nobody else should use this */
int cman_get_extra_info(cman_handle_t handle, cman_extra_info_t *info, int maxlen);
/*
* -----------------------------------------------------------------------------
* Admin functions. You will need privileges and have a handle created by
* cman_admin_init() to use them.
*/
/* Change the config file version. This should be needed much less now, as
* cman will re-read the config file if a new node joins with a new config
* version */
int cman_set_version(cman_handle_t handle, const cman_version_t *version);
/* Deprecated in favour of cman_shutdown(). Use cman_tool anyway please. */
int cman_leave_cluster(cman_handle_t handle, int reason);
/* Change the number of votes for this node. NOTE: a CCS update will
overwrite this, so make sure you change both. Or, better, change CCS
and call set_version() */
int cman_set_votes(cman_handle_t handle, int votes, int nodeid);
/* As above, for expected_votes */
int cman_set_expected_votes(cman_handle_t handle, int expected_votes);
/* Tell a particular node to leave the cluster NOW */
int cman_kill_node(cman_handle_t handle, int nodeid);
/*
* cman_shutdown() will send a REASON_TRY_SHUTDOWN event to all
* clients registered for notifications. They should respond by calling
* cman_replyto_shutdown() to indicate whether they will allow
* cman to close down or not. If cman gets >=1 "no" (0) replies or the
* request times out (default 5 seconds) then shutdown will be
* cancelled and cman_shutdown() will return -1 with errno == EBUSY.
*
* Set flags to CMAN_SHUTDOWN_ANYWAY to force shutdown. Clients will still
* be notified /and/ they will know you want a forced shutdown.
*
* Setting flags to CMAN_SHUTDOWN_REMOVED will tell the rest of the
* cluster to adjust quorum to keep running with this node has left
*/
int cman_shutdown(cman_handle_t, int flags);
/* -----------------------------------------------------------------------------
* Data transmission API. Uses the same FD as the rest of the calls.
* If the nodeid passed to cman_send_data() is zero then it will be
* broadcast to all nodes in the cluster.
* cman_start_recv_data() is like a bind(), and marks the port
* as "listening". See cman_is_listening() above.
*/
int cman_send_data(cman_handle_t handle, const void *buf, int len, int flags, uint8_t port, int nodeid);
int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t, uint8_t port);
int cman_end_recv_data(cman_handle_t handle);
/*
* Barrier API.
* Here for backwards compatibility. Most of the things you would achieve
* with this can now be better done using openAIS services or just messaging.
*/
int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes);
int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg);
int cman_barrier_wait(cman_handle_t handle, const char *name);
int cman_barrier_delete(cman_handle_t handle, const char *name);
/*
* Add your own quorum device here, needs an admin socket
*
* register_quorum and update_quorum arguments are mandatory.
* name has to be a valid null-terminated string and votes >= 0.
*
* After creating a quorum device you will need to call 'poll_quorum_device'
* at least once every (default) 10 seconds (this can be changed in CCS)
* otherwise it will time-out and the cluster will lose its vote.
*/
int cman_register_quorum_device(cman_handle_t handle, char *name, int votes);
int cman_unregister_quorum_device(cman_handle_t handle);
int cman_poll_quorum_device(cman_handle_t handle, int isavailable);
int cman_get_quorum_device(cman_handle_t handle, struct cman_qdev_info *info);
int cman_update_quorum_device(cman_handle_t handle, char *name, int votes);
/*
* Sets the dirty bit inside cman. This indicates that the node has
* some internal 'state' (eg in a daemon, filesystem or lock manager)
* and cannot merge with another cluster that already has state.
* This needs an admin socket. It cannot be reset.
*/
int cman_set_dirty(cman_handle_t handle);
/*
* Changes the debug logging level inside cman.
* subsystems is a bitmask of:
*/
#define CMAN_DEBUGLOG_NONE 0
#define CMAN_DEBUGLOG_BARRIER 2
#define CMAN_DEBUGLOG_MEMBERSHIP 4
#define CMAN_DEBUGLOG_DAEMON 8
#define CMAN_DEBUGLOG_AIS 16
int cman_set_debuglog(cman_handle_t handle, int subsystems);
#endif
|