47#include <sys/socket.h>
66#define SAM_CMAP_S_FAILED "failed"
67#define SAM_CMAP_S_REGISTERED "stopped"
68#define SAM_CMAP_S_STARTED "running"
69#define SAM_CMAP_S_Q_WAIT "waiting for quorum"
71#define SAM_RP_MASK_Q(pol) (pol & (~SAM_RECOVERY_POLICY_QUORUM))
72#define SAM_RP_MASK_C(pol) (pol & (~SAM_RECOVERY_POLICY_CMAP))
73#define SAM_RP_MASK(pol) (pol & (~(SAM_RECOVERY_POLICY_QUORUM | SAM_RECOVERY_POLICY_CMAP)))
168 hc_period = sam_internal_data.time_interval;
215static cs_error_t sam_cmap_destroy_pid_path (
void)
227 cmap_delete(sam_internal_data.cmap_handle, key_name);
260 sam_cmap_destroy_pid_path ();
265static void quorum_notification_fn (
272 sam_internal_data.quorate =
quorate;
305 if ((
err =
quorum_fd_get (sam_internal_data.quorum_handle, &sam_internal_data.quorum_fd)) !=
CS_OK) {
322 sam_internal_data.warn_signal =
SIGTERM;
324 sam_internal_data.am_i_child = 0;
326 sam_internal_data.user_data =
NULL;
327 sam_internal_data.user_data_size = 0;
328 sam_internal_data.user_data_allocated = 0;
343static size_t sam_safe_write (
371static size_t sam_safe_read (
412 if (sam_safe_read (sam_internal_data.child_fd_in, &
err,
sizeof (
err)) !=
sizeof (
err)) {
446 *size = sam_internal_data.user_data_size;
474 if (sam_internal_data.user_data_size == 0) {
480 if (size < sam_internal_data.user_data_size) {
486 memcpy (data, sam_internal_data.user_data, sam_internal_data.user_data_size);
520 if (sam_internal_data.am_i_child) {
531 if (sam_safe_write (sam_internal_data.child_fd_out, &size,
sizeof (size)) !=
sizeof (size)) {
537 if (data !=
NULL && sam_safe_write (sam_internal_data.child_fd_out, data, size) != size) {
546 if ((
err = sam_read_reply (sam_internal_data.child_fd_in)) !=
CS_OK) {
555 free (sam_internal_data.user_data);
556 sam_internal_data.user_data =
NULL;
557 sam_internal_data.user_data_allocated = 0;
558 sam_internal_data.user_data_size = 0;
560 if (sam_internal_data.user_data_allocated < size) {
567 sam_internal_data.user_data_allocated = size;
569 new_data = sam_internal_data.user_data;
571 sam_internal_data.user_data =
new_data;
572 sam_internal_data.user_data_size = size;
574 memcpy (sam_internal_data.user_data, data, size);
597 recpol = sam_internal_data.recovery_policy;
617 if ((
err = sam_read_reply (sam_internal_data.child_fd_in)) !=
CS_OK) {
626 if (sam_internal_data.hc_callback)
662 if ((
err = sam_read_reply (sam_internal_data.child_fd_in)) !=
CS_OK) {
671 if (sam_internal_data.hc_callback)
714 free (sam_internal_data.user_data);
754 if (sam_internal_data.am_i_child) {
775 if ((
err = sam_read_reply (sam_internal_data.child_fd_in)) !=
CS_OK) {
876 while (!sam_internal_data.quorate) {
881 pfds[1].fd = sam_internal_data.quorum_fd;
961 if (!sam_internal_data.term_send) {
967 sam_internal_data.term_send = 1;
979static cs_error_t sam_parent_mark_child_failed (
985 recpol = sam_internal_data.recovery_policy;
987 sam_internal_data.term_send = 1;
1006 if (sam_safe_read (
parent_fd_in, &size,
sizeof (size)) !=
sizeof (size)) {
1058 recpol = sam_internal_data.recovery_policy;
1063 pfds[0].revents = 0;
1066 if (
status == 1 && sam_internal_data.time_interval != 0) {
1073 pfds[
nfds].fd = sam_internal_data.quorum_fd;
1185 pfds[1].revents != 0) {
1218 recpol = sam_internal_data.recovery_policy;
1224 if ((
error = sam_cmap_register ()) !=
CS_OK) {
1251 sam_internal_data.instance_id++;
1253 sam_internal_data.term_send = 0;
1261 sam_internal_data.instance_id--;
1275 sam_internal_data.child_fd_in =
pipe_fd_in[0];
1280 sam_internal_data.am_i_child = 1;
1329 sam_cmap_destroy_pid_path ();
1360 pfds.fd = sam_internal_data.cb_rpipe_fd;
1378 if (sam_internal_data.hc_callback () != 0) {
1417 if (sam_internal_data.time_interval == 0) {
1421 if (sam_internal_data.cb_registered) {
1422 sam_internal_data.hc_callback =
cb;
1445 sam_internal_data.cb_rpipe_fd =
pipe_fd[0];
1446 sam_internal_data.cb_wpipe_fd =
pipe_fd[1];
1476 sam_internal_data.cb_registered = 1;
1477 sam_internal_data.hc_callback =
cb;
1484 sam_internal_data.cb_rpipe_fd = sam_internal_data.cb_wpipe_fd = 0;
cs_error_t
The cs_error_t enum.
uint64_t cmap_iter_handle_t
cs_error_t cmap_finalize(cmap_handle_t handle)
Close the cmap handle.
#define CMAP_KEYNAME_MAXLEN
cs_error_t cmap_iter_next(cmap_handle_t handle, cmap_iter_handle_t iter_handle, char key_name[], size_t *value_len, cmap_value_types_t *type)
Return next item in iterator iter.
cs_error_t cmap_delete(cmap_handle_t handle, const char *key_name)
Deletes key from cmap database.
cs_error_t cmap_initialize(cmap_handle_t *handle)
Create a new cmap connection.
cs_error_t cmap_iter_finalize(cmap_handle_t handle, cmap_iter_handle_t iter_handle)
Finalize iterator.
cs_error_t cmap_iter_init(cmap_handle_t handle, const char *prefix, cmap_iter_handle_t *cmap_iter_handle)
Initialize iterator with given prefix.
cs_error_t cmap_set_string(cmap_handle_t handle, const char *key_name, const char *value)
cs_error_t cmap_set_uint64(cmap_handle_t handle, const char *key_name, uint64_t value)
uint64_t quorum_handle_t
quorum_handle_t
cs_error_t quorum_initialize(quorum_handle_t *handle, quorum_callbacks_t *callbacks, uint32_t *quorum_type)
Create a new quorum connection.
cs_error_t quorum_fd_get(quorum_handle_t handle, int *fd)
Get a file descriptor on which to poll.
cs_error_t quorum_trackstart(quorum_handle_t handle, unsigned int flags)
Track node and quorum changes.
cs_error_t quorum_finalize(quorum_handle_t handle)
Close the quorum handle.
cs_error_t quorum_dispatch(quorum_handle_t handle, cs_dispatch_flags_t dispatch_types)
Dispatch messages and configuration changes.
cs_error_t sam_warn_signal_set(int warn_signal)
Set warning signal to be sent.
#define SAM_CMAP_S_FAILED
cs_error_t sam_finalize(void)
Close the SAM handle.
cs_error_t sam_hc_callback_register(sam_hc_callback_t cb)
Register healtcheck callback.
#define SAM_CMAP_S_STARTED
#define SAM_CMAP_S_Q_WAIT
cs_error_t sam_data_store(const void *data, size_t size)
Store user data.
@ SAM_COMMAND_MARK_FAILED
@ SAM_COMMAND_WARN_SIGNAL_SET
sam_hc_callback_t hc_callback
quorum_handle_t quorum_handle
#define SAM_CMAP_S_REGISTERED
cs_error_t sam_mark_failed(void)
Marks child as failed.
#define SAM_RP_MASK_C(pol)
#define SAM_RP_MASK_Q(pol)
cs_error_t sam_data_restore(void *data, size_t size)
Return stored data.
sam_recovery_policy_t recovery_policy
enum sam_internal_status_t internal_status
@ SAM_INTERNAL_STATUS_STARTED
@ SAM_INTERNAL_STATUS_NOT_INITIALIZED
@ SAM_INTERNAL_STATUS_FINALIZED
@ SAM_INTERNAL_STATUS_REGISTERED
@ SAM_INTERNAL_STATUS_INITIALIZED
cs_error_t sam_register(unsigned int *instance_id)
Register application.
cs_error_t sam_data_getsize(size_t *size)
Return size of stored data.
cs_error_t sam_stop(void)
Stop healthchecking.
cs_error_t sam_initialize(int time_interval, sam_recovery_policy_t recovery_policy)
Create a new SAM connection.
cs_error_t sam_hc_send(void)
Send healthcheck confirmation.
char cmap_pid_path[CMAP_KEYNAME_MAXLEN]
@ SAM_PARENT_ACTION_ERROR
@ SAM_PARENT_ACTION_CONTINUE
@ SAM_PARENT_ACTION_RECOVERY
cs_error_t sam_start(void)
Start healthchecking.
cmap_handle_t cmap_handle
size_t user_data_allocated
sam_recovery_policy_t
sam_recovery_policy_t enum
@ SAM_RECOVERY_POLICY_CMAP
@ SAM_RECOVERY_POLICY_QUORUM
@ SAM_RECOVERY_POLICY_QUIT
@ SAM_RECOVERY_POLICY_RESTART
int(* sam_hc_callback_t)(void)
Callback definition for event driven checking.
The quorum_callbacks_t struct.
quorum_notification_fn_t quorum_notify_fn
struct memb_ring_id ring_id