diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:40:13 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 06:40:13 +0000 |
commit | e9be59e1502a41bab9891d96d753102a7dafef0b (patch) | |
tree | c3b2da87c414881f4b53d0964f407c83492d813e /include/clplumbing | |
parent | Initial commit. (diff) | |
download | cluster-glue-upstream.tar.xz cluster-glue-upstream.zip |
Adding upstream version 1.0.12.upstream/1.0.12upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'include/clplumbing')
34 files changed, 2982 insertions, 0 deletions
diff --git a/include/clplumbing/GSource.h b/include/clplumbing/GSource.h new file mode 100644 index 0000000..2acc9eb --- /dev/null +++ b/include/clplumbing/GSource.h @@ -0,0 +1,236 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_GSOURCE_H +# define _CLPLUMBING_GSOURCE_H +# include <clplumbing/ipc.h> + +typedef struct GFDSource_s GFDSource; +typedef struct GCHSource_s GCHSource; +typedef struct GWCSource_s GWCSource; +typedef struct GSIGSource_s GSIGSource; +typedef struct GTRIGSource_s GTRIGSource; + + +void G_main_setmaxdispatchdelay(GSource* s, unsigned long delayms); +void G_main_setmaxdispatchtime(GSource* s, unsigned long dispatchms); +void G_main_setdescription(GSource* s, const char * description); + +void G_main_setmaxdispatchdelay_id(guint id, unsigned long delayms); +void G_main_setmaxdispatchtime_id(guint id, unsigned long dispatchms); +void G_main_setdescription_id(guint id, const char * description); +void G_main_setall_id(guint id, const char * description, unsigned long delayms, unsigned long dispatchms); + + +/*********************************************************************** + * Functions for interfacing input to the mainloop + ***********************************************************************/ + +GSource* +G_main_add_input(int priority, + gboolean can_recurse, + GSourceFuncs* funcs); + +/*********************************************************************** + * Functions for interfacing "raw" file descriptors to the mainloop + ***********************************************************************/ +/* +* Add a file descriptor to the gmainloop world... + */ +GFDSource* G_main_add_fd(int priority, int fd, gboolean can_recurse +, gboolean (*dispatch)(int fd, gpointer user_data) +, gpointer userdata +, GDestroyNotify notify); + +/* + * Delete a file descriptor from the gmainloop world... + * Note: destroys the GFDSource object. + */ +gboolean G_main_del_fd(GFDSource* fdp); + +/* + * Notify us that a file descriptor is blocked on output. + * (i.e., we should poll for output events) + */ +void g_main_output_is_blocked(GFDSource* fdp); + + +/************************************************************** + * Functions for interfacing IPC_Channels to the mainloop + **************************************************************/ +/* + * Add an IPC_channel to the gmainloop world... + */ +GCHSource* G_main_add_IPC_Channel(int priority, IPC_Channel* ch +, gboolean can_recurse +, gboolean (*dispatch)(IPC_Channel* source_data +, gpointer user_data) +, gpointer userdata +, GDestroyNotify notify); + +/* + * the events in this source is paused/resumed + */ + +void G_main_IPC_Channel_pause(GCHSource* chp); +void G_main_IPC_Channel_resume(GCHSource* chp); + + +/* + * Delete an IPC_channel from the gmainloop world... + * Note: destroys the GCHSource object, and the IPC_Channel + * object automatically. + */ +gboolean G_main_del_IPC_Channel(GCHSource* chp); + + +/* + * Set the destroy notify function + * + */ +void set_IPC_Channel_dnotify(GCHSource* chp, + GDestroyNotify notify); + + +/********************************************************************* + * Functions for interfacing IPC_WaitConnections to the mainloop + ********************************************************************/ +/* + * Add an IPC_WaitConnection to the gmainloop world... + * Note that the dispatch function is called *after* the + * connection is accepted. + */ +GWCSource* G_main_add_IPC_WaitConnection(int priority, IPC_WaitConnection* ch +, IPC_Auth* auth_info +, gboolean can_recurse +, gboolean (*dispatch)(IPC_Channel* source_data +, gpointer user_data) +, gpointer userdata +, GDestroyNotify notify); + +/* + * Delete an IPC_WaitConnection from the gmainloop world... + * Note: destroys the GWCSource object, and the IPC_WaitConnection + * object automatically. + */ +gboolean G_main_del_IPC_WaitConnection(GWCSource* wcp); + + +/************************************************************** + * Functions for interfacing Signals to the mainloop + **************************************************************/ +/* + * Add an Signal to the gmainloop world... + */ +GSIGSource* G_main_add_SignalHandler( + int priority, int signal, + gboolean (*dispatch)(int nsig, gpointer user_data), + gpointer userdata, GDestroyNotify notify); + +/* + * Delete an signal from the gmainloop world... + * Note: destroys the GSIGSource object, and the removes the + * Signal Handler automatically. + */ +gboolean G_main_del_SignalHandler(GSIGSource* chp); + + +/* + * Set the destroy notify function + * + */ +void set_SignalHandler_dnotify(GSIGSource* chp, GDestroyNotify notify); + + +/* manage child process death using sig source*/ +#define DEFAULT_MAXDISPATCHTIME 30 /* in ms */ +void set_sigchld_proctrack(int priority, unsigned long maxdisptime); + + + +/************************************************************** + * Functions for interfacing Manual triggers to the mainloop + **************************************************************/ +/* + * Add an Trigger to the gmainloop world... + */ +GTRIGSource* G_main_add_TriggerHandler( + int priority, gboolean (*dispatch)(gpointer user_data), + gpointer userdata, GDestroyNotify notify); + +/* + * Delete an signal from the gmainloop world... + * Note: destroys the GTRIGSource object, and the removes the + * Trigger Handler automatically. + */ +gboolean G_main_del_TriggerHandler(GTRIGSource* chp); + + +/* + * Set the destroy notify function + * + */ +void set_TriggerHandler_dnotify(GTRIGSource* chp, GDestroyNotify notify); + + +void G_main_set_trigger(GTRIGSource* man_src); + +/* + * Create a trigger for triggering an action in a short-lived (temporary) + * child process. + * + * The name isn't wonderful, but we couldn't think of a better one. + */ +GTRIGSource* G_main_add_tempproc_trigger(int priority +, int (*fun)(gpointer p) /* What to do? */ + /* Called in child process */ +, const char * procname /* What do we call this process? */ +, gpointer userdata /* Passed to 'triggerfun' */ +, void (*prefork)(gpointer p) /* Called before fork */ +, void (*postfork)(gpointer p) /* Called by parent process + * after fork(2) call. + * Each has 'userdata' + * passed to it. + */ +, void (*complete)(gpointer p, int status, int signo, int exitcode)); /* called after the child process completes */ + +/* + * Special notes: + * - No more than one child process will be active at a time per trigger + * object. + * + * - If you trigger the action while this object has a child active, + * then it will be re-triggered after the currently running child + * completes. There is no necessary correlation between the + * number of times a the action is triggered and how many + * times it is executed. What is guaranteed is that after you + * trigger the action, it will happen (at least) once - as soon + * as the scheduler gets around to it at the priority you've + * assigned it. But if several are triggered while a child + * process is running, only one process will be instantiated to + * take the action requested by all the trigger calls. + * + * - Child processes are forked off at the priority of the trigger, + * not the priority of the SIGCHLD handler. + * + * - This is useful for writing out updates to a file for example. + * While we're writing one copy out, subsequent updates are + * held off until this one completes. When it completes, then + * the file is written again - but not "n" times - just the + * latest version available at the time the trigger is + * activated (run). + */ +#endif diff --git a/include/clplumbing/GSource_internal.h b/include/clplumbing/GSource_internal.h new file mode 100644 index 0000000..c20a9c9 --- /dev/null +++ b/include/clplumbing/GSource_internal.h @@ -0,0 +1,111 @@ +/* + * Author: Alan Robertson <alanr@unix.sh> + * Copyright (C) 2005 International Business Machines Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <clplumbing/longclock.h> +#include <clplumbing/GSource.h> + +#define MAG_GFDSOURCE 0xfeed0001U +#define MAG_GCHSOURCE 0xfeed0002U +#define MAG_GWCSOURCE 0xfeed0003U +#define MAG_GSIGSOURCE 0xfeed0004U +#define MAG_GTRIGSOURCE 0xfeed0005U +#define MAG_GTIMEOUTSRC 0xfeed0006U + +#define IS_FDSOURCE(p) (p && (p)->magno == MAG_GFDSOURCE) +#define IS_CHSOURCE(p) (p && (p)->magno == MAG_GCHSOURCE) +#define IS_WCSOURCE(p) (p && (p)->magno == MAG_GWCSOURCE) +#define IS_SIGSOURCE(p) (p && (p)->magno == MAG_GSIGSOURCE) +#define IS_TRIGSOURCE(p) (p && (p)->magno == MAG_GTRIGSOURCE) +#define IS_TIMEOUTSRC(p) (p && (p)->magno == MAG_GTIMEOUTSRC) + +#define IS_ONEOFOURS(p) (IS_CHSOURCE(p)|IS_FDSOURCE(p)|IS_WCSOURCE(p)|| \ + IS_SIGSOURCE(p)|IS_TRIGSOURCE(p)||IS_TIMEOUTSRC(p)) + + +#define DEFAULT_MAXDISPATCH 0 +#define DEFAULT_MAXDELAY 0 +#define OTHER_MAXDELAY 100 + +#define COMMON_STRUCTSTART \ +GSource source; /* Common glib struct - must be 1st */ \ +unsigned magno; /* Magic number */ \ +long maxdispatchms; /* Time limit for dispatch function */ \ +long maxdispatchdelayms; /* Max delay before processing */ \ +char detecttime[sizeof(longclock_t)]; \ + /* Time last input detected */ \ +void* udata; /* User-defined data */ \ +guint gsourceid; /* Source id of this source */ \ +const char * description; /* Description of this source */ \ +GDestroyNotify dnotify + +struct GFDSource_s { + COMMON_STRUCTSTART; + gboolean (*dispatch)(int fd, gpointer user_data); + GPollFD gpfd; +}; + + +typedef gboolean (*GCHdispatch)(IPC_Channel* ch, gpointer user_data); + +struct GCHSource_s { + COMMON_STRUCTSTART; + IPC_Channel* ch; + gboolean fd_fdx; + GPollFD infd; + GPollFD outfd; + gboolean dontread; /* TRUE when we don't want to read + * more input for a while - we're + * flow controlling the writer off + */ + gboolean (*dispatch)(IPC_Channel* ch, gpointer user_data); +}; + +struct GWCSource_s { + COMMON_STRUCTSTART; + GPollFD gpfd; + IPC_WaitConnection* wch; + IPC_Auth* auth_info; + gboolean (*dispatch)(IPC_Channel* accept_ch, gpointer udata); +}; + +struct GSIGSource_s { + COMMON_STRUCTSTART; + clock_t sh_detecttime; + int signal; + gboolean signal_triggered; + gboolean (*dispatch)(int signal, gpointer user_data); +}; + +struct GTRIGSource_s { + COMMON_STRUCTSTART; + gboolean manual_trigger; + gboolean (*dispatch)(gpointer user_data); +}; + +/************************************************************ + * Functions for IPC_Channels + ***********************************************************/ +gboolean G_CH_prepare_int(GSource* source, gint* timeout); +gboolean G_CH_check_int(GSource* source); +gboolean G_CH_dispatch_int(GSource* source, GSourceFunc callback, + gpointer user_data); +void G_CH_destroy_int(GSource* source); +GCHSource* +G_main_IPC_Channel_constructor(GSource* source, IPC_Channel* ch +, gpointer userdata, GDestroyNotify notify); diff --git a/include/clplumbing/Gmain_timeout.h b/include/clplumbing/Gmain_timeout.h new file mode 100644 index 0000000..c696a9d --- /dev/null +++ b/include/clplumbing/Gmain_timeout.h @@ -0,0 +1,44 @@ +#ifndef _CLPLUMBING_GMAIN_TIMEOUT_H +#define _CLPLUMBING_GMAIN_TIMEOUT_H +#include <glib.h> +/* + * Copyright (C) 2002 Alan Robertson <alanr@unix.sh> + * This software licensed under the GNU LGPL. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +/* + * These functions must work correctly even if someone resets the + * time-of-day clock. The g_main_timeout_add() function does not have + * this property, since it relies on gettimeofday(). + * + * Our functions have the same semantics - except they always work ;-) + * + * This is because we use longclock_t for our time values. + */ +guint Gmain_timeout_add(guint interval +, GSourceFunc function +, gpointer data); + +guint Gmain_timeout_add_full(gint priority +, guint interval +, GSourceFunc function +, gpointer data +, GDestroyNotify notify); + +void Gmain_timeout_remove(guint tag); +#endif diff --git a/include/clplumbing/Makefile.am b/include/clplumbing/Makefile.am new file mode 100644 index 0000000..599b24c --- /dev/null +++ b/include/clplumbing/Makefile.am @@ -0,0 +1,59 @@ +# +# linux-ha: Linux-HA heartbeat code +# +# Copyright (C) 2002 International Business Machines. +# Author: Alan Robertson <alanr@unix.sh> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +# +MAINTAINERCLEANFILES = Makefile.in + +idir=$(includedir)/clplumbing + +i_HEADERS = \ + Gmain_timeout.h \ + GSource.h \ + GSource_internal.h \ + apphb_cs.h \ + base64.h \ + cl_log.h \ + cl_poll.h \ + cl_signal.h \ + cl_pidfile.h \ + cl_random.h \ + cl_reboot.h \ + cl_syslog.h \ + cl_uuid.h \ + coredumps.h \ + cpulimits.h \ + ipc.h \ + lsb_exitcodes.h \ + loggingdaemon.h \ + longclock.h \ + mkstemp_mode.h \ + netstring.h \ + proctrack.h \ + realtime.h \ + replytrack.h \ + setproctitle.h \ + timers.h \ + uids.h \ + cl_misc.h \ + md5.h \ + cl_plugin.h \ + cl_tiebreaker.h \ + cl_quorum.h \ + cl_quorumd.h diff --git a/include/clplumbing/apphb_cs.h b/include/clplumbing/apphb_cs.h new file mode 100644 index 0000000..9506db6 --- /dev/null +++ b/include/clplumbing/apphb_cs.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2002 Alan Robertson <alanr@unix.sh> + * This software licensed under the GNU LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _CLPLUMBING_APPHB_CS_H +#define _CLPLUMBING_APPHB_CS_H + +/* Internal client-server messages for APP heartbeat service */ + +#ifndef HA_VARRUNDIR +#define HA_VARRUNDIR "/var/run" +#endif +#define APPHBSOCKPATH HA_VARRUNDIR "/heartbeat/apphb.comm" + +#define APPHB_TLEN 8 +#define APPHB_OLEN 256 + +#define REGISTER "reg" +#define UNREGISTER "unreg" +#define HEARTBEAT "hb" +#define SETINTERVAL "setint" +#define SETWARNTIME "setwarn" +#define SETREBOOT "setboot" + +/* + * These messages are really primitive. + * They don't have any form of version control, they're in host byte order, + * and they're all in binary... + * + * Fortunately, this is a very simple local service ;-) + */ + +/* Generic (no parameter) App heartbeat message */ +struct apphb_msg { + char msgtype [APPHB_TLEN]; +}; + +/* App heartbeat Registration message */ +struct apphb_signupmsg { + char msgtype [APPHB_TLEN]; + char appname [APPHB_OLEN]; + char appinstance [APPHB_OLEN]; + char curdir [APPHB_OLEN]; + pid_t pid; + uid_t uid; + gid_t gid; +}; + +/* App heartbeat setinterval / setwarn message */ +struct apphb_msmsg { + char msgtype [APPHB_TLEN]; + unsigned long ms; +}; + +/* App heartbeat server return code (errno) */ +struct apphb_rc { + int rc; +}; +#endif diff --git a/include/clplumbing/base64.h b/include/clplumbing/base64.h new file mode 100644 index 0000000..4ea6810 --- /dev/null +++ b/include/clplumbing/base64.h @@ -0,0 +1,50 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_BASE64_H +# define _CLPLUMBING_BASE64_H +/* + * + * Base64 conversion functions. + * They convert from a binary array into a single string + * in base 64. This is almost (but not quite) like section 5.2 of RFC 1341 + * The only difference is that we don't care about line lengths. + * We do use their encoding algorithm. + * + */ + +#define B64inunit 3 +#define B64outunit 4 + +/* How long will the base64 string be for a particular binary object size? */ +/* This is like strlen() and doesn't include the '\0' byte at the end */ +#define B64_stringlen(bytes) \ + ((((bytes)+(B64inunit-1))/B64inunit)*B64outunit) + +/* How many bytes to you need to malloc to store a base64 string? */ +/* (includes space for the '\0' terminator byte) */ +#define B64_stringspace(bytes) (B64_stringlen(bytes)+1) + +/* How many bytes will a base64 string take up back in binary? */ +/* Note: This may be as much as two 2 bytes more than strictly needed */ +#define B64_maxbytelen(slen) (((slen) / B64outunit)*B64inunit) + +/* Returns strlen() of base64 string returned in "output" */ +int binary_to_base64(const void * data, int nbytes, char * output, int outlen); + +/* Returns the size of the binary object we returned in "output" */ +int base64_to_binary(const char * input, int inlen, void * output, int outlen); +#endif diff --git a/include/clplumbing/cl_log.h b/include/clplumbing/cl_log.h new file mode 100644 index 0000000..aa30fcd --- /dev/null +++ b/include/clplumbing/cl_log.h @@ -0,0 +1,99 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_CL_LOG_H +# define _CLPLUMBING_CL_LOG_H +# include <glib.h> +# include <syslog.h> + +#define TIME_T unsigned long +#define HA_FAIL 0 +#define HA_OK 1 +#define MAXLINE (512*10) + +/* this is defined by the caller */ +struct logspam { + const char *id; /* identifier */ + int max; /* maximum number of messages ... */ + time_t window; /* ... within this timeframe */ + time_t reset_time; /* log new messages after this time */ + const char *advice; /* what to log in case messages get suppressed */ +}; + +/* this is internal (oblique to the caller) */ +struct msg_ctrl { + struct logspam *lspam; /* */ + time_t *msg_slots; /* msg slot root (space for lspam->max) */ + int last; /* last used msg slot [0..lspam->max-1]; -1 on init */ + int cnt; /* current msg count [0..lspam->max] */ + time_t suppress_t; /* messages blocked since this time */ +}; + +struct IPC_CHANNEL; + +extern int debug_level; +#define ANYDEBUG (debug_level) +#define DEBUGDETAILS (debug_level >= 2) +#define DEBUGAUTH (debug_level >=3) +#define DEBUGMODULE (debug_level >=3) +#define DEBUGPKT (debug_level >= 4) +#define DEBUGPKTCONT (debug_level >= 5) + +void cl_direct_log(int priority, const char* buf, gboolean, const char*, int, TIME_T); +void cl_log(int priority, const char * fmt, ...) G_GNUC_PRINTF(2,3); +void cl_limit_log(struct msg_ctrl *ml, int priority, const char * fmt, ...) G_GNUC_PRINTF(3,4); +struct msg_ctrl *cl_limit_log_new(struct logspam *lspam); +void cl_limit_log_destroy(struct msg_ctrl *ml); +void cl_limit_log_reset(struct msg_ctrl *ml); +void cl_perror(const char * fmt, ...) G_GNUC_PRINTF(1,2); +void cl_log_enable_stderr(int truefalse); +void cl_log_enable_stdout(int truefalse); +gboolean cl_log_test_logd(void); +void cl_log_set_uselogd(int truefalse); +void cl_log_enable_syslog_filefmt(int truefalse); +void cl_log_use_buffered_io(int truefalse); +gboolean cl_log_get_uselogd(void); +void cl_log_set_facility(int facility); +void cl_log_set_entity(const char * entity); +void cl_log_set_syslogprefix(const char *prefix); +void cl_log_set_logfile(const char * path); +void cl_log_set_debugfile(const char * path); +void cl_inherit_logging_environment(int maxqlen); +int cl_log_set_logd_channel_source( void (*create_callback)(struct IPC_CHANNEL* chan), + GDestroyNotify destroy_callback); +int cl_log_get_logdtime(void); +void cl_log_set_logdtime(int logdintval); + +char * ha_timestamp(TIME_T t); +void cl_glib_msg_handler(const gchar *log_domain +, GLogLevelFlags log_level, const gchar *message +, gpointer user_data); + +void cl_flush_logs(void); +void cl_log_args(int argc, char **argv); +int cl_log_is_logd_fd(int fd); +const char * prio2str(int priority); + +/* cl_log_use_buffered_io and cl_log_do_fflush as optimization for logd, + * so it may buffer a few message lines, then fflush them out in one write. + * Set do_fsync != 0, if you even want it to fsync. */ +void cl_log_do_fflush(int do_fsync); +void cl_log_use_buffered_io(int truefalse); +/* We now keep the file handles open for a potentially very long time. + * Sometimes we may need to close them explicitly. */ +void cl_log_close_log_files(void); + +#endif diff --git a/include/clplumbing/cl_misc.h b/include/clplumbing/cl_misc.h new file mode 100644 index 0000000..6f698b5 --- /dev/null +++ b/include/clplumbing/cl_misc.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_CL_MISC_H +#define _CLPLUMBING_CL_MISC_H +int cl_str_to_boolean(const char*, int*); + +int cl_file_exists(const char* filename); + +char* cl_get_env(const char* env_name); + +int cl_binary_to_int(const char* data, int len); + +long cl_get_msec(const char * input); /* string to msec */ + +#endif diff --git a/include/clplumbing/cl_pidfile.h b/include/clplumbing/cl_pidfile.h new file mode 100644 index 0000000..3dba50f --- /dev/null +++ b/include/clplumbing/cl_pidfile.h @@ -0,0 +1,25 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _LOCKFILE_H_ +#define _LOCKFILE_H_ + +int cl_read_pidfile(const char *filename); +int cl_read_pidfile_no_checking(const char *filename); +int cl_lock_pidfile(const char *filename); +int cl_unlock_pidfile(const char *filename); + +#endif diff --git a/include/clplumbing/cl_plugin.h b/include/clplumbing/cl_plugin.h new file mode 100644 index 0000000..e2431bf --- /dev/null +++ b/include/clplumbing/cl_plugin.h @@ -0,0 +1,29 @@ + + +/* + * cl_manage_plugin.c: This file handle plugin loading and deleting + * + * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __CL_PLUGIN__ +#define __CL_PLUGIN__ + +int cl_remove_plugin(const char* type, const char* pluginname); +void* cl_load_plugin(const char* type, const char* pluginname); + +#endif diff --git a/include/clplumbing/cl_poll.h b/include/clplumbing/cl_poll.h new file mode 100644 index 0000000..1b1908f --- /dev/null +++ b/include/clplumbing/cl_poll.h @@ -0,0 +1,46 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef CLPLUMBING_CL_POLL_H +# define CLPLUMBING_CL_POLL_H + +#include <glib.h> +#include <sys/poll.h> + +/* + * Poll the file descriptors described by the NFDS structures starting at + * FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for + * an event to occur; if TIMEOUT is -1, block until an event occurs. + * Returns the number of file descriptors with events, zero if timed out, + * or -1 for errors. + * + * When available, this function uses POSIX signals, and Linux F_SETSIG() + * calls to provide this capability. When it is not available it + * uses the real poll() call. + * + */ +int cl_poll(struct pollfd *fds, unsigned int nfds, int timeout_ms); + +/* + * Call cl_poll_ignore() when you close a file descriptor you monitored + * via cl_poll() before, or if you don't want it monitored any more. + */ +int cl_poll_ignore(int fd); + +/* Select the signal you want us to use (must be a RT signal) */ +int cl_poll_setsig(int nsig); + +int cl_glibpoll(GPollFD* ufds, guint nfsd, gint timeout); +#endif diff --git a/include/clplumbing/cl_quorum.h b/include/clplumbing/cl_quorum.h new file mode 100644 index 0000000..b7798ba --- /dev/null +++ b/include/clplumbing/cl_quorum.h @@ -0,0 +1,44 @@ +/* + * quorum.h: head file for quorum module + * + * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _QUORUM_H_ +#define _QUORUM_H_ + +#define HB_QUORUM_TYPE quorum +#define HB_QUORUM_TYPE_S "quorum" + +#define QUORUM_YES 0 +#define QUORUM_NO 1 +#define QUORUM_TIE 2 +typedef void(*callback_t)(void); +/* + * List of functions provided by implementations of the quorum interface. + */ +struct hb_quorum_fns { + + int (*getquorum) (const char* cluster + , int member_count, int member_quorum_votes + , int total_node_count, int total_quorum_votes); + int (*init) (callback_t notify, const char* cluster, const char* quorum_server); + void (*stop) (void); +}; + + +#endif diff --git a/include/clplumbing/cl_quorumd.h b/include/clplumbing/cl_quorumd.h new file mode 100644 index 0000000..6d282b3 --- /dev/null +++ b/include/clplumbing/cl_quorumd.h @@ -0,0 +1,48 @@ +/* + * quorum.h: head file for quorum module + * + * Author: Huang Zhen <zhenhltc@cn.ibm.com> + * Copyright (C) 2006 International Business Machines + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _QUORUMD_H_ +#define _QUORUMD_H_ + +#define HB_QUORUMD_TYPE quorumd +#define HB_QUORUMD_TYPE_S "quorumd" + +#define CONFIGFILE HA_HBCONF_DIR"/quorumd.conf" +#define MAX_DN_LEN 256 +#define quorum_log(priority, fmt...); \ + cl_log(priority, fmt); \ + +#define quorum_debug(priority, fmt...); \ + if ( debug_level > 0 ) { \ + cl_log(priority, fmt); \ + } + +/* List of functions provided by implementations of the quorumd interface. */ +struct hb_quorumd_fns { + int (*test) (void); + int (*init) (void); + int (*load_config_file) (void); + int (*dump_data) (int priority); + int (*on_connect) (int sock, gnutls_session session, const char* CN); +}; + + +#endif diff --git a/include/clplumbing/cl_random.h b/include/clplumbing/cl_random.h new file mode 100644 index 0000000..d1e37ce --- /dev/null +++ b/include/clplumbing/cl_random.h @@ -0,0 +1,81 @@ + +/* + * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu> + * Copyright (C) 2005 International Business Machines Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdlib.h> + +/* Intended usage is srand(cl_randseed()). + * This returns on "as good as it gets" random number usually taken from + * /dev/urandom to have a nice seed for future random numbers generated by + * rand(). */ +unsigned int cl_randseed(void); + +/* get_next_random() currently rand() based. + * + * You probably want to use cl_rand_from_interval instead. + * + * You don't need to srand(), it will seed once with cl_randseed internally. + * + * It is called that way, because it was exposed in the header file for a long + * time, and used to be coded in an attempt to pregenerate a queue of random + * numbers from the mainloop, and it would shift the next random number from + * that queue and trigger generation of new random numbers "at idle time" to + * refill that queue. + * Only that functionality never actually worked, is not interessting anymore + * anyways (rand() is cheap enough), and is now ripped out. + * + * So it now does srand(cl_randseed()) once internally, + * and from there on is equivalent to calling rand() directly, + * and could be called cl_rand(). + * + * If you want your own specific rand seed to re-generate a particular + * sequence, call it once, throw away the return code, then call + * srand(yourseed). Or don't use it anywhere in your code. */ +int get_next_random(void); + +/* generate some random number in the range [a;b]; + * typically used to randomly delay messages. */ +#define HAVE_CL_RAND_FROM_INTERVAL 1 +static inline +int cl_rand_from_interval(const int a, const int b) +{ + /* + * Be careful here, you don't know RAND_MAX at coding time, + * only at compile time. If you think + * (int)(a + (rand()*(b-a)+(RAND_MAX/2))/RAND_MAX); + * was correct, think again with RAND_MAX = INT_MAX, + * which is the case for many rand() implementations nowadays. + * + * Don't do modulo, either, as that will skew the distribution, and + * still has possible wraparounds, or an insufficient input set for too + * small RAND_MAX. + * + * Rather do the whole calculation in 64 bit, which should be correct + * as long as r, a, b, and RAND_MAX are all int. + * Of course, if you prefer, you can do it with floating point as well. + */ +#if 1 /* use long long */ + long long r = get_next_random(); + r = a + (r * (b-a) + RAND_MAX/2)/RAND_MAX; +#else /* use floating point */ + int r = get_next_random(); + r = a + (int)(1.0 / RAND_MAX * r * (b-a) + 0.5); +#endif + return r; +} diff --git a/include/clplumbing/cl_reboot.h b/include/clplumbing/cl_reboot.h new file mode 100644 index 0000000..1c759c8 --- /dev/null +++ b/include/clplumbing/cl_reboot.h @@ -0,0 +1,6 @@ +#ifndef CLPLUMBING_CL_REBOOT_H +#define CLPLUMBING_CL_REBOOT_H 1 +#include <glib.h> +void cl_enable_coredump_before_reboot(gboolean yesno); /* not implemented in all OSes */ +void cl_reboot(int msdelaybeforereboot, const char * reason); +#endif diff --git a/include/clplumbing/cl_signal.h b/include/clplumbing/cl_signal.h new file mode 100644 index 0000000..1a13a6b --- /dev/null +++ b/include/clplumbing/cl_signal.h @@ -0,0 +1,91 @@ +/* + * cl_signal.h: signal handling routines to be used by Linux-HA programmes + * + * Copyright (C) 2002 Horms <horms@verge.net.au> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _CL_SIGNAL_H +#define _CL_SIGNAL_H + +#include <stdio.h> +#include <signal.h> +#include <sys/signal.h> + +typedef struct { + int sig; + void (*handler)(int); + int interrupt; +} cl_signal_mode_t; + +#define CL_SIGNAL(_sig, _handler) \ + cl_signal_set_simple_handler((_sig), (_handler), NULL) +#if HAVE_SIGIGNORE +#define CL_IGNORE_SIG(_sig) sigignore((_sig)) +#else +#define CL_IGNORE_SIG(_sig) CL_SIGNAL((_sig), SIG_IGN) +#endif +#define CL_DEFAULT_SIG(_sig) CL_SIGNAL((_sig), SIG_DFL) + +#define CL_SIGINTERRUPT(_sig, _flag) siginterrupt((_sig), (_flag)) + +#define CL_SIGACTION(_signum, _act, _oldact) \ + sigaction((_signum), (_act), (_oldact)) +#define CL_SIGPROCMASK(_how, _set, _oldset) \ + cl_signal_block_set((_how), (_set), (_oldset)) +#define CL_SIGPENDING(_set) sigpending(_set) +#define CL_SIGSUSPEND(_mask) sigsuspend(_mask) + +#define CL_SIGEMPTYSET(_set) sigemptyset(_set) +#define CL_SIGFILLSET(_set) sigfillset(_set) +#define CL_SIGADDSET(_set, _signum) sigaddset((_set), (_signum)) +#define CL_SIGDELSET(_set, _signum) sigdelset((_set), (_signum)) +#define CL_SIGISMEMBER(_set, _signum) sigmember((_set), (_signum)) + +#define CL_KILL(_pid, _sig) kill((_pid), (_sig)) + +#define CL_PID_EXISTS(_pid) ( CL_KILL((_pid), 0) >= 0 || errno != ESRCH ) + +int +cl_signal_set_handler(int sig, void (*handler)(int), sigset_t *mask +, int flags, struct sigaction *oldact); + +int +cl_signal_set_simple_handler(int sig, void (*handler)(int) +, struct sigaction *oldact); + +int +cl_signal_set_action(int sig, void (*action)(int, siginfo_t *, void *) +, sigset_t *mask, int flags, struct sigaction *oldact); + +int +cl_signal_set_simple_action(int sig, void (*action)(int, siginfo_t *, void *) +, struct sigaction *oldact); + +int +cl_signal_set_interrupt(int sig, int flag); + +int +cl_signal_block(int how, int signal, sigset_t *oldset); + +int +cl_signal_block_set(int how, const sigset_t *set, sigset_t *oldset); + +int +cl_signal_set_handler_mode(const cl_signal_mode_t *mode, sigset_t *set); + + +#endif /* _CL_SIGNAL_H */ diff --git a/include/clplumbing/cl_syslog.h b/include/clplumbing/cl_syslog.h new file mode 100644 index 0000000..a7c1bfa --- /dev/null +++ b/include/clplumbing/cl_syslog.h @@ -0,0 +1,32 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Functions to support syslog. + * David Lee (c) 2005 + */ + +#ifndef _CLPLUMBING_CL_SYSLOG_H +#define _CLPLUMBING_CL_SYSLOG_H + +/* Convert string "auth" to equivalent number "LOG_AUTH" etc. */ +int cl_syslogfac_str2int(const char *); + +/* Convert number "LOG_AUTH" to equivalent string "auth" etc. */ +/* Returns static string; caller must NOT free. */ +const char *cl_syslogfac_int2str(int); + +#endif /* _CLPLUMBING_CL_SYSLOG_H */ diff --git a/include/clplumbing/cl_tiebreaker.h b/include/clplumbing/cl_tiebreaker.h new file mode 100644 index 0000000..11c10c4 --- /dev/null +++ b/include/clplumbing/cl_tiebreaker.h @@ -0,0 +1,35 @@ +/* + * cl_tiebreaker.h: head file for tiebreaker module + * + * Copyright (C) 2005 Guochun Shi <gshi@ncsa.uiuc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CL_TIEBREAKER_H_ +#define _CL_TIEBREAKER_H_ + +#define HB_TIEBREAKER_TYPE tiebreaker +#define HB_TIEBREAKER_TYPE_S "tiebreaker" + +/* + * List of functions provided by implementations of tiebreaker interface. + */ +struct hb_tiebreaker_fns { + gboolean (*break_tie) (int, int); +}; + + +#endif diff --git a/include/clplumbing/cl_uuid.h b/include/clplumbing/cl_uuid.h new file mode 100644 index 0000000..12542cd --- /dev/null +++ b/include/clplumbing/cl_uuid.h @@ -0,0 +1,40 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CL_UUID_H_ +#define _CL_UUID_H_ +#include <glib.h> + +typedef struct cl_uuid_s{ + unsigned char uuid[16]; +}cl_uuid_t; + +void cl_uuid_copy(cl_uuid_t* dst, cl_uuid_t* src); +void cl_uuid_clear(cl_uuid_t* uu); +int cl_uuid_compare(const cl_uuid_t* uu1, const cl_uuid_t* uu2); +void cl_uuid_generate(cl_uuid_t* out); +int cl_uuid_is_null(cl_uuid_t* uu); +int cl_uuid_parse( char *in, cl_uuid_t* uu); +#define UU_UNPARSE_SIZEOF 37 /* Including NULL byte */ +void cl_uuid_unparse(const cl_uuid_t* uu, char *out); + +/* Suitable for ues as a GHashFunc from glib */ +guint cl_uuid_g_hash(gconstpointer uuid_ptr); +/* Suitable for ues as a GEqualFunc from glib */ +gboolean cl_uuid_g_equal(gconstpointer uuid_ptr_a, gconstpointer uuid_ptr_b); + + +#endif diff --git a/include/clplumbing/coredumps.h b/include/clplumbing/coredumps.h new file mode 100644 index 0000000..4d5ce79 --- /dev/null +++ b/include/clplumbing/coredumps.h @@ -0,0 +1,36 @@ +/* + * Basic Core dump control functions. + * + * Copyright (C) 2004 IBM Corporation + * + * This software licensed under the GNU LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _CLPLUMBING_COREFILES_H +# define _CLPLUMBING_COREFILES_H 1 + /* Set the root directory of our core directory hierarchy */ +int cl_set_corerootdir(const char * dir); + /* Change directory to the directory our core file needs to go in */ + /* Call after you establish the userid you're running under */ +int cl_cdtocoredir(void); + /* Enable/disable core dumps for ourselves and our child processes */ +int cl_enable_coredumps(int truefalse); +void cl_untaint_coredumps(void); +void cl_set_coredump_signal_handler(int nsig); +void cl_set_all_coredump_signal_handlers(void); + +#endif diff --git a/include/clplumbing/cpulimits.h b/include/clplumbing/cpulimits.h new file mode 100644 index 0000000..f7dd875 --- /dev/null +++ b/include/clplumbing/cpulimits.h @@ -0,0 +1,66 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Functions to put limits on CPU consumption. + * This allows us to better catch runaway realtime processes that + * might otherwise hang the whole system. + * + * The process is basically this: + * - Set the CPU percentage limit with cl_cpu_limit_setpercent() + * according to what you expect the CPU percentage to top out at + * measured over an interval at >= 10 seconds + * - Call cl_cpu_limit_ms_interval() to figure out how often to update + * the CPU limit (it returns milliseconds) + * - At least as often as indicated above, call cl_cpu_limit_update() + * to update our current CPU limit. + * + * These limits are approximate, so be a little conservative. + * If you've gone into an infinite loop, it'll likely get caught ;-) + * + * Note that exceeding the soft CPU limits we set here will cause a + * SIGXCPU signal to be sent. + * + * The default action for this signal is to cause a core dump. + * This is a good choice ;-) + * + * As of this writing, this code will never set the soft CPU limit less + * than two seconds, or greater than 10 seconds. + * + * It will currrently return a limit update interval between 10000 and + * 400000 milliseconds. + * + */ + +/* + * Set expected CPU percentage upper bound + */ +int cl_cpu_limit_setpercent(int ipercent); + +/* + * Update the current CPU limit + */ +int cl_cpu_limit_update(void); + +/* + * How often should we call cl_cpu_limit_update()? + * + * Note: return result is in milliseconds + */ +int cl_cpu_limit_ms_interval(void); + +/* Disable further CPU limits... */ +int cl_cpu_limit_disable(void); diff --git a/include/clplumbing/ipc.h b/include/clplumbing/ipc.h new file mode 100644 index 0000000..4a5e151 --- /dev/null +++ b/include/clplumbing/ipc.h @@ -0,0 +1,788 @@ +/* + * ipc.h IPC abstraction data structures. + * + * author Xiaoxiang Liu <xiliu@ncsa.uiuc.edu>, + * Alan Robertson <alanr@unix.sh> + * + * + * Copyright (c) 2002 International Business Machines + * Copyright (c) 2002 Xiaoxiang Liu <xiliu@ncsa.uiuc.edu> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _IPC_H_ +#define _IPC_H_ +#include <glib.h> +#undef MIN +#undef MAX +#include <sys/types.h> +#include <sys/poll.h> + +#ifdef IPC_TIME_DEBUG +#include <clplumbing/longclock.h> +#define MAXIPCTIME 3000 + +#endif + +/* constants */ +#define DEFAULT_MAX_QLEN 64 +#define MAX_MSGPAD 128 +/* channel and connection status */ +#define IPC_CONNECT 1 /* Connected: can read, write */ +#define IPC_WAIT 2 /* Waiting for connection */ +#define IPC_DISCONNECT 3 /* Disconnected, can't read or write*/ +#define IPC_DISC_PENDING 4 /* Disconnected, can't write but */ + /* may be more data to read */ + +#define MAXFAILREASON 128 + +#define IPC_SERVER 1 +#define IPC_CLIENT 2 +#define IPC_PEER 3 + +#define IPC_ISRCONN(ch) ((ch)->ch_status == IPC_CONNECT \ + || (ch)->ch_status == IPC_DISC_PENDING) + +#define IPC_ISWCONN(ch) ((ch)->ch_status == IPC_CONNECT) + +/* general return values */ +#define IPC_OK 0 +#define IPC_FAIL 1 +#define IPC_BROKEN 2 +#define IPC_INTR 3 +#define IPC_TIMEOUT 4 + +/* + * IPC: Sockets-like Interprocess Communication Abstraction + * + * We have two fundamental abstractions which we maintain. + * Everything else is in support of these two abstractions. + * + * These two main abstractions are: + * + * IPC_WaitConnection: + * A server-side abstraction for waiting for someone to connect. + * + * IPC_Channel: + * An abstraction for an active communications channel. + * + * All the operations on these two abstractions are carried out + * via function tables (channel->ops). Below we refer to the + * function pointers in these tables as member functions. + * + * On the server side, everything starts up with a call to + * ipc_wait_conn_constructor(), which returns an IPC_WaitConnection. + * + * Once the server has the IPC_WaitConnection object in hand, + * it can give the result of the get_select_fd() member function + * to poll or select to inform you when someone tries to connect. + * + * Once select tells you someone is trying to connect, you then + * use the accept_connection() member function to accept + * the connection. accept_connection() returns an IPC_Channel. + * + * With that, the server can talk to the client, and away they + * go ;-) + * + * On the client side, everything starts up with a call to + * ipc_channel_constructor() which we use to talk to the server. + * The client is much easier ;-) + */ + + +typedef struct IPC_WAIT_CONNECTION IPC_WaitConnection; +typedef struct IPC_CHANNEL IPC_Channel; + +typedef struct IPC_MESSAGE IPC_Message; +typedef struct IPC_QUEUE IPC_Queue; +typedef struct IPC_AUTH IPC_Auth; + +typedef struct IPC_OPS IPC_Ops; +typedef struct IPC_WAIT_OPS IPC_WaitOps; + + + +/* wait connection structure. */ +struct IPC_WAIT_CONNECTION{ + int ch_status; /* wait conn. status.*/ + void * ch_private; /* wait conn. private data. */ + IPC_WaitOps *ops; /* wait conn. function table .*/ +}; + + +typedef void(*flow_callback_t)(IPC_Channel*, void*); + +/* channel structure.*/ +struct IPC_CHANNEL{ + int ch_status; /* identify the status of channel.*/ + int refcount; /* reference count */ + pid_t farside_pid; /* far side pid */ + void* ch_private; /* channel private data. */ + /* (may contain conn. info.) */ + IPC_Ops* ops; /* IPC_Channel function table.*/ + + /* number of bytes needed + * at the begginging of <ipcmessage>->msg_body + * it's for msg head needed to tranmit in wire + */ + unsigned int msgpad; + + /* the number of bytes remainng to send for the first message in send queue + 0 means nothing has been sent thus all bytes needs to be send + n != 0 means there are still n bytes needs to be sent + */ + unsigned int bytes_remaining; + + + /* is the send blocking or nonblocking*/ + gboolean should_send_block; + + /* if send would block, should an error be returned or not */ + gboolean should_block_fail; + +/* There are two queues in channel. One is for sending and the other + * is for receiving. + * Those two queues are channel's internal queues. They should not be + * accessed directly. + */ + /* private: */ + IPC_Queue* send_queue; + IPC_Queue* recv_queue; + + /* buffer pool for receive in this channel*/ + struct ipc_bufpool* pool; + + /* the follwing is for send flow control*/ + int high_flow_mark; + int low_flow_mark; + void* high_flow_userdata; + void* low_flow_userdata; + flow_callback_t high_flow_callback; + flow_callback_t low_flow_callback; + + int conntype; + + char failreason[MAXFAILREASON]; + + /* New members to support Multi-level ACLs for the CIB, + * available since libplumb.so.2.1.0, added at the + * end of the struct to maintain backwards ABI compatibility. + * + * If you don't like to care for library versions, + * create your IPC channels with + * c = ipc_wait_conn_constructor(IPC_UDS_CRED, ...), + * and these members will be available. + */ + uid_t farside_uid; /* far side uid */ + gid_t farside_gid; /* far side gid */ +}; + +struct IPC_QUEUE{ + size_t current_qlen; /* Current qlen */ + size_t max_qlen; /* Max allowed qlen */ + GList* queue; /* List of messages */ + /* keep the time of the last max queue warning */ + time_t last_maxqlen_warn; + /* and the number of messages lost */ + unsigned maxqlen_cnt; +}; + +/* authentication information : set of gids and uids */ +struct IPC_AUTH { + GHashTable * uid; /* hash table for user id */ + GHashTable * gid; /* hash table for group id */ +}; + + +/* Message structure. */ +struct IPC_MESSAGE{ + size_t msg_len; + void* msg_buf; + void* msg_body; +/* + * IPC_MESSAGE::msg_done + * the callback function pointer which can be called after this + * message is sent, received or otherwise processed. + * + * Parameter: + * msg: the back pointer to the message which contains this + * function pointer. + * + */ + void (* msg_done)(IPC_Message * msg); + void* msg_private; /* the message private data. */ + /* Belongs to message creator */ + /* May be used by callback function. */ + IPC_Channel * msg_ch; /* Channel the */ + /* message is from/in */ + +}; + +struct IPC_WAIT_OPS{ +/* + * IPC_WAIT_OPS::destroy + * destroy the wait connection and free the memory space used by + * this wait connection. + * + * Parameters: + * wait_conn (IN): the pointer to the wait connection. + * + */ + void (* destroy)(IPC_WaitConnection *wait_conn); +/* + * IPC_WAIT_OPS::get_select_fd + * provide a fd which user can listen on for a new coming connection. + * + * Parameters: + * wait_conn (IN) : the pointer to the wait connection which + * we're supposed to return the file descriptor for + * (the file descriptor can be used with poll too ;-)) + * + * Return values: + * integer >= 0 : the select_fd. + * -1 : can't get the select fd. + * + */ + int (* get_select_fd)(IPC_WaitConnection *wait_conn); +/* + * IPC_WAIT_OPS::accept_connection + * accept and create a new connection and verify the authentication. + * + * Parameters: + * wait_conn (IN) : the waiting connection which will accept + * create the new connection. + * auth_info (IN) : the authentication information which will be + * verified for the new connection. + * + * Return values: + * the pointer to the new IPC channel; NULL if the creation or + * authentication fails. + * + */ + IPC_Channel * (* accept_connection) + (IPC_WaitConnection * wait_conn, IPC_Auth *auth_info); +}; + +/* Standard IPC channel operations */ + +struct IPC_OPS{ +/* + * IPC_OPS::destroy + * brief destroy the channel object. + * + * Parameters: + * ch (IN) : the pointer to the channel which will be destroyed. + * + */ + void (*destroy) (IPC_Channel * ch); +/* + * IPC_OPS::initiate_connection + * used by service user side to set up a connection. + * + * Parameters: + * ch (IN) : the pointer to channel used to initiate the connection. + * + * Return values: + * IPC_OK : the channel set up the connection successfully. + * IPC_FAIL : the connection initiation fails. + * + */ + int (* initiate_connection) (IPC_Channel * ch); +/* + * IPC_OPS::verify_auth + * used by either side to verify the identity of peer on connection. + * + * Parameters + * ch (IN) : the pointer to the channel. + * + * Return values: + * IPC_OK : the peer is trust. + * IPC_FAIL : verifying authentication fails. + */ + int (* verify_auth) (IPC_Channel * ch, IPC_Auth* info); +/* + * IPC_OPS::assert_auth + * service user asserts to be certain qualified service user. + * + * Parameters: + * ch (IN): the active channel. + * auth (IN): the hash table which contains the asserting information. + * + * Return values: + * IPC_OK : assert the authentication successfully. + * IPC_FAIL : assertion fails. + * + * NOTE: This operation is a bit obscure. It isn't needed with + * UNIX domain sockets at all. The intent is that some kinds + * of IPC (like FIFOs), do not have an intrinsic method to + * authenticate themselves except through file permissions. + * The idea is that you must tell it how to chown/grp your + * FIFO so that the other side and see that if you can write + * this, you can ONLY be the user/group they expect you to be. + * But, I think the parameters may be wrong for this ;-) + */ + int (* assert_auth) (IPC_Channel * ch, GHashTable * auth); +/* + * IPC_OPS::send + * send the message through the sending connection. + * + * Parameters: + * ch (IN) : the channel which contains the connection. + * msg (IN) : pointer to the sending message. User must + * allocate the message space. + * + * Return values: + * IPC_OK : the message was either sent out successfully or + * appended to the send_queue. + * IPC_FAIL : the send operation failed. + * IPC_BROKEN : the channel is broken. + * +*/ + int (* send) (IPC_Channel * ch, IPC_Message* msg); + +/* + * IPC_OPS::recv + * receive the message through receving queue. + * + * Parameters: + * ch (IN) : the channel which contains the connection. + * msg (OUT): the IPC_MESSAGE** pointer which contains the pointer + * to the received message or NULL if there is no + * message available. + * + * Return values: + * IPC_OK : receive operation is completed successfully. + * IPC_FAIL : operation failed. + * IPC_BROKEN : the channel is broken (disconnected) + * + * Note: + * return value IPC_OK doesn't mean the message is already + * sent out to (or received by) the peer. It may be pending + * in the send_queue. In order to make sure the message is no + * longer needed, please specify the msg_done function in the + * message structure and once this function is called, the + * message is no longer needed. + * + * is_sending_blocked() is another way to check if there is a message + * pending in the send_queue. + * + */ + int (* recv) (IPC_Channel * ch, IPC_Message** msg); + +/* + * IPC_OPS::waitin + * Wait for input to become available + * + * Parameters: + * ch (IN) : the channel which contains the connection. + * + * Side effects: + * If output becomes unblocked while waiting, it will automatically + * be resumed without comment. + * + * Return values: + * IPC_OK : a message is pending or output has become unblocked. + * IPC_FAIL : operation failed. + * IPC_BROKEN : the channel is broken (disconnected) + * IPC_INTR : waiting was interrupted by a signal + */ + int (* waitin) (IPC_Channel * ch); +/* + * IPC_OPS::waitout + * Wait for output to finish + * + * Parameters: + * ch (IN) : the channel which contains the connection. + * + * Side effects: + * If input becomes available while waiting, it will automatically + * be read into the channel queue without comment. + * + * Return values: + * IPC_OK : output no longer blocked + * IPC_FAIL : operation failed. + * IPC_BROKEN : the channel is broken (disconnected) + * IPC_INTR : waiting was interrupted by a signal + */ + int (* waitout) (IPC_Channel * ch); + +/* + * IPC_OPS::is_message_pending + * check to see if there is any messages ready to read, or hangup has + * occurred. + * + * Parameters: + * ch (IN) : the pointer to the channel. + * + * Return values: + * TRUE : there are messages ready to read, or hangup. + * FALSE: there are no messages ready to be read. + */ + gboolean (* is_message_pending) (IPC_Channel * ch); + +/* + * IPC_OPS::is_sending_blocked + * check the send_queue to see if there are any messages blocked. + * + * Parameters: + * ch (IN) : the pointer to the channel. + * + * Return values: + * TRUE : there are messages blocked (waiting) in the send_queue. + * FALSE: there are no message blocked (waiting) in the send_queue. + * + * See also: + * get_send_select_fd() + */ + gboolean (* is_sending_blocked) (IPC_Channel *ch); + +/* + * IPC_OPS::resume_io + * Resume all possible IO operations through the IPC transport + * + * Parameters: + * the pointer to the channel. + * + * Return values: + * IPC_OK : resume all the possible I/O operation successfully. + * IPC_FAIL : the operation fails. + * IPC_BROKEN : the channel is broken. + * + */ + int (* resume_io) (IPC_Channel *ch); +/* + * IPC_OPS::get_send_select_fd() + * return a file descriptor which can be given to select/poll. This fd + * is used by the IPC code for sending. It is intended that this be + * ONLY used with select, poll, or similar mechanisms, not for direct I/O. + * Note that due to select(2) and poll(2) semantics, you must check + * is_sending_blocked() to see whether you should include this FD in + * your poll for writability, or you will loop very fast in your + * select/poll loop ;-) + * + * Parameters: + * ch (IN) : the pointer to the channel. + * + * Return values: + * integer >= 0 : the send fd for selection. + * -1 : there is no send fd. + * + * See also: + * is_sending_blocked() + */ + int (* get_send_select_fd) (IPC_Channel * ch); +/* + * IPC_OPS::get_recv_select_fd + * return a file descriptor which can be given to select. This fd + * is for receiving. It is intended that this be ONLY used with select, + * poll, or similar mechanisms, NOT for direct I/O. + * + * Parameters: + * ch (IN) : the pointer to the channel. + * + * Return values: + * integer >= 0 : the recv fd for selection. + * -1 : there is no recv fd. + * + * NOTE: This file descriptor is often the same as the send + * file descriptor. + */ + int (* get_recv_select_fd) (IPC_Channel * ch); +/* + * IPC_OPS::set_send_qlen + * allow user to set the maximum send_queue length. + * + * Parameters + * ch (IN) : the pointer to the channel. + * q_len (IN) : the max length for the send_queue. + * + * Return values: + * IPC_OK : set the send queue length successfully. + * IPC_FAIL : there is no send queue. (This isn't supposed + * to happen). + * It means something bad happened. + * + */ + int (* set_send_qlen) (IPC_Channel * ch, int q_len); +/* + * IPC_OPS::set_recv_qlen + * allow user to set the maximum recv_queue length. + * + * Parameters: + * ch (IN) : the pointer to the channel. + * q_len (IN) : the max length for the recv_queue. + * + * Return values: + * IPC_OK : set the recv queue length successfully. + * IPC_FAIL : there is no recv queue. + * + */ + int (* set_recv_qlen) (IPC_Channel * ch, int q_len); + + +/* + * IPC_OPS: set callback for high/low flow mark + * ch (IN) : the pointer to the channel + * callback (IN) : the callback function + * user_data(IN) : a pointer to user_data + * callback will be called with channel and + * this user_data as parameters + * + * Return values: + * void + * + */ + + + void (* set_high_flow_callback) (IPC_Channel* ch , + flow_callback_t callback, + void* user_data); + + void (* set_low_flow_callback) (IPC_Channel* ch , + flow_callback_t callback, + void* user_data); + +/* + * IPC_OPS::new_ipcmsg + * ch (IN) : the pointer to the channel + * data (IN) : data to be copied to the message body + * len (IN) : data len + * private (IN): the pointer value to set as in the message + * + * Return values: + * the pointer to a new created message will be + * returned if success or NULL if failure + * + */ + + IPC_Message* (*new_ipcmsg)(IPC_Channel* ch, const void* data, + int len, void* private); + + +/* + * IPC_OPS::nget_chan_status + * ch (IN) : the pointer to the channel + * + * Return value: + * channel status. + * + */ + int (*get_chan_status)(IPC_Channel* ch); + + +/* + * These two functions returns true if the corresponding queue + * is full, otherwise it returns false + */ + + gboolean (*is_sendq_full)(struct IPC_CHANNEL * ch); + gboolean (*is_recvq_full)(struct IPC_CHANNEL * ch); + + + /* Get the connection type for the channel + * it can be IPC_SERVER, IPC_CLIENT, IPC_PEER + */ + + int (*get_conntype)(struct IPC_CHANNEL* ch); + + int (*disconnect)(struct IPC_CHANNEL* ch); + +}; + + +/* + * ipc_wait_conn_constructor: + * the common constructor for ipc waiting connection. + * Use ch_type to identify the connection type. Usually it's only + * needed by server side. + * + * Parameters: + * ch_type (IN) : the type of the waiting connection to create. + * ch_attrs (IN) : the hash table which contains the attributes + * needed by this waiting connection in name/value + * pair format. + * + * For example, the only attribute needed by UNIX + * domain sockets is path name. + * + * Return values: + * the pointer to a new waiting connection or NULL if the connection + * can't be created. + * Note: + * current implementation supports + * IPC_ANYTYPE: This is what program code should typically use. + * Internally it is an alias to IPC_UDS_CRED. + * IPC_UDS_CRED: Unix Domain Sockets, + * farside uid + gid credentials is available. + * Available since libplumb.so.2.1.0. + * IPC_DOMAIN_SOCKET: An other alias to Unix Domain Sockets; + * internally it is equivalent to both above. + * Using this explicitly, your code will work + * even with libplumb.so.2.0.0. + * Which also means that you MUST NOT use the + * farside_uid/gid functionality then. + */ +extern IPC_WaitConnection * ipc_wait_conn_constructor(const char * ch_type +, GHashTable* ch_attrs); + +/* + * ipc_channel_constructor: + * brief the common constructor for ipc channel. + * Use ch_type to identify the channel type. + * Usually this function is only called by client side. + * + * Parameters: + * ch_type (IN): the type of the channel you want to create. + * ch_attrs (IN): the hash table which contains the attributes needed + * by this channel. + * For example, the only attribute needed by UNIX domain + * socket is path name. + * + * Return values: + * the pointer to the new channel whose status is IPC_DISCONNECT + * or NULL if the channel can't be created. + * + * Note: + * See comments for ipc_wait_conn_constructor above + * for currently implemented ch_type channel types. + */ +extern IPC_Channel * ipc_channel_constructor(const char * ch_type +, GHashTable* ch_attrs); + +/* + * ipc_channel_pair: + * Construct a pair of connected IPC channels in a fashion analogous + * to pipe(2) or socketpair(2). + * + * Parameters: + * channels: an array of two IPC_Channel pointers for return result + */ +int ipc_channel_pair(IPC_Channel* channels[2]); + +/* + * ipc_set_auth: + * A helper function used to convert array of uid and gid into + * an authentication structure (IPC_Auth) + * + * Parameters: + * a_uid (IN): the array of a set of user ids. + * a_gid (IN): the array of a set of group ids. + * num_uid (IN): the number of user ids. + * num_gid (IN): the number of group ids. + * + * Return values: + * the pointer to the authentication structure which contains the + * set of uid and the set of gid. Or NULL if this structure can't + * be created. + * + */ + + +IPC_Auth* ipc_str_to_auth(const char * uidlist, int, const char * gidlist, int); + +extern IPC_Auth * ipc_set_auth(uid_t * a_uid, gid_t * a_gid +, int num_uid, int num_gid); + +/* Destroys an object constructed by ipc_set_auth or ipc_str_to_auth() */ +extern void ipc_destroy_auth(IPC_Auth * auth); + +extern void ipc_set_pollfunc(int (*)(struct pollfd*, unsigned int, int)); +extern void ipc_bufpool_dump_stats(void); + +#ifdef IPC_TIME_DEBUG + +enum MSGPOS_IN_IPC{ + MSGPOS_ENQUEUE, + MSGPOS_SEND, + MSGPOS_RECV, + MSGPOS_DEQUEUE +}; + +#endif + + +struct SOCKET_MSG_HEAD{ + int msg_len; + unsigned int magic; +#ifdef IPC_TIME_DEBUG + longclock_t enqueue_time; + longclock_t send_time; + longclock_t recv_time; + longclock_t dequeue_time; +#endif + +}; + + +/* MAXMSG is the maximum final message size on the wire. */ +#define MAXMSG (256*1024) +/* MAXUNCOMPRESSED is the maximum, raw data size prior to compression. */ +/* 1:8 compression ratio is to be expected on data such as xml */ +#define MAXUNCOMPRESSED (2048*1024) +#define HEADMAGIC 0xabcd +#define POOL_SIZE (4*1024) +struct ipc_bufpool{ + + int refcount; + char* currpos; + char* consumepos; + char* startpos; + char* endpos; + int size; +}; + +struct ipc_bufpool* ipc_bufpool_new(int); + +void ipc_bufpool_del(struct ipc_bufpool* pool); + +int ipc_bufpool_spaceleft(struct ipc_bufpool* pool); + +int ipc_bufpool_update(struct ipc_bufpool* pool, + struct IPC_CHANNEL * ch, + int msg_len, + IPC_Queue* rqueue); + +gboolean ipc_bufpool_full(struct ipc_bufpool* pool, + struct IPC_CHANNEL* ch, + int*); +int ipc_bufpool_partial_copy(struct ipc_bufpool* dstpool, + struct ipc_bufpool* srcpool); + +void ipc_bufpool_ref(struct ipc_bufpool* pool); + +void ipc_bufpool_unref(struct ipc_bufpool* pool); + +void set_ipc_time_debug_flag(gboolean flag); + +/* pathname attribute */ +#define IPC_PATH_ATTR "path" +/* socket mode attribute */ +#define IPC_MODE_ATTR "sockmode" +/* Unix domain socket, used by old code. + * See also the comment block above ipc_wait_conn_constructor() */ +#define IPC_DOMAIN_SOCKET "uds" +/* Unix domain socket with farside uid + gid credentials. + * Available since libplumb.so.2.1.0 */ +#define IPC_UDS_CRED "uds_c" + +#ifdef IPC_UDS_CRED +# define IPC_ANYTYPE IPC_UDS_CRED +#else +# error "No IPC types defined(!)" +#endif + +#endif diff --git a/include/clplumbing/loggingdaemon.h b/include/clplumbing/loggingdaemon.h new file mode 100644 index 0000000..ba986f5 --- /dev/null +++ b/include/clplumbing/loggingdaemon.h @@ -0,0 +1,32 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Messages sent to the logging daemon */ +#define LD_LOGIT 2 +#define MAXENTITY 64 + +/* Message contains following header, followed by the text (char[]) itself */ +struct LogDaemonMsgHdr_s { + int msgtype; + int facility; + int priority; + int msglen; + gboolean use_pri_str; + int entity_pid; + char entity[MAXENTITY]; + TIME_T timestamp; +}; +typedef struct LogDaemonMsgHdr_s LogDaemonMsgHdr; diff --git a/include/clplumbing/longclock.h b/include/clplumbing/longclock.h new file mode 100644 index 0000000..ae95b28 --- /dev/null +++ b/include/clplumbing/longclock.h @@ -0,0 +1,143 @@ +/* + * Longclock operations + * + * Copyright (c) 2002 International Business Machines + * Author: Alan Robertson <alanr@unix.sh> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _LONGCLOCK_H +# define _LONGCLOCK_H +/* + * A longclock_t object is a lot like a clock_t object, except that it + * won't wrap in the lifetime of the earth. It is guaranteed to be at + * least 64 bits. This means it should go for around 2 billion years. + * + * It is also supposed to be proof against changes in the local time on + * the computer. This is easy if you have a properly-working times(2) + * for us to use. + * + * longclock_t's are definitely not comparable between computers, and in + * some implementations, not even between processes on the same computer. + * + * + * The functions provided here are: + * + * unsigned long cl_times(void); + * A rational wrapper for the times(2) call + * for those cases where only the return value + * is wanted. + * longclock_t time_longclock(void); + * Returns current time as a longclock_t. + * + * longclock_t msto_longclock(unsigned long); + * Converts quantity in milliseconds to longclock_t + * + * unsigned long longclockto_ms(longclock_t); + * Converts quantity in longclock_t to milliseconds + * NOTE: Can overflow! + * + * unsigned long longclockto_long(longclock_t); + * Converts quantity in longclock_t to clock_t + * NOTE: Can overflow! + * + * longclock_t secsto_longclock(unsigned long); + * Converts quantity in seconds to longclock_t + * + * longclock_t add_longclock(longclock_t l, longclock_t r); + * Adds two longclock_t values + * + * int cmp_longclock(longclock_t l, longclock_t r); + * Returns negative, zero or positive value + * + * longclock_t sub_longclock(longclock_t l, longclock_t r); + * Subtracts two longclock_t values + * NOTE: Undefined if l is < r + * + * longclock_t dsecsto_longclock(double); + * Converts quantity in seconds (as a double) + * to a longclock_t + * + * unsigned hz_longclock(void); + * Returns frequency of longclock_t clock. + * + * We provide this constant: + * + * extern const longclock_t zero_longclock; + */ +extern unsigned long cl_times(void); + +#ifdef CLOCK_T_IS_LONG_ENOUGH +# ifndef HAVE_LONGCLOCK_ARITHMETIC +# define HAVE_LONGCLOCK_ARITHMETIC +# endif + +# include <sys/times.h> + + typedef clock_t longclock_t; + +#else /* clock_t isn't at least 64 bits */ + typedef unsigned long long longclock_t; +#endif + +longclock_t time_longclock(void); + +extern const longclock_t zero_longclock; + +unsigned hz_longclock(void); +longclock_t secsto_longclock(unsigned long); +longclock_t dsecsto_longclock(double); +longclock_t msto_longclock(unsigned long); +unsigned long longclockto_ms(longclock_t); /* Can overflow! */ +long longclockto_long(longclock_t); /* May overflow! */ + + +#ifndef HAVE_LONGCLOCK_ARITHMETIC + +longclock_t add_longclock(longclock_t l, longclock_t r); + + /* Undefined if l is < r according to cmp_longclock() */ +longclock_t sub_longclock(longclock_t l, longclock_t r); + +int cmp_longclock(longclock_t l, longclock_t r); + + +#else /* We HAVE_LONGCLOCK_ARITHMETIC */ + +# define longclockto_long(lc) ((long)(lc)) + +# define add_longclock(l,r) \ + ((longclock_t)(l) + (longclock_t)(r)) + +# define sub_longclock(l,r) \ + ((longclock_t)(l) - (longclock_t)(r)) + +# define cmp_longclock(l,r) \ + (((longclock_t)(l) < (longclock_t)(r)) \ + ? -1 \ + : (((longclock_t)(l) > (longclock_t)(r)) \ + ? +1 : 0)) +#endif + + +/* N.B: Possibly not the best place for this, but it will do for now */ +/* This is consistent with OpenBSD, and is a good choice anyway */ +#define TIME_T unsigned long +#define TIME_F "%lu" +#define TIME_X "%lx" + +#endif diff --git a/include/clplumbing/lsb_exitcodes.h b/include/clplumbing/lsb_exitcodes.h new file mode 100644 index 0000000..e46b5be --- /dev/null +++ b/include/clplumbing/lsb_exitcodes.h @@ -0,0 +1,92 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* LSB status exit codes. + * + * All of these and the supporting text are taken from the LSB. + * + * If the status command is given, the init script will return + * the following exit status codes. + * + * 0 program is running or service is OK + * 1 program is dead and /var/run pid file exists + * 2 program is dead and /var/lock lock file exists + * 3 program is stopped + * 4 program or service status is unknown + * 5-99 reserved for future LSB use + * 100-149 reserved for distribution use + * 150-199 reserved for application use + * 200-254 reserved + */ + +#define LSB_STATUS_OK 0 +#define LSB_STATUS_VAR_PID 1 +#define LSB_STATUS_VAR_LOCK 2 +#define LSB_STATUS_STOPPED 3 +#define LSB_STATUS_UNKNOWN 4 +#define LSB_STATUS_LSBRESERVED 5 +#define LSB_STATUS_DISTRESERVED 100 +#define LSB_STATUS_APPRESERVED 150 +#define LSB_STATUS_RESERVED 200 +/* + * + * In the case of init script commands other than "status" + * (i.e., "start", "stop", "restart", "reload", and "force-reload"), + * the init script must return an exit status of zero if the action + * described by the argument has been successful. Otherwise, the + * exit status shall be non-zero, as defined below. In addition + * to straightforward success, the following situations are also + * to be considered successful: + * + * restarting a service (instead of reloading it) with the + * "force-reload" argument + * running "start" on a service already running + * running "stop" on a service already stopped or not running + * running "restart" on a service already stopped or not running + * In case of an error, while processing any init script action + * except for "status", the init script must print an error + * message and return one of the following non-zero exit + * status codes. + * + * 1 generic or unspecified error (current practice) + * 2 invalid or excess argument(s) + * 3 unimplemented feature (for example, "reload") + * 4 user had insufficient privilege + * 5 program is not installed + * 6 program is not configured + * 7 program is not running + * 8-99 reserved for future LSB use + * 100-149 reserved for distribution use + * 150-199 reserved for application use + * 200-254 reserved + * + * All error messages must be printed on standard error. + * All status messages must be printed on standard output. + * (This does not prevent scripts from calling the logging + * functions such as log_failure_msg). + */ +#define LSB_EXIT_OK 0 +#define LSB_EXIT_GENERIC 1 +#define LSB_EXIT_EINVAL 2 +#define LSB_EXIT_ENOTSUPPORTED 3 +#define LSB_EXIT_EPERM 4 +#define LSB_EXIT_NOTINSTALLED 5 +#define LSB_EXIT_NOTCONFIGED 6 +#define LSB_EXIT_NOTRUNNING 7 +#define LSB_EXIT_LSBRESERVED 8 +#define LSB_EXIT_DISTRESERVED 100 +#define LSB_EXIT_APPRESERVED 150 +#define LSB_EXIT_RESERVED 200 diff --git a/include/clplumbing/md5.h b/include/clplumbing/md5.h new file mode 100644 index 0000000..95b2c33 --- /dev/null +++ b/include/clplumbing/md5.h @@ -0,0 +1,49 @@ +/* + * md5.h: MD5 and keyed-MD5 algorithms + * + * Author: Sun Jiang Dong <sunjd@cn.ibm.com> + * Copyright (c) 2005 International Business Machines + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _MD5_H_ +#define _MD5_H__ + +/* + * MD5: The MD5 Message-Digest Algorithm ( RFC 1321 ) + * return value: 0 - success + * <0 - fail + * Note: The digest buffer should be not less than 16. + * + */ +int MD5( const unsigned char *data + , unsigned long data_len + , unsigned char * digest); + +/* + * HMAC: Keyed-Hashing for Message Authentication + * return value: 0 - success + * <0 - fail + * Note: The digest buffer should be not less than 16. + */ +int HMAC( const unsigned char * key + , unsigned int key_len + , const unsigned char * data + , unsigned long data_len + , unsigned char * digest); + +#endif diff --git a/include/clplumbing/mkstemp_mode.h b/include/clplumbing/mkstemp_mode.h new file mode 100644 index 0000000..ff5f893 --- /dev/null +++ b/include/clplumbing/mkstemp_mode.h @@ -0,0 +1,34 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * A slightly safer version of mkstemp(3) + * + * In this version, the file is initially created mode 0, (using umask) and + * then chmod-ed to the requested permissions after calling mkstemp(3). + * This guarantees that the file is not even momentarily open beyond the + * requested permissions. + * + * Return values: + * + * Like mkstemp, it returns the file descriptor of the open file, or -1 + * on error. + * + * In addition to the errno values documented for mkstemp(3), this functio + * can also fail with any of the errno values documented for chmod(2). + * + */ +int mkstemp_mode(char* template, mode_t requested_filemode); diff --git a/include/clplumbing/netstring.h b/include/clplumbing/netstring.h new file mode 100644 index 0000000..ef24e8f --- /dev/null +++ b/include/clplumbing/netstring.h @@ -0,0 +1,48 @@ +/* + * Intracluster message object (struct ha_msg) + * + * Copyright (C) 1999, 2000 Guochun Shi<gshi@unix.sh> + * This software licensed under the GNU LGPL. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef NET_STRING_H +#define NET_STRING_H +#include <stdlib.h> +#include <stdio.h> +#include <ha_msg.h> + +extern gboolean cl_msg_quiet_fmterr; + +/* Convert a message to netstring data */ +char* msg2netstring(const struct ha_msg*, size_t*); +char * msg2netstring_noauth(const struct ha_msg *m, size_t * slen); + +/* Convert netstring data to a message */ +struct ha_msg * netstring2msg(const char*, size_t, int); + +/* Is this netstring authentic? */ +int is_auth_netstring(const char* datap, size_t datalen, + const char* authstring, size_t authlen); + +void cl_set_authentication_computation_method(int (*method)(int authmethod +, const void * data +, size_t datalen +, char * authstr +, size_t authlen)); + +#endif diff --git a/include/clplumbing/proctrack.h b/include/clplumbing/proctrack.h new file mode 100644 index 0000000..975ff1b --- /dev/null +++ b/include/clplumbing/proctrack.h @@ -0,0 +1,120 @@ +/* + * Process tracking object. + * + * Copyright (c) 2002 International Business Machines + * Author: Alan Robertson <alanr@unix.sh> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _PROCTRACK_H +# define _PROCTRACK_H +#include <sys/types.h> +#include <sys/times.h> +#include <clplumbing/longclock.h> + +/* + * We track processes, mainly so we can do something appropriate + * when they die, and find processes should we need to kill them... + */ + +typedef struct _ProcTrack ProcTrack; +typedef struct _ProcTrack_ops ProcTrack_ops; +typedef struct _ProcTrackKillInfo ProcTrackKillInfo; + +/* + * The levels of logging possible for our process + */ +enum _ProcTrackLogType { + PT_LOGNONE = 2, /* Exits never automatically logged */ + PT_LOGNORMAL, /* Automatically log abnormal exits */ + PT_LOGVERBOSE /* Automatically log every exit */ +}; +typedef enum _ProcTrackLogType ProcTrackLogType; + +#define proctrack_pid(p) (p)->pid +#define proctrack_data(p) (p)->privatedata +#define reset_proctrack_data(p) (p)->privatedata = NULL +#define proctrack_timedout(p) ((p)->timeoutseq > 0) + +struct _ProcTrack { + pid_t pid; + int isapgrp; + ProcTrackLogType loglevel; + void * privatedata; + ProcTrack_ops* ops; + + longclock_t startticks; + TIME_T starttime; + unsigned timerid; + int timeoutseq; + ProcTrackKillInfo* killinfo; +}; + +/* + * The set of operations to perform on our tracked processes. + */ +struct _ProcTrack_ops { + + /* Called when a process dies */ + void (*procdied) + (ProcTrack* p, int status, int signo, int exitcode + , int waslogged); + + /* Called when a process registers */ + void (*procregistered) + (ProcTrack*p); + + /* Returns a "name" for a process (for messages) */ + /* (may have to be copied, because it may be a static value) */ + const char * + (*proctype) + (ProcTrack* p); +}; + +struct _ProcTrackKillInfo { + long mstimeout; /* Timeout in milliseconds */ + int signalno; /* Signal number to issue @ timeout */ +}; + +/* A function for calling by the process table iterator */ +typedef void (*ProcTrackFun) (ProcTrack* p, void * data); + +/* Call this function to activate the procdied member function */ +/* Returns TRUE if 'pid' was registered */ +int ReportProcHasDied(int pid, int status); + +/* Create/Log a new tracked process */ +void NewTrackedProc(pid_t pid, int isapgrp, ProcTrackLogType loglevel +, void * privatedata , ProcTrack_ops* ops); + +/* "info" is 0-terminated (terminated by a 0 signal) */ +int SetTrackedProcTimeouts(pid_t pid, ProcTrackKillInfo* info); +void RemoveTrackedProcTimeouts(pid_t pid); + +/* Return information associated with the given PID (or NULL) */ +ProcTrack* GetProcInfo(pid_t pid); + +/* + * Iterate over the set of tracked processes. + * If proctype is NULL, then walk through them all, otherwise only those + * of the given type ("f") + */ +void ForEachProc(ProcTrack_ops* proctype, ProcTrackFun f, void * data); + +void DisableProcLogging(void); /* Useful for shutdowns */ +void EnableProcLogging(void); +#endif diff --git a/include/clplumbing/realtime.h b/include/clplumbing/realtime.h new file mode 100644 index 0000000..45eb76c --- /dev/null +++ b/include/clplumbing/realtime.h @@ -0,0 +1,65 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_REALTIME_H +# define _CLPLUMBING_REALTIME_H +# include <sched.h> + +#if defined(SCHED_RR) && defined(_POSIX_PRIORITY_SCHEDULING) && !defined(ON_DARWIN) +# define DEFAULT_REALTIME_POLICY SCHED_RR +#endif + +/* + * + * make_realtime() will make the current process a soft realtime process + * and lock it into memory after growing the heap by heapgrowK*1024 bytes + * + * If you set spolicy or priority to <= 0, then defaults will be used. + * Otherwise you need to use a value for spolicy from <sched.h> + * and use an appropriate priority for the given spolicy. + * + * WARNING: badly behaved programs which use the make_realtime() function + * can easily hang the machine. + */ + +void cl_make_realtime +( int spolicy, /* SCHED_RR or SCHED_FIFO (or SCHED_OTHER) */ + int priority, /* typically 1-99 */ + int stackgrowK, /* Amount to grow stack by */ + int heapgrowK /* Amount to grow heap by */ +); + +void cl_make_normaltime(void); + +/* Cause calls to make_realtime() to be ignored */ +void cl_disable_realtime(void); + +/* Cause calls to make_realtime() to be accepted. + * This is the default behaviour */ +void cl_enable_realtime(void); + +/* Sleep a really short (the shortest) time */ +int cl_shortsleep(void); + +/* Print messages if we've done (more) non-realtime mallocs */ +void cl_realtime_malloc_check(void); + +/* Number of times we "go to the well" for memory after becoming realtime */ +int cl_nonrealtime_malloc_count(void); +/* Number of bytes we "got from the well" for memory after becoming realtime */ +unsigned long cl_nonrealtime_malloc_size(void); + +#endif diff --git a/include/clplumbing/replytrack.h b/include/clplumbing/replytrack.h new file mode 100644 index 0000000..f98fe48 --- /dev/null +++ b/include/clplumbing/replytrack.h @@ -0,0 +1,208 @@ +/* + * Process tracking object. + * + * Copyright (c) 2007 Alan Robertson + * Author: Alan Robertson <alanr@unix.sh> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef _REPLYTRACK_H +# define _REPLYTRACK_H +#include <sys/types.h> +#include <sys/times.h> +#include <clplumbing/longclock.h> +#include <clplumbing/cl_uuid.h> + +/* + * We track replies - so we can tell when all expected replies were received. + * + * There is a problem in clusters where a message is sent to each node, and a + * reply is expected from each node of knowing when all the replies have been + * received. + * + * If all nodes are up, it's easy to see when all replies are received. + * But, if some nodes are down, we really don't want to wait for a timeout + * before we decide that we've gotten all the replies we're going to get, + * since nodes can be down for potentially very long periods of time, and + * waiting for a long timeout can delay things a great deal again and + * again - causing significant delays and user frustration. + * + * That's where these functions come in! + * Instead, inform these functions what nodes are up and what ones are down, + * and when you receive a reply, and it will tell you when you've gotten + * them all - managing all that tedious bookwork for you. + */ + +typedef enum _replytrack_completion_type replytrack_completion_type_t; +typedef enum _nodetrack_change nodetrack_change_t; +typedef struct _replytrack replytrack_t; +typedef struct _nodetrack nodetrack_t; +typedef struct _nodetrack_intersection nodetrack_intersection_t; + +/* + * The levels of logging possible for our process + */ +enum _replytrack_completion_type { + REPLYT_ALLRCVD = 2, /* All replies received */ + REPLYT_TIMEOUT, /* Timeout occurred with replies missing */ +}; + + +typedef void (*replytrack_callback_t) +( replytrack_t * rl +, gpointer user_data +, replytrack_completion_type_t reason); + +typedef void (*replytrack_iterator_t) +( replytrack_t* rl +, gpointer user_data +, const char* node +, cl_uuid_t uuid); + +typedef void (*nodetrack_iterator_t) +( nodetrack_t* rl +, gpointer user_data +, const char* node +, cl_uuid_t uuid); + + +/* + * Note: + * If you use the timeout feature of this code, it relies on you using glib mainloop + * for your scheduling. timeout_ms should be zero for no timeout. + */ +replytrack_t* replytrack_new(nodetrack_t* membership +, replytrack_callback_t callback +, unsigned long timeout_ms +, gpointer user_data); + +void replytrack_del(replytrack_t *rl); +gboolean replytrack_gotreply(replytrack_t *rl +, const char * node +, cl_uuid_t uuid); + /* Returns TRUE if this was the final expected reply */ +/* + * Iterate over the set of outstanding replies: + * return count of how many items in the iteration + */ +int replytrack_outstanding_iterate(replytrack_t* rl +, replytrack_iterator_t i, gpointer user_data); +int replytrack_outstanding_count(replytrack_t* rl); + +/* + * The functions above operate using a view of membership which is established + * through the functions below. + * + * This can either be through the heartbeat low-level membership API, or any + * other view of membership you wish. Mentioning a node as either up or down + * will automatically add that node to our view of potential membership. + * + * These functions only support one view of membership per process. + * + * The general idea of how to use these functions: + * Initially: + * 1) iterate through init membership and call nodetrack_node(up|down) for + * each node to start things off. + * + * On an ongoing basis: + * 2) call nodetrack_node_up whenever a node comes up + * We expect a reply from nodes that are up. + * 3) call nodetrack_node_down whenever a node goes down + * We don't expect a reply from nodes that are down. + * + * For each set of replies you want tracked: + * 4) Create a replytrack_t for a set of expected replies + * 5) call replytrack_gotreply() each time you get an expected reply + * 6) replist_gotreply() returns TRUE when the final message was received. + * (it does this by comparing against the membership as defined below) + * 7) you will get a callback when timeout occurs or final message is received + * n. b.: + * No callback function => manage timeouts yourself + * 8) call replytrack_del() when you're done with the reply list + * n. b.: + * If you have replies outstanding, and you have a timeout and + * a callback function set, you will get a warning for destroying + * a replytrack_t object 'prematurely'. + * You will also log a warning if you call replytrack_gotreply() after + * all replies were received or a timeout occurred. + * + */ + +/* + * The levels of logging possible for our process + */ +enum _nodetrack_change { + NODET_UP = 2, /* This node came up */ + NODET_DOWN, /* This node went down */ +}; + +typedef void (*nodetrack_callback_t) +( nodetrack_t * mbr +, const char * node +, cl_uuid_t u +, nodetrack_change_t reason +, gpointer user_data); + +nodetrack_t* nodetrack_new(nodetrack_callback_t callback +, gpointer user_data); +void nodetrack_del(nodetrack_t*); +gboolean nodetrack_nodeup(nodetrack_t* mbr, const char * node +, cl_uuid_t u); +gboolean nodetrack_nodedown(nodetrack_t* mbr, const char * node +, cl_uuid_t u); +gboolean nodetrack_ismember(nodetrack_t* mbr, const char * node +, cl_uuid_t u); +int nodetrack_iterate(nodetrack_t* mbr +, nodetrack_iterator_t i, gpointer user_data); + +/* An intesection nodetrack table + * A node is put into the "intersection" nodetrack_t table when it is in all + * the underlying constituent nodetrack_t tables, and removed when it is + * removed from any of them. + * Note that you can set a callback to be informed when these "intersection" + * membership changes occur. + */ +nodetrack_intersection_t* + nodetrack_intersection_new(nodetrack_t** tables, int ntables +, nodetrack_callback_t callback, gpointer user_data); +void nodetrack_intersection_del(nodetrack_intersection_t*); +nodetrack_t* nodetrack_intersection_table(nodetrack_intersection_t*); + +#if 0 +/* + * I don't know if this should be in this library, or just in + * the CCM. Probably only the CCM _should_ be using it (when I write it) + */ +/* + * Use of the nodetrack_hb_* functions implies you're using the heartbeat + * peer-connectivity information as your source of information. This is + * really only suitable if you're using heartbeat's low-level group membership + * for your source of who to expect replies from. + * If you're using nodetrack_hb_init, this replaces step (1) above. + */ +void nodetrack_hb_init(void) +/* + * If you're using nodetrack_hb_statusmsg, just pass it all status messages + * and all peer-connectivity status messages or even all heartbeat messages + * (non-status messages will be ignored). + * This replaces steps (2) and (3) above _if_ you're using heartbeat low + * level membership for your source of who to expect replies from. + */ +void nodetrack_hb_statusmsg(struct ha_msg* statusmsg); +#endif /*0*/ + +#endif diff --git a/include/clplumbing/setproctitle.h b/include/clplumbing/setproctitle.h new file mode 100644 index 0000000..5caeef0 --- /dev/null +++ b/include/clplumbing/setproctitle.h @@ -0,0 +1,64 @@ +/* + * setproctitle.h + * + * The code in this file, setproctitle.h is heavily based on code from + * proftpd, please see the licening information below. + * + * This file added to the heartbeat tree by Horms <horms@vergenet.net> + * + * Code to portably change the title of a programme as displayed + * by ps(1). + * + * heartbeat: Linux-HA heartbeat code + * + * Copyright (C) 1999,2000,2001 Alan Robertson <alanr@unix.sh> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * ProFTPD - FTP server daemon + * Copyright (c) 1997, 1998 Public Flood Software + * Copyright (C) 1999, 2000 MacGyver aka Habeeb J. Dihu <macgyver@tos.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + * + * As a special exemption, Public Flood Software/MacGyver aka Habeeb J. Dihu + * and other respective copyright holders give permission to link this program + * with OpenSSL, and distribute the resulting executable, without including + * the source code for OpenSSL in the source distribution. + */ + +#ifndef _HA_SETPROCTITLE_H +#define _HA_SETPROCTITLE_H + +#include <glib.h> +int init_set_proc_title(int argc, char *argv[], char *envp[]); + +void set_proc_title(const char *fmt,...) G_GNUC_PRINTF(1,2); + +#endif /* _HA_SETPROCTITLE_H */ diff --git a/include/clplumbing/timers.h b/include/clplumbing/timers.h new file mode 100644 index 0000000..669ac21 --- /dev/null +++ b/include/clplumbing/timers.h @@ -0,0 +1,23 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef _CLPLUMBING_TIMERS_H +# define _CLPLUMBING_TIMERS_H +int setmsrepeattimer(long ms); +int setmsalarm(long ms); +int cancelmstimer(void); +long mssleep(long ms); +#endif diff --git a/include/clplumbing/uids.h b/include/clplumbing/uids.h new file mode 100644 index 0000000..89ba303 --- /dev/null +++ b/include/clplumbing/uids.h @@ -0,0 +1,32 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CLPLUMBING_UIDS_H +# define CLPLUMBING_UIDS_H +#include <sys/types.h> + +/* Tell us who you want to be - or zero for nobody */ +int drop_privs(uid_t uid, gid_t gid); + +/* Return to original privileged state */ +int return_to_orig_privs(void); + +/* Drop down to (probably nobody) privileges again */ +int return_to_dropped_privs(void); + +/* Return TRUE if we have full privileges at the moment */ +int cl_have_full_privs(void); +#endif |