[sheepdog] [PATCH 2/2] sheep: rotate log with SIGHUP

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Fri Oct 18 13:54:34 CEST 2013


Current sheep process rotates log when the log file reaches its
maximum size (500MB). But it is not comfortable for periodical backup
of log files.

Rotating log with catching SIGHUP is a common behavior of unix
processes. This patch implements the behavior in sheep daemon.

Example of rog lotation:
$ sudo sheep -P /tmp/sheep/sheep.pid -c local /tmp/sheep
$ sudo kill -SIGHUP `sudo cat /tmp/sheep/sheep.pid`

Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 CHANGELOG.md     |    1 +
 include/logger.h |    2 ++
 lib/logger.c     |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 sheep/sheep.c    |   11 +++++++++++
 4 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 83ec887..1a2e20d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,3 +13,4 @@ DOG COMMAND INTERFACE:
 SHEEP COMMAND INTERFACE:
  - improvements of help messages
  - change format of the size format in -j (journaling) and -w (object cache) options. The new format is: n[TtGgMmKkb]. e.g. "-j size=1024M".
+ - rotate log when sheep process catches SIGHUP signal
diff --git a/include/logger.h b/include/logger.h
index 3f9292d..a86c369 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -90,4 +90,6 @@ void sd_backtrace(void);
 void set_loglevel(int new_loglevel);
 int get_loglevel(void);
 
+extern pid_t logger_pid;
+
 #endif	/* LOG_H */
diff --git a/lib/logger.c b/lib/logger.c
index bf1a605..4ee3027 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -114,12 +114,39 @@ static const char *log_name;
 static char *log_nowname;
 int sd_log_level = SDOG_INFO;
 static pid_t sheep_pid;
-static pid_t logger_pid;
+pid_t logger_pid = -1;
 static key_t semkey;
 static char *log_buff;
 
 static int64_t max_logsize = 500 * 1024 * 1024;  /*500MB*/
 
+static void block_sighup(void)
+{
+	/* this function is used for protecting log_fd */
+	int ret;
+	sigset_t new, old;
+
+	sigemptyset(&new);
+	sigemptyset(&old);
+	sigaddset(&new, SIGHUP);
+	ret = sigprocmask(SIG_BLOCK, &new, &old);
+	if (ret < 0)
+		syslog(LOG_ERR, "blocking SIGHUP failed\n");
+}
+
+static void unblock_sighup(void)
+{
+	int ret;
+	sigset_t new, old;
+
+	sigemptyset(&new);
+	sigemptyset(&old);
+	sigaddset(&new, SIGHUP);
+	ret = sigprocmask(SIG_UNBLOCK, &new, &old);
+	if (ret < 0)
+		syslog(LOG_ERR, "unblock SIGHUP failed\n");
+}
+
 static const char *format_thread_name(char *str, size_t size, const char *name,
 				      int idx)
 {
@@ -328,10 +355,15 @@ static void log_syslog(const struct logmsg *msg)
 
 	len = format->formatter(str, sizeof(str) - 1, msg);
 	str[len++] = '\n';
+
+	block_sighup();
+
 	if (log_fd >= 0)
 		xwrite(log_fd, str, len);
 	else
 		syslog(msg->prio, "%s", str);
+
+	unblock_sighup();
 }
 
 static void init_logmsg(struct logmsg *msg, struct timeval *tv,
@@ -507,6 +539,22 @@ static void crash_handler(int signo)
 	reraise_crash_signal(signo, 1);
 }
 
+static void sighup_handler(int signo)
+{
+	if (getppid() == 1)
+		/*
+		 * My parent (sheep process) is dead. This SIGHUP is sent
+		 * because of prctl(PR_SET_PDEATHSIG, SIGHUP)
+		 */
+		return crash_handler(signo);
+
+	/*
+	 * My parent sheep process is still alive, this SIGHUP is a request
+	 * for log rotation.
+	*/
+	rotate_log();
+}
+
 static void logger(char *log_dir, char *outfile)
 {
 	int fd;
@@ -537,7 +585,7 @@ static void logger(char *log_dir, char *outfile)
 
 	/* flush when either the logger or its parent dies */
 	install_crash_handler(crash_handler);
-	install_sighandler(SIGHUP, crash_handler, false);
+	install_sighandler(SIGHUP, sighup_handler, false);
 
 	prctl(PR_SET_PDEATHSIG, SIGHUP);
 
@@ -551,6 +599,8 @@ static void logger(char *log_dir, char *outfile)
 	while (la->active) {
 		log_flush();
 
+		block_sighup();
+
 		if (max_logsize) {
 			off_t offset;
 
@@ -564,6 +614,8 @@ static void logger(char *log_dir, char *outfile)
 			}
 		}
 
+		unblock_sighup();
+
 		sleep(1);
 	}
 
diff --git a/sheep/sheep.c b/sheep/sheep.c
index c73d0f9..f7766fb 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -526,6 +526,15 @@ end:
 	return status;
 }
 
+static void sighup_handler(int signum)
+{
+	if (unlikely(logger_pid == -1))
+		return;
+
+	/* forward SIGHUP for log rotating */
+	kill(logger_pid, SIGHUP);
+}
+
 int main(int argc, char **argv)
 {
 	int ch, longindex, ret, port = SD_LISTEN_PORT, io_port = SD_LISTEN_PORT;
@@ -543,6 +552,8 @@ int main(int argc, char **argv)
 	install_crash_handler(crash_handler);
 	signal(SIGPIPE, SIG_IGN);
 
+	install_sighandler(SIGHUP, sighup_handler, false);
+
 	long_options = build_long_options(sheep_options);
 	short_options = build_short_options(sheep_options);
 	while ((ch = getopt_long(argc, argv, short_options, long_options,
-- 
1.7.10.4




More information about the sheepdog mailing list