[sheepdog-users] [PATCH stable-0.7 2/5] sheep: rotate log with SIGHUP

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Thu Dec 12 10:46:42 CET 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>
Signed-off-by: Liu Yuan <namei.unix at gmail.com>

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

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 987d2f5..157cf12 100644
--- a/lib/logger.c
+++ b/lib/logger.c
@@ -120,12 +120,43 @@ 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*/
 
+/*
+ * block_sighup()
+ *
+ * used for protecting log_fd from SIGHUP rotation
+ */
+static void block_sighup(void)
+{
+	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)
 {
@@ -324,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,
@@ -503,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;
@@ -533,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);
 
@@ -547,6 +599,8 @@ static void logger(char *log_dir, char *outfile)
 	while (la->active) {
 		log_flush();
 
+		block_sighup();
+
 		if (max_logsize) {
 			off_t offset;
 
@@ -560,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 61d7f76..d3192fc 100644
--- a/sheep/sheep.c
+++ b/sheep/sheep.c
@@ -570,6 +570,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;
@@ -587,6 +596,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-users mailing list