[Cluster-devel] fenced logsys/cman/ccs setup

David Teigland teigland at redhat.com
Tue Jul 1 21:28:45 UTC 2008


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 <teigland at redhat.com>
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 <teigland at redhat.com>

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/logger_subsys[@subsys=\"FENCED\"]/@syslog_level"
+#define DEBUG_PATH "/cluster/logging/logger_subsys[@subsys=\"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/logger_subsys[@subsys=\"prog_name\"]/@syslog_level"
+
+   file from
+   "/cluster/logging/@filename"
+
+   debug from
+   "/cluster/logging/logger_subsys[@subsys=\"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);




More information about the Cluster-devel mailing list