server: improve pidfile and log handling
authorJens Axboe <axboe@kernel.dk>
Mon, 10 Oct 2011 17:51:26 +0000 (19:51 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 10 Oct 2011 17:51:26 +0000 (19:51 +0200)
Signed-off-by: Jens Axboe <axboe@kernel.dk>
log.c
log.h
server.c
server.h

diff --git a/log.c b/log.c
index a16baafc97846f68e08b1d466eff67ed130b24ae..af974f85b594abc1951b4bfb77ad625f4887b529 100644 (file)
--- a/log.c
+++ b/log.c
@@ -21,6 +21,16 @@ int log_valist(const char *str, va_list args)
        return len;
 }
 
+int log_local_buf(const char *buf, size_t len)
+{
+       if (log_syslog)
+               syslog(LOG_INFO, "%s", buf);
+       else
+               len = fwrite(buf, len, 1, f_out);
+
+       return len;
+}
+
 int log_local(const char *format, ...)
 {
        char buffer[1024];
@@ -51,7 +61,10 @@ int log_info(const char *format, ...)
 
        if (is_backend)
                return fio_server_text_output(buffer, len);
-       else
+       else if (log_syslog) {
+               syslog(LOG_INFO, "%s", buffer);
+               return len;
+       } else
                return fwrite(buffer, len, 1, f_out);
 }
 
@@ -67,7 +80,10 @@ int log_err(const char *format, ...)
 
        if (is_backend)
                return fio_server_text_output(buffer, len);
-       else {
+       else if (log_syslog) {
+               syslog(LOG_INFO, "%s", buffer);
+               return len;
+       } else {
                if (f_err != stderr) {
                        int fio_unused ret;
 
diff --git a/log.h b/log.h
index a69846efd7a5721fd8af10592ef73ad5e0c3e7bd..fdf3d7b19aed3d3981b166c32339fbd7bb596f79 100644 (file)
--- a/log.h
+++ b/log.h
@@ -11,5 +11,6 @@ extern int log_err(const char *format, ...);
 extern int log_info(const char *format, ...);
 extern int log_local(const char *format, ...);
 extern int log_valist(const char *str, va_list);
+extern int log_local_buf(const char *buf, size_t);
 
 #endif
index 2de65ad27371de8af4d38baf9205ff624c223a27..4f9c02310563604c08064209af92567a306acbe6 100644 (file)
--- a/server.c
+++ b/server.c
@@ -525,12 +525,12 @@ out:
        return exitval;
 }
 
-int fio_server_text_output(const char *buf, unsigned int len)
+int fio_server_text_output(const char *buf, size_t len)
 {
        if (server_fd != -1)
                return fio_net_send_cmd(server_fd, FIO_NET_CMD_TEXT, buf, len, 0);
 
-       return fwrite(buf, len, 1, f_err);
+       return log_local_buf(buf, len);
 }
 
 static void convert_io_stat(struct io_stat *dst, struct io_stat *src)
@@ -924,17 +924,46 @@ static void server_signal_handler(void)
        sigaction(SIGTERM, &act, NULL);
 }
 
-static void write_pid(pid_t pid, const char *pidfile)
+static int check_existing_pidfile(const char *pidfile)
+{
+       struct stat sb;
+       char buf[16];
+       pid_t pid;
+       FILE *f;
+
+       if (stat(pidfile, &sb))
+               return 0;
+
+       f = fopen(pidfile, "r");
+       if (!f)
+               return 0;
+
+       if (fread(buf, sb.st_size, 1, f) < 0) {
+               fclose(f);
+               return 1;
+       }
+       fclose(f);
+
+       pid = atoi(buf);
+       if (kill(pid, SIGCONT) < 0)
+               return 0;
+
+       return 1;
+}
+
+static int write_pid(pid_t pid, const char *pidfile)
 {
        FILE *fpid;
 
        fpid = fopen(pidfile, "w");
        if (!fpid) {
                log_err("fio: failed opening pid file %s\n", pidfile);
-               return;
+               return 1;
        }
 
        fprintf(fpid, "%u\n", (unsigned int) pid);
+       fclose(fpid);
+       return 0;
 }
 
 /*
@@ -950,24 +979,31 @@ int fio_start_server(char *pidfile)
        if (!pidfile)
                return fio_server();
 
-       openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
+       if (check_existing_pidfile(pidfile)) {
+               log_err("fio: pidfile %s exists and server appears alive\n",
+                                                               pidfile);
+               return -1;
+       }
+
        pid = fork();
        if (pid < 0) {
-               syslog(LOG_ERR, "failed server fork");
+               log_err("fio: failed server fork: %s", strerror(errno));
                free(pidfile);
                return -1;
        } else if (pid) {
-               write_pid(pid, pidfile);
-               exit(0);
+               int ret = write_pid(pid, pidfile);
+
+               exit(ret);
        }
 
        setsid();
+       openlog("fio", LOG_NDELAY|LOG_NOWAIT|LOG_PID, LOG_USER);
+       log_syslog = 1;
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
        f_out = NULL;
        f_err = NULL;
-       log_syslog = 1;
 
        ret = fio_server();
 
index 72e4cc888dc8ff9649da36cfe0bb9752d7ec6d86..ea888af46c4bcf7e19947088cd2ee02db7cf5d7a 100644 (file)
--- a/server.h
+++ b/server.h
@@ -76,7 +76,7 @@ struct cmd_line_pdu {
 };
 
 extern int fio_start_server(char *);
-extern int fio_server_text_output(const char *, unsigned int len);
+extern int fio_server_text_output(const char *, size_t);
 extern int fio_server_log(const char *format, ...);
 extern int fio_net_send_cmd(int, uint16_t, const void *, off_t, uint64_t);
 extern int fio_net_send_simple_cmd(int sk, uint16_t opcode, uint64_t tag);