[sheepdog] [PATCH] sheep, logger: select log formatter before log_init()

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Fri Feb 1 07:41:07 CET 2013


sd_printf() series can be called before calling log_init(). In such a
case, segmentation faults can be rised because format in logger.c is
NULL.
e.g. init_path() calls sd_eprintf() before log_init() when it fails
creating directory for sheep process.

This patch adds new function select_log_formatter(). This is only for
selecting formatter and should be called before sd_printf() series.
After applying this patch, sheep calls this function in the loop for
parsing command line options.

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 include/logger.h |    3 ++-
 lib/logger.c     |   28 ++++++++++++++++++++--------
 sheep/sheep.c    |   13 +++++++++----
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/include/logger.h b/include/logger.h
index eac4655..309b484 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -21,8 +21,9 @@
 #define MAX_MSG_SIZE 256
 #define MAX_THREAD_NAME_LEN	20
 
+void select_log_formatter(const char *format_name);
 int log_init(const char *progname, int size, bool to_stdout, int level,
-	char *outfile, const char *format_name);
+	char *outfile);
 void log_close(void);
 void dump_logmsg(void *);
 void log_write(int prio, const char *func, int line, const char *fmt, ...)
diff --git a/lib/logger.c b/lib/logger.c
index 0f5d857..c41c90a 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -499,18 +499,30 @@ static notrace void logger(char *log_dir, char *outfile)
 	exit(0);
 }
 
-notrace int log_init(const char *program_name, int size, bool to_stdout,
-		int level, char *outfile, const char *format_name)
+void select_log_formatter(const char *format_name)
 {
-	char log_dir[PATH_MAX], tmp[PATH_MAX];
+	struct log_format *f;
+
+	list_for_each_entry(f, &log_formats, list) {
+		if (!strcmp(f->name, format_name)) {
+			format = f;
+			return;
+		}
+	}
 
-	list_for_each_entry(format, &log_formats, list) {
-		if (!strcmp(format->name, format_name))
-			goto format_found;
+	fprintf(stderr, "invalid log format: %s\n", format_name);
+	fprintf(stderr, "valid options are:\n");
+	list_for_each_entry(f, &log_formats, list) {
+		fprintf(stderr, "\t%s\n", f->name);
 	}
 
-	panic("invalid format: %s\n", format_name);
-format_found:
+	exit(1);
+}
+
+notrace int log_init(const char *program_name, int size, bool to_stdout,
+		int level, char *outfile)
+{
+	char log_dir[PATH_MAX], tmp[PATH_MAX];
 
 	log_level = level;
 
diff --git a/sheep/sheep.c b/sheep/sheep.c
index 0068c5a..c41faca 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -431,7 +431,7 @@ int main(int argc, char **argv)
 	int64_t zone = -1, free_space = 0;
 	struct cluster_driver *cdrv;
 	struct option *long_options;
-	const char *log_format = "default";
+	bool log_format_selected = false;
 
 	signal(SIGPIPE, SIG_IGN);
 
@@ -568,13 +568,18 @@ int main(int argc, char **argv)
 			exit(0);
 			break;
 		case 'F':
-			log_format = optarg;
+			select_log_formatter(optarg);
+			log_format_selected = true;
 			break;
 		default:
 			usage(1);
 			break;
 		}
 	}
+
+	if (!log_format_selected)
+		select_log_formatter("default");
+
 	if (nr_vnodes == 0) {
 		sys->gateway_only = true;
 		sys->disk_space = 0;
@@ -600,8 +605,8 @@ int main(int argc, char **argv)
 	if (is_daemon && daemon(0, 0))
 		exit(1);
 
-	ret = log_init(program_name, LOG_SPACE_SIZE, to_stdout, log_level, path,
-		log_format);
+	ret = log_init(program_name, LOG_SPACE_SIZE, to_stdout, log_level,
+		path);
 	if (ret)
 		exit(1);
 
-- 
1.7.2.5




More information about the sheepdog mailing list