Here's a patch for review that changes fenced to use the logsys api I posted earlier. It also includes some other minor changes related to ccs and cman setup. Untested, and can't be commited until the logsys api is official.
commit 1ccaf002a5989a22cb14fde4dfc3d13260f6316f Author: David Teigland <[EMAIL PROTECTED]> Date: Wed Jun 25 15:56:34 2008 -0500 fenced: use logsys - Setup ccs connection once at the start and keep it open. - Read logging configuration from ccs. - Replace calls to syslog with calls to logsys. - Direct debug statements to logsys. - cman setup uses cman_is_active - cman setup retries cman_init and cman_is_active Signed-off-by: David Teigland <[EMAIL PROTECTED]> diff --git a/fence/fenced/Makefile b/fence/fenced/Makefile index 1e9bbc9..61ec989 100644 --- a/fence/fenced/Makefile +++ b/fence/fenced/Makefile @@ -15,7 +15,8 @@ OBJS= config.o \ group.o \ main.o \ member_cman.o \ - recover.o + recover.o \ + logging.o CFLAGS += -D_FILE_OFFSET_BITS=64 CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${fenceincdir} -I${openaisincdir} diff --git a/fence/fenced/config.c b/fence/fenced/config.c index 56b7b0e..f2a8372 100644 --- a/fence/fenced/config.c +++ b/fence/fenced/config.c @@ -1,7 +1,9 @@ #include "fd.h" #include "ccs.h" -static int open_ccs(void) +static int ccs_handle; + +int setup_ccs(void) { int i = 0, cd; @@ -9,18 +11,62 @@ static int open_ccs(void) sleep(1); if (++i > 9 && !(i % 10)) log_error("connect to ccs error %d, " - "check ccsd or cluster status", cd); + "check cluster status", cd); + + /* FIXME: do we want this infinite? */ + if (i > 10) + break; } - return cd; + + if (cd < 0) + return cd; + + ccs_handle = cd; + return 0; +} + +void read_ccs_name(char *path, char *name) +{ + char *str; + int error; + + error = ccs_get(ccs_handle, path, &str); + if (error || !str) + return; + + strcpy(name, str); + + free(str); +} + +void read_ccs_yesno(char *path, int *yes, int *no) +{ + char *str; + int error; + + *yes = 0; + *no = 0; + + error = ccs_get(ccs_handle, path, &str); + if (error || !str) + return; + + if (!strcmp(str, "yes")) + *yes = 1; + + else if (!strcmp(str, "no")) + *no = 1; + + free(str); } -static void read_ccs_int(int cd, char *path, int *config_val) +void read_ccs_int(char *path, int *config_val) { char *str; int val; int error; - error = ccs_get(cd, path, &str); + error = ccs_get(ccs_handle, path, &str); if (error || !str) return; @@ -48,11 +94,8 @@ int read_ccs(struct fd *fd) { char path[256]; char *str; - int error, cd, i = 0, count = 0; - - cd = open_ccs(); - if (cd < 0) - return cd; + int error, i = 0, count = 0; + int cd = ccs_handle; /* Our own nodename must be in cluster.conf before we're allowed to join the fence domain and then mount gfs; other nodes need this to @@ -122,7 +165,6 @@ int read_ccs(struct fd *fd) log_debug("added %d nodes from ccs", count); out: - ccs_disconnect(cd); return 0; } diff --git a/fence/fenced/fd.h b/fence/fenced/fd.h index 5ef1756..c74da54 100644 --- a/fence/fenced/fd.h +++ b/fence/fenced/fd.h @@ -10,7 +10,6 @@ #include <errno.h> #include <string.h> #include <stdint.h> -#include <syslog.h> #include <time.h> #include <sched.h> #include <sys/ioctl.h> @@ -24,6 +23,7 @@ #include <openais/saAis.h> #include <openais/cpg.h> +#include <openais/service/logsys.h> #include "list.h" #include "linux_endian.h" @@ -58,6 +58,7 @@ #define GROUP_LIBCPG 3 extern int daemon_debug_opt; +extern int daemon_debug_logsys; extern int daemon_quit; extern struct list_head domains; extern int cman_quorate; @@ -74,14 +75,17 @@ extern void daemon_dump_save(void); #define log_debug(fmt, args...) \ do { \ snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \ - if (daemon_debug_opt) fprintf(stderr, "%s", daemon_debug_buf); \ daemon_dump_save(); \ + if (daemon_debug_opt) \ + fprintf(stderr, "%s", daemon_debug_buf); \ + if (daemon_debug_logsys) \ + log_printf(LOG_DEBUG, "%s", daemon_debug_buf); \ } while (0) #define log_error(fmt, args...) \ do { \ log_debug(fmt, ##args); \ - syslog(LOG_ERR, fmt, ##args); \ + log_printf(LOG_ERR, fmt, ##args); \ } while (0) /* config option defaults */ @@ -210,6 +214,10 @@ struct fd { /* config.c */ +int setup_ccs(void); +void read_ccs_name(char *path, char *name); +void read_ccs_yesno(char *path, int *yes, int *no); +void read_ccs_int(char *path, int *config_val); int read_ccs(struct fd *fd); /* cpg.c */ @@ -266,5 +274,10 @@ void delay_fencing(struct fd *fd, int node_join); void defer_fencing(struct fd *fd); void fence_victims(struct fd *fd); +/* logging.c */ + +int init_logging(void); +int setup_logging(int *prog_debug); + #endif /* __FD_DOT_H__ */ diff --git a/fence/fenced/logging.c b/fence/fenced/logging.c new file mode 100644 index 0000000..6d09839 --- /dev/null +++ b/fence/fenced/logging.c @@ -0,0 +1,153 @@ +#include "fd.h" + +#define DEFAULT_MODE LOG_MODE_OUTPUT_SYSLOG_THREADED +#define DEFAULT_FACILITY LOG_DAEMON +#define DEFAULT_PRIORITY LOG_LEVEL_ERROR +#define DEFAULT_FILE NULL + +#define LEVEL_PATH "/cluster/logging/[EMAIL PROTECTED]"FENCED\"]/@syslog_level" +#define DEBUG_PATH "/cluster/logging/[EMAIL PROTECTED]"FENCED\"]/@debug" + +/* Read cluster.conf settings and convert them into logsys values. + If no cluster.conf setting exists, the default that was used in + logsys_init() is used. + + mode from + "/cluster/logging/@to_stderr" + "/cluster/logging/@to_syslog" + "/cluster/logging/@to_file" + + facility from + "/cluster/logging/@syslog_facility" + + priority from + "/cluster/logging/[EMAIL PROTECTED]"prog_name\"]/@syslog_level" + + file from + "/cluster/logging/@filename" + + debug from + "/cluster/logging/[EMAIL PROTECTED]"prog_name\"]/@debug" +*/ + +static int read_ccs_logging(int *mode, int *facility, int *priority, char *file, + int *debug) +{ + char name[PATH_MAX]; + int val, y, n; + int m = 0, f = 0, p = 0; + + /* + * defaults + */ + + *mode = DEFAULT_MODE; + *facility = DEFAULT_FACILITY; + *priority = DEFAULT_PRIORITY; + if (DEFAULT_FILE) + strcpy(file, DEFAULT_FILE); + + /* + * mode + */ + + read_ccs_yesno("/cluster/logging/@to_stderr", &y, &n); + if (y) + m |= LOG_MODE_OUTPUT_STDERR; + + read_ccs_yesno("/cluster/logging/@to_syslog", &y, &n); + if (y) + m |= LOG_MODE_OUTPUT_SYSLOG_THREADED; + + read_ccs_yesno("/cluster/logging/@to_file", &y, &n); + if (y) + m |= LOG_MODE_OUTPUT_FILE; + + if (!m) + goto facil; + + *mode = m; + + /* + * facility + */ + facil: + memset(name, 0, sizeof(name)); + read_ccs_name("/cluster/logging/@syslog_facility", name); + + if (!name[0]) + goto prior; + + f = logsys_facility_get(name); + if (f < 0) + goto prior; + + *facility = f; + + /* + * priority + */ + prior: + read_ccs_int(LEVEL_PATH, &val); + if (!val) + goto dofile; + + p = logsys_priority_id_get(val); + if (p < 0) + goto dofile; + + *priority = p; + + /* + * file + */ + dofile: + memset(name, 0, sizeof(name)); + read_ccs_name("/cluster/logging/@filename", name); + + if (!name[0]) + goto deb; + + strcpy(file, name); + + /* + * debug + */ + deb: + memset(name, 0, sizeof(name)); + read_ccs_name("/cluster/logging/@debug", name); + + if (!strcmp(name, "on")) + *debug = 1; + + memset(name, 0, sizeof(name)); + read_ccs_name(DEBUG_PATH, name); + + if (!strcmp(name, "on")) + *debug = 1; + + return 0; +} + +/* initial settings until we can read cluster.conf logging settings from ccs */ + +void init_logging(void) +{ + logsys_init("fenced", LOG_MODE_OUTPUT_SYSLOG_THREADED, LOG_DAEMON, + LOG_LEVEL_ERROR, NULL); +} + +/* this function is also called when we get a cman config-update event */ + +void setup_logging(int *prog_debug) +{ + int mode, facility, priority; + char file[PATH_MAX]; + + /* The debug setting is special, it's used by the program + and not used to configure logsys. */ + + read_ccs_logging(&mode, &facility, &priority, file, prog_debug); + logsys_conf("fenced", mode, facility, priority, file); +} + diff --git a/fence/fenced/main.c b/fence/fenced/main.c index 83ca075..0a8c10c 100644 --- a/fence/fenced/main.c +++ b/fence/fenced/main.c @@ -619,6 +619,12 @@ static int loop(void) goto out; client_add(rv, process_cman, cluster_dead); + rv = setup_ccs(); + if (rv < 0) + goto out; + + setup_logging(&daemon_debug_logsys); + group_mode = GROUP_LIBCPG; if (comline.groupd_compat) { @@ -852,6 +858,8 @@ int main(int argc, char **argv) comline.override_time = DEFAULT_OVERRIDE_TIME; comline.override_path = strdup(DEFAULT_OVERRIDE_PATH); + init_logging(); + read_arguments(argc, argv); lockfile(); @@ -863,7 +871,6 @@ int main(int argc, char **argv) } umask(0); } - openlog("fenced", LOG_PID, LOG_DAEMON); signal(SIGTERM, sigterm_handler); set_oom_adj(-16); @@ -888,6 +895,7 @@ void daemon_dump_save(void) } int daemon_debug_opt; +int daemon_debug_logsys; int daemon_quit; struct list_head domains; int cman_quorate; diff --git a/fence/fenced/member_cman.c b/fence/fenced/member_cman.c index e85fcb6..1cc409a 100644 --- a/fence/fenced/member_cman.c +++ b/fence/fenced/member_cman.c @@ -122,6 +122,10 @@ static void cman_callback(cman_handle_t h, void *private, int reason, int arg) if (!quorate && cman_quorate && (group_mode == GROUP_LIBCPG)) process_fd_changes(); break; + + case CMAN_REASON_CONFIG_UPDATE: + setup_logging(&daemon_debug_logsys); + break; } } @@ -140,10 +144,28 @@ int setup_cman(void) { cman_node_t node; int rv, fd; + int init = 0, active = 0; + retry_init: ch = cman_init(NULL); if (!ch) { - log_error("cman_init error %p %d", ch, errno); + if (init++ < 2) { + sleep(1); + goto retry_init; + } + log_error("cman_init error %d", errno); + return -ENOTCONN; + } + + retry_active: + rv = cman_is_active(ch); + if (!rv) { + if (active++ < 2) { + sleep(1); + goto retry_active; + } + log_error("cman_is_active error %d", errno); + cman_finish(ch); return -ENOTCONN; } diff --git a/fence/fenced/recover.c b/fence/fenced/recover.c index 21bf735..e3bf7e1 100644 --- a/fence/fenced/recover.c +++ b/fence/fenced/recover.c @@ -116,7 +116,7 @@ static int check_override(int ofd, char *nodename, int timeout) ret = select(ofd + 1, &rfds, NULL, NULL, &tv); if (ret < 0) { - syslog(LOG_ERR, "select: %s\n", strerror(errno)); + log_printf(LOG_ERR, "select: %s\n", strerror(errno)); return -1; } @@ -126,7 +126,7 @@ static int check_override(int ofd, char *nodename, int timeout) memset(buf, 0, sizeof(buf)); ret = read(ofd, buf, sizeof(buf) - 1); if (ret < 0) { - syslog(LOG_ERR, "read: %s\n", strerror(errno)); + log_printf(LOG_ERR, "read: %s\n", strerror(errno)); return -1; } @@ -212,8 +212,8 @@ void delay_fencing(struct fd *fd, int node_join) (int) (last.tv_sec - first.tv_sec), victim_count); out: list_for_each_entry(node, &fd->victims, list) { - syslog(LOG_INFO, "%s not a cluster member after %d sec %s", - node->name, delay, delay_type); + log_printf(LOG_INFO, "%s not a cluster member after %d sec %s", + node->name, delay, delay_type); } } @@ -227,7 +227,7 @@ void defer_fencing(struct fd *fd) master_name = nodeid_to_name(fd->master); log_debug("defer fencing to %d %s", fd->master, master_name); - syslog(LOG_INFO, "fencing deferred to %s", master_name); + log_printf(LOG_INFO, "fencing deferred to %s", master_name); } void fence_victims(struct fd *fd) @@ -258,13 +258,13 @@ void fence_victims(struct fd *fd) } log_debug("fencing node %s", node->name); - syslog(LOG_INFO, "fencing node \"%s\"", node->name); + log_printf(LOG_INFO, "fencing node \"%s\"", node->name); query_unlock(); error = fence_node(node->name); query_lock(); - syslog(LOG_INFO, "fence \"%s\" %s", node->name, + log_printf(LOG_INFO, "fence \"%s\" %s", node->name, error ? "failed" : "success"); if (!error) { @@ -286,8 +286,8 @@ void fence_victims(struct fd *fd) override = open_override(comline.override_path); if (check_override(override, node->name, comline.override_time) > 0) { - syslog(LOG_WARNING, "fence \"%s\" overridden by " - "administrator intervention", node->name); + log_printf(LOG_WARNING, "fence \"%s\" overridden by " + "administrator intervention", node->name); victim_done(fd, node->nodeid, VIC_DONE_OVERRIDE); list_del(&node->list); free(node);