28 #include <qb/qbarray.h>    30 struct mainloop_child_s {
    52 struct mainloop_timer_s {
    62 crm_trigger_prepare(GSource * source, gint * 
timeout)
    89 crm_trigger_check(GSource * source)
   107 crm_trigger_dispatch(GSource * source, GSourceFunc callback, gpointer userdata)
   109     gboolean 
rc = G_SOURCE_CONTINUE;
   114         return G_SOURCE_CONTINUE;
   116     trig->trigger = FALSE;
   119         int callback_rc = callback(trig->user_data);
   121         if (callback_rc < 0) {
   122             crm_trace(
"Trigger handler %p not yet complete", trig);
   123             trig->running = TRUE;
   124         } 
else if (callback_rc == 0) {
   125             rc = G_SOURCE_REMOVE;
   132 crm_trigger_finalize(GSource * source)
   134     crm_trace(
"Trigger %p destroyed", source);
   137 static GSourceFuncs crm_trigger_funcs = {
   140     crm_trigger_dispatch,
   141     crm_trigger_finalize,
   145 mainloop_setup_trigger(GSource * source, 
int priority, 
int (*dispatch) (gpointer user_data),
   153     trigger->trigger = FALSE;
   154     trigger->user_data = userdata;
   157         g_source_set_callback(source, dispatch, trigger, NULL);
   160     g_source_set_priority(source, priority);
   161     g_source_set_can_recurse(source, FALSE);
   163     trigger->id = g_source_attach(source, NULL);
   170     crm_trace(
"Trigger handler %p complete", trig);
   171     trig->running = FALSE;
   188     GSource *source = NULL;
   191     source = g_source_new(&crm_trigger_funcs, 
sizeof(
crm_trigger_t));
   194     return mainloop_setup_trigger(source, priority, dispatch, userdata);
   201         source->trigger = TRUE;
   214     gs = (GSource *)source;
   216     g_source_destroy(gs); 
   231 typedef struct signal_s {
   233     void (*handler) (
int sig);  
   252 crm_signal_dispatch(GSource * source, GSourceFunc callback, gpointer userdata)
   256     if(sig->signal != SIGCHLD) {
   258                    strsignal(sig->signal), sig->signal,
   259                    (sig->handler? 
"invoking" : 
"no"));
   262     sig->trigger.trigger = FALSE;
   264         sig->handler(sig->signal);
   279 mainloop_signal_handler(
int sig)
   281     if (sig > 0 && sig < NSIG && crm_signals[sig] != NULL) {
   287 static GSourceFuncs crm_signal_funcs = {
   291     crm_trigger_finalize,
   311     struct sigaction old;
   313     if (sigemptyset(&mask) < 0) {
   314         crm_err(
"Could not set handler for signal %d: %s",
   319     memset(&sa, 0, 
sizeof(
struct sigaction));
   320     sa.sa_handler = dispatch;
   321     sa.sa_flags = SA_RESTART;
   324     if (sigaction(sig, &sa, &old) < 0) {
   325         crm_err(
"Could not set handler for signal %d: %s",
   329     return old.sa_handler;
   333 mainloop_destroy_signal_entry(
int sig)
   337     crm_signals[sig] = NULL;
   357     GSource *source = NULL;
   358     int priority = G_PRIORITY_HIGH - 1;
   360     if (sig == SIGTERM) {
   368     if (sig >= NSIG || sig < 0) {
   369         crm_err(
"Signal %d is out of range", sig);
   372     } 
else if (crm_signals[sig] != NULL && crm_signals[sig]->handler == dispatch) {
   373         crm_trace(
"Signal handler for %d is already installed", sig);
   376     } 
else if (crm_signals[sig] != NULL) {
   377         crm_err(
"Different signal handler for %d is already installed", sig);
   382     source = g_source_new(&crm_signal_funcs, 
sizeof(
crm_signal_t));
   384     crm_signals[sig] = (
crm_signal_t *) mainloop_setup_trigger(source, priority, NULL, NULL);
   387     crm_signals[sig]->handler = dispatch;
   388     crm_signals[sig]->signal = sig;
   391         mainloop_destroy_signal_entry(sig);
   400     if (siginterrupt(sig, 1) < 0) {
   401         crm_perror(LOG_INFO, 
"Could not enable system call interruptions for signal %d", sig);
   411     if (sig >= NSIG || sig < 0) {
   412         crm_err(
"Signal %d is out of range", sig);
   416         crm_perror(LOG_ERR, 
"Could not uninstall signal handler for signal %d", sig);
   419     } 
else if (crm_signals[sig] == NULL) {
   422     mainloop_destroy_signal_entry(sig);
   426 static qb_array_t *gio_map = NULL;
   432         qb_array_free(gio_map);
   435     for (
int sig = 0; sig < NSIG; ++sig) {
   436         mainloop_destroy_signal_entry(sig);
   443 struct gio_to_qb_poll {
   448     qb_ipcs_dispatch_fn_t fn;
   449     enum qb_loop_priority p;
   453 gio_read_socket(GIOChannel * gio, GIOCondition condition, gpointer 
data)
   455     struct gio_to_qb_poll *adaptor = (
struct gio_to_qb_poll *)
data;
   456     gint fd = g_io_channel_unix_get_fd(gio);
   464     return (adaptor->fn(fd, condition, adaptor->data) == 0);
   468 gio_poll_destroy(gpointer 
data)
   470     struct gio_to_qb_poll *adaptor = (
struct gio_to_qb_poll *)
data;
   475     if (adaptor->is_used == 0) {
   476         crm_trace(
"Marking adaptor %p unused", adaptor);
   490 conv_prio_libqb2glib(
enum qb_loop_priority prio)
   492     gint ret = G_PRIORITY_DEFAULT;
   495             ret = G_PRIORITY_LOW;
   498             ret = G_PRIORITY_HIGH;
   501             crm_trace(
"Invalid libqb's loop priority %d, assuming QB_LOOP_MED",
   518 static enum qb_ipcs_rate_limit
   519 conv_libqb_prio2ratelimit(
enum qb_loop_priority prio)
   522     enum qb_ipcs_rate_limit ret = QB_IPCS_RATE_NORMAL;
   525             ret = QB_IPCS_RATE_SLOW;
   528             ret = QB_IPCS_RATE_FAST;
   531             crm_trace(
"Invalid libqb's loop priority %d, assuming QB_LOOP_MED",
   541 gio_poll_dispatch_update(
enum qb_loop_priority p, int32_t fd, int32_t evts,
   542                          void *
data, qb_ipcs_dispatch_fn_t fn, int32_t add)
   544     struct gio_to_qb_poll *adaptor;
   548     res = qb_array_index(gio_map, fd, (
void **)&adaptor);
   550         crm_err(
"Array lookup failed for fd=%d: %d", fd, res);
   554     crm_trace(
"Adding fd=%d to mainloop as adaptor %p", fd, adaptor);
   556     if (add && adaptor->source) {
   557         crm_err(
"Adaptor for descriptor %d is still in-use", fd);
   560     if (!add && !adaptor->is_used) {
   561         crm_err(
"Adaptor for descriptor %d is not in-use", fd);
   566     channel = g_io_channel_unix_new(fd);
   568         crm_err(
"No memory left to add fd=%d", fd);
   572     if (adaptor->source) {
   573         g_source_remove(adaptor->source);
   578     evts |= (G_IO_HUP | G_IO_NVAL | G_IO_ERR);
   581     adaptor->events = evts;
   582     adaptor->data = 
data;
   586         g_io_add_watch_full(channel, conv_prio_libqb2glib(p), evts,
   587                             gio_read_socket, adaptor, gio_poll_destroy);
   598     g_io_channel_unref(channel);
   600     crm_trace(
"Added to mainloop with gsource id=%d", adaptor->source);
   601     if (adaptor->source > 0) {
   609 gio_poll_dispatch_add(
enum qb_loop_priority p, int32_t fd, int32_t evts,
   610                       void *
data, qb_ipcs_dispatch_fn_t fn)
   612     return gio_poll_dispatch_update(p, fd, evts, 
data, fn, QB_TRUE);
   616 gio_poll_dispatch_mod(
enum qb_loop_priority p, int32_t fd, int32_t evts,
   617                       void *
data, qb_ipcs_dispatch_fn_t fn)
   619     return gio_poll_dispatch_update(p, fd, evts, 
data, fn, QB_FALSE);
   623 gio_poll_dispatch_del(int32_t fd)
   625     struct gio_to_qb_poll *adaptor;
   628     if (qb_array_index(gio_map, fd, (
void **)&adaptor) == 0) {
   629         if (adaptor->source) {
   630             g_source_remove(adaptor->source);
   639     .dispatch_add = gio_poll_dispatch_add,
   640     .dispatch_mod = gio_poll_dispatch_mod,
   641     .dispatch_del = gio_poll_dispatch_del,
   644 static enum qb_ipc_type
   645 pick_ipc_type(
enum qb_ipc_type requested)
   647     const char *env = getenv(
"PCMK_ipc_type");
   649     if (env && strcmp(
"shared-mem", env) == 0) {
   651     } 
else if (env && strcmp(
"socket", env) == 0) {
   652         return QB_IPC_SOCKET;
   653     } 
else if (env && strcmp(
"posix", env) == 0) {
   654         return QB_IPC_POSIX_MQ;
   655     } 
else if (env && strcmp(
"sysv", env) == 0) {
   656         return QB_IPC_SYSV_MQ;
   657     } 
else if (requested == QB_IPC_NATIVE) {
   671                         struct qb_ipcs_service_handlers *callbacks)
   678                                   struct qb_ipcs_service_handlers *callbacks,
   679                                   enum qb_loop_priority prio)
   682     qb_ipcs_service_t *server = NULL;
   684     if (gio_map == NULL) {
   685         gio_map = qb_array_create_2(64, 
sizeof(
struct gio_to_qb_poll), 1);
   688     server = qb_ipcs_create(
name, 0, pick_ipc_type(
type), callbacks);
   690     if (server == NULL) {
   695     if (prio != QB_LOOP_MED) {
   696         qb_ipcs_request_rate_limit(server, conv_libqb_prio2ratelimit(prio));
   703     rc = qb_ipcs_run(server);
   716         qb_ipcs_destroy(server);
   720 struct mainloop_io_s {
   729     int (*dispatch_fn_ipc) (
const char *buffer, ssize_t length, gpointer userdata);
   730     int (*dispatch_fn_io) (gpointer userdata);
   731     void (*destroy_fn) (gpointer userdata);
   746 mainloop_gio_callback(GIOChannel * gio, GIOCondition condition, gpointer 
data)
   748     gboolean 
rc = G_SOURCE_CONTINUE;
   751     CRM_ASSERT(client->fd == g_io_channel_unix_get_fd(gio));
   753     if (condition & G_IO_IN) {
   761                     crm_trace(
"Could not read IPC message from %s: %s (%ld)",
   764                 } 
else if (client->dispatch_fn_ipc) {
   767                     crm_trace(
"New %ld-byte IPC message from %s "   768                               "after I/O condition %d",
   769                               read_rc, client->name, (
int) condition);
   770                     if (client->dispatch_fn_ipc(buffer, read_rc, client->userdata) < 0) {
   771                         crm_trace(
"Connection to %s no longer required", client->name);
   772                         rc = G_SOURCE_REMOVE;
   776             } 
while ((
rc == G_SOURCE_CONTINUE) && (read_rc > 0) && --max > 0);
   779             crm_trace(
"New I/O event for %s after I/O condition %d",
   780                       client->name, (
int) condition);
   781             if (client->dispatch_fn_io) {
   782                 if (client->dispatch_fn_io(client->userdata) < 0) {
   783                     crm_trace(
"Connection to %s no longer required", client->name);
   784                     rc = G_SOURCE_REMOVE;
   791         crm_err(
"Connection to %s closed " CRM_XS "client=%p condition=%d",
   792                 client->name, client, condition);
   793         rc = G_SOURCE_REMOVE;
   795     } 
else if (condition & (G_IO_HUP | G_IO_NVAL | G_IO_ERR)) {
   796         crm_trace(
"The connection %s[%p] has been closed (I/O condition=%d)",
   797                   client->name, client, condition);
   798         rc = G_SOURCE_REMOVE;
   800     } 
else if ((condition & G_IO_IN) == 0) {
   828         crm_err(
"Strange condition: %d", condition);
   838 mainloop_gio_destroy(gpointer c)
   841     char *c_name = strdup(client->name);
   846     crm_trace(
"Destroying client %s[%p]", c_name, c);
   852     if (client->destroy_fn) {
   853         void (*destroy_fn) (gpointer userdata) = client->destroy_fn;
   855         client->destroy_fn = NULL;
   856         destroy_fn(client->userdata);
   866     crm_trace(
"Destroyed client %s[%p]", c_name, c);
   868     free(client->name); client->name = NULL;
   897     CRM_CHECK((ipc != NULL) && (callbacks != NULL), 
return EINVAL);
   906     if (*source == NULL) {
   912     (*source)->ipc = ipc;
   913     (*source)->destroy_fn = callbacks->
destroy;
   914     (*source)->dispatch_fn_ipc = callbacks->
dispatch;
   929         return timer->period_ms;
   945             fprintf(stderr, 
"Connection to %s failed: %s",
   982         if (client == NULL) {
   985         client->name = strdup(
name);
   986         client->userdata = userdata;
   989             client->destroy_fn = callbacks->
destroy;
   990             client->dispatch_fn_io = callbacks->
dispatch;
   994         client->channel = g_io_channel_unix_new(fd);
   996             g_io_add_watch_full(client->channel, priority,
   997                                 (G_IO_IN | G_IO_HUP | G_IO_NVAL | G_IO_ERR), mainloop_gio_callback,
   998                                 client, mainloop_gio_destroy);
  1009         g_io_channel_unref(client->channel);
  1010         crm_trace(
"Added connection %d for %s[%p].%d", client->source, client->name, client, fd);
  1021     if (client != NULL) {
  1022         crm_trace(
"Removing client %s[%p]", client->name, client);
  1023         if (client->source) {
  1027             g_source_remove(client->source);
  1032 static GList *child_list = NULL;
  1049     return child->timeout;
  1055     return child->privatedata;
  1061     child->privatedata = NULL;
  1068     if (child->timerid != 0) {
  1069         crm_trace(
"Removing timer %d", child->timerid);
  1070         g_source_remove(child->timerid);
  1083         crm_debug(
"Kill pid %d only. leave group intact.", child->pid);
  1084         rc = kill(child->pid, SIGKILL);
  1086         crm_debug(
"Kill pid %d's group", child->pid);
  1087         rc = kill(-child->pid, SIGKILL);
  1091         if (errno != ESRCH) {
  1092             crm_perror(LOG_ERR, 
"kill(%d, KILL) failed", child->pid);
  1100 child_timeout_callback(gpointer p)
  1106     if (child->timeout) {
  1107         crm_warn(
"%s process (PID %d) will not die!", child->desc, (
int)child->pid);
  1111     rc = child_kill_helper(child);
  1117     child->timeout = TRUE;
  1118     crm_debug(
"%s process (PID %d) timed out", child->desc, (
int)child->pid);
  1120     child->timerid = g_timeout_add(5000, child_timeout_callback, child);
  1132     bool callback_needed = 
true;
  1134     rc = waitpid(child->pid, &status, 
flags);
  1136         crm_trace(
"Child process %d (%s) still active",
  1137                   child->pid, child->desc);
  1138         callback_needed = 
false;
  1140     } 
else if (
rc != child->pid) {
  1152         crm_notice(
"Wait for child process %d (%s) interrupted: %s",
  1155     } 
else if (WIFEXITED(status)) {
  1156         exitcode = WEXITSTATUS(status);
  1157         crm_trace(
"Child process %d (%s) exited with status %d",
  1158                   child->pid, child->desc, exitcode);
  1160     } 
else if (WIFSIGNALED(status)) {
  1161         signo = WTERMSIG(status);
  1162         crm_trace(
"Child process %d (%s) exited with signal %d (%s)",
  1163                   child->pid, child->desc, signo, strsignal(signo));
  1165 #ifdef WCOREDUMP // AIX, SunOS, maybe others  1166     } 
else if (WCOREDUMP(status)) {
  1168         crm_err(
"Child process %d (%s) dumped core",
  1169                 child->pid, child->desc);
  1173         crm_trace(
"Child process %d (%s) stopped or continued",
  1174                   child->pid, child->desc);
  1175         callback_needed = 
false;
  1178     if (callback_needed && child->callback) {
  1179         child->callback(child, child->pid, core, signo, exitcode);
  1181     return callback_needed;
  1185 child_death_dispatch(
int signal)
  1187     for (GList *iter = child_list; iter; ) {
  1188         GList *saved = iter;
  1192         if (child_waitpid(child, WNOHANG)) {
  1193             crm_trace(
"Removing completed process %d from child list",
  1195             child_list = g_list_remove_link(child_list, saved);
  1203 child_signal_init(gpointer p)
  1210     child_death_dispatch(SIGCHLD);
  1222     int waitflags = 0, 
rc = 0;
  1224     for (iter = child_list; iter != NULL && match == NULL; iter = iter->next) {
  1226         if (
pid == child->pid) {
  1231     if (match == NULL) {
  1235     rc = child_kill_helper(match);
  1242         crm_trace(
"Waiting for signal that child process %d completed",
  1246     } 
else if(
rc != 0) {
  1250         waitflags = WNOHANG;
  1253     if (!child_waitpid(match, waitflags)) {
  1258     child_list = g_list_remove(child_list, match);
  1274     static bool need_init = TRUE;
  1279     child->timeout = FALSE;
  1280     child->privatedata = privatedata;
  1281     child->callback = callback;
  1282     child->flags = 
flags;
  1285         child->desc = strdup(desc);
  1289         child->timerid = g_timeout_add(
timeout, child_timeout_callback, child);
  1292     child_list = g_list_append(child_list, child);
  1300         g_timeout_add(1, child_signal_init, NULL);
  1312 mainloop_timer_cb(gpointer user_data)
  1315     bool repeat = FALSE;
  1316     struct mainloop_timer_s *t = user_data;
  1326         crm_trace(
"Invoking callbacks for timer %s", t->name);
  1328         if(t->cb(t->userdata) == FALSE) {
  1329             crm_trace(
"Timer %s complete", t->name);
  1345     if(t && t->id != 0) {
  1355     if(t && t->period_ms > 0) {
  1356         crm_trace(
"Starting timer %s", t->name);
  1357         t->id = g_timeout_add(t->period_ms, mainloop_timer_cb, t);
  1364     if(t && t->id != 0) {
  1365         crm_trace(
"Stopping timer %s", t->name);
  1366         g_source_remove(t->id);
  1377         last = t->period_ms;
  1378         t->period_ms = period_ms;
  1381     if(t && t->id != 0 && last != t->period_ms) {
  1399         t->period_ms = period_ms;
  1402         t->userdata = userdata;
  1403         crm_trace(
"Created timer %s with %p %p", t->name, userdata, t->userdata);
  1412         crm_trace(
"Destroying timer %s", t->name);
  1424 drain_timeout_cb(gpointer user_data)
  1426     bool *timeout_popped = (
bool*) user_data;
  1428     *timeout_popped = TRUE;
  1441     if ((mloop != NULL) && g_main_loop_is_running(mloop)) {
  1442         GMainContext *ctx = g_main_loop_get_context(mloop);
  1447         for (
int i = 0; (i < n) && g_main_context_pending(ctx); ++i) {
  1448             g_main_context_dispatch(ctx);
  1450         g_main_loop_quit(mloop);
  1469     bool timeout_popped = FALSE;
  1471     GMainContext *ctx = NULL;
  1475     ctx = g_main_loop_get_context(mloop);
  1477         time_t start_time = time(NULL);
  1479         timer = g_timeout_add(timer_ms, drain_timeout_cb, &timeout_popped);
  1480         while (!timeout_popped
  1481                && check(timer_ms - (time(NULL) - start_time) * 1000)) {
  1482             g_main_context_iteration(ctx, TRUE);
  1485     if (!timeout_popped && (timer > 0)) {
  1486         g_source_remove(timer);
 void * mainloop_child_userdata(mainloop_child_t *child)
 
#define CRM_CHECK(expr, failure_action)
 
pid_t mainloop_child_pid(mainloop_child_t *child)
 
bool mainloop_timer_running(mainloop_timer_t *t)
 
bool crm_ipc_connect(crm_ipc_t *client)
Establish an IPC connection to a Pacemaker component. 
 
#define crm_notice(fmt, args...)
 
const char * pcmk_strerror(int rc)
 
struct signal_s crm_signal_t
 
void mainloop_del_fd(mainloop_io_t *client)
 
void mainloop_del_ipc_server(qb_ipcs_service_t *server)
 
gboolean mainloop_destroy_signal(int sig)
 
crm_trigger_t * mainloop_add_trigger(int priority, int(*dispatch)(gpointer user_data), gpointer userdata)
Create a trigger to be used as a mainloop source. 
 
void(* destroy)(gpointer userdata)
Destroy function for mainloop file descriptor client data. 
 
int crm_ipc_get_fd(crm_ipc_t *client)
 
Deprecated Pacemaker mainloop API. 
 
void mainloop_trigger_complete(crm_trigger_t *trig)
 
const char * mainloop_child_name(mainloop_child_t *child)
 
void pcmk_quit_main_loop(GMainLoop *mloop, unsigned int n)
Drain some remaining main loop events then quit it. 
 
struct mainloop_timer_s mainloop_timer_t
 
struct mainloop_io_s mainloop_io_t
 
struct mainloop_child_s mainloop_child_t
 
gboolean crm_signal(int sig, void(*dispatch)(int sig))
 
long crm_ipc_read(crm_ipc_t *client)
 
mainloop_timer_t * mainloop_timer_add(const char *name, guint period_ms, bool repeat, GSourceFunc cb, void *userdata)
 
enum crm_ais_msg_types type
 
const char * pcmk_rc_str(int rc)
Get a user-friendly description of a return code. 
 
mainloop_io_t * mainloop_add_ipc_client(const char *name, int priority, size_t max_size, void *userdata, struct ipc_client_callbacks *callbacks)
 
struct qb_ipcs_poll_handlers gio_poll_funcs
 
guint mainloop_timer_set_period(mainloop_timer_t *t, guint period_ms)
 
Wrappers for and extensions to glib mainloop. 
 
void mainloop_timer_del(mainloop_timer_t *t)
 
crm_ipc_t * mainloop_get_ipc_client(mainloop_io_t *client)
 
const char * crm_ipc_buffer(crm_ipc_t *client)
 
void mainloop_del_ipc_client(mainloop_io_t *client)
 
struct trigger_s crm_trigger_t
 
int(* dispatch)(gpointer userdata)
Dispatch function for mainloop file descriptor with data ready. 
 
#define crm_warn(fmt, args...)
 
int mainloop_child_timeout(mainloop_child_t *child)
 
#define crm_debug(fmt, args...)
 
struct crm_ipc_s crm_ipc_t
 
void mainloop_set_trigger(crm_trigger_t *source)
 
guint pcmk__mainloop_timer_get_period(mainloop_timer_t *timer)
Get period for mainloop timer. 
 
void(* destroy)(gpointer userdata)
Destroy function for mainloop IPC connection client data. 
 
#define crm_trace(fmt, args...)
 
mainloop_io_t * mainloop_add_fd(const char *name, int priority, int fd, void *userdata, struct mainloop_fd_callbacks *callbacks)
 
void mainloop_timer_start(mainloop_timer_t *t)
 
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
 
int pcmk__add_mainloop_ipc(crm_ipc_t *ipc, int priority, void *userdata, struct ipc_client_callbacks *callbacks, mainloop_io_t **source)
Connect to IPC and add it as a main loop source. 
 
qb_ipcs_service_t * mainloop_add_ipc_server(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks)
 
Wrappers for and extensions to libxml2. 
 
void mainloop_clear_child_userdata(mainloop_child_t *child)
 
gboolean mainloop_child_kill(pid_t pid)
 
void mainloop_timer_stop(mainloop_timer_t *t)
 
void mainloop_child_add_with_flags(pid_t pid, int timeout, const char *desc, void *privatedata, enum mainloop_child_flags flags, void(*callback)(mainloop_child_t *p, pid_t pid, int core, int signo, int exitcode))
 
unsigned int crm_ipc_default_buffer_size(void)
Return pacemaker's default IPC buffer size. 
 
void crm_ipc_destroy(crm_ipc_t *client)
 
void mainloop_child_add(pid_t pid, int timeout, const char *desc, void *privatedata, void(*callback)(mainloop_child_t *p, pid_t pid, int core, int signo, int exitcode))
 
bool crm_ipc_connected(crm_ipc_t *client)
 
unsigned int crm_log_level
 
void(* sighandler_t)(int)
 
const char * crm_ipc_name(crm_ipc_t *client)
 
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr. 
 
qb_ipcs_service_t * mainloop_add_ipc_server_with_prio(const char *name, enum qb_ipc_type type, struct qb_ipcs_service_handlers *callbacks, enum qb_loop_priority prio)
Start server-side API end-point, hooked into the internal event loop. 
 
#define crm_err(fmt, args...)
 
crm_ipc_t * crm_ipc_new(const char *name, size_t max_size)
Create a new (legacy) object for using Pacemaker daemon IPC. 
 
void mainloop_cleanup(void)
 
gboolean mainloop_add_signal(int sig, void(*dispatch)(int sig))
 
gboolean mainloop_destroy_trigger(crm_trigger_t *source)
 
void pcmk_drain_main_loop(GMainLoop *mloop, guint timer_ms, bool(*check)(guint))
Process main loop events while a certain condition is met. 
 
sighandler_t crm_signal_handler(int sig, sighandler_t dispatch)
 
void crm_ipc_close(crm_ipc_t *client)
 
int(* dispatch)(const char *buffer, ssize_t length, gpointer userdata)
Dispatch function for an IPC connection used as mainloop source.