]> xenbits.xensource.com Git - people/dstodden/blktap.git/commitdiff
CA-34981: Integrate tapdisk-logfile into tapdisk-log.
authorDaniel Stodden <daniel.stodden@citrix.com>
Sat, 14 Nov 2009 04:26:09 +0000 (20:26 -0800)
committerDaniel Stodden <daniel.stodden@citrix.com>
Sat, 14 Nov 2009 04:26:09 +0000 (20:26 -0800)
drivers/block-vhd.c
drivers/block-vindex.c
drivers/tapdisk-interface.c
drivers/tapdisk-interface.h
drivers/tapdisk-log.c
drivers/tapdisk-log.h
drivers/tapdisk-server.c
drivers/tapdisk-utils.c
drivers/tapdisk-utils.h
drivers/tapdisk-vbd.c

index bc722c7519095c422747bb23a2c5b94534de24c8..1abf34e478d93cbfae5a6f3d31c359039848e534 100644 (file)
@@ -67,8 +67,7 @@ unsigned int SPB;
                        __FILE__, __LINE__, #_p);                       \
                DBG(TLOG_WARN, "%s:%d: FAILED ASSERTION: '%s'\n",       \
                    __FILE__, __LINE__, #_p);                           \
-               tlog_flush();                                           \
-               *(int*)0 = 0;                                           \
+               td_panic();                                             \
        }
 
 #if (DEBUGGING == 1)
index 792684131af0a0453eff072c0fed99833060530f..8c5eb7b569a4d9cbd6871d40266de039513b2bc3 100644 (file)
@@ -24,8 +24,7 @@
 #define ASSERT(condition)                                      \
        if (!(condition)) {                                     \
                WARN("FAILED ASSERTION: '%s'\n", #condition);   \
-               tlog_flush();                                   \
-               *(int *)0 = 0;                                  \
+               td_panic();                                     \
        }
 
 #define VHD_INDEX_FILE_POOL_SIZE     12
index 58366d0a0bbe72c24ee8ecc00bb6cd1cba0473da..0221206ae03ef5ec10250d1e30eb2d3eadd6e8f9 100644 (file)
@@ -25,6 +25,8 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
+#include <signal.h>
 #include <errno.h>
 
 #include "tapdisk.h"
@@ -33,6 +35,7 @@
 #include "tapdisk-driver.h"
 #include "tapdisk-server.h"
 #include "tapdisk-interface.h"
+#include "tapdisk-log.h"
 
 int
 td_load(td_image_t *image)
@@ -248,3 +251,10 @@ td_debug(td_image_t *image)
 
        tapdisk_driver_debug(driver);
 }
+
+void
+td_panic(void)
+{
+       tlog_precious();
+       raise(SIGABRT);
+}
index 1e48e5811a0f6946771cee9e26b0d5654f09eabd..a9cabc9fdc8bc1966baa2bfe615c07331df9b574 100644 (file)
@@ -49,5 +49,6 @@ void td_prep_read(struct tiocb *, int, char *, size_t,
                  long long, td_queue_callback_t, void *);
 void td_prep_write(struct tiocb *, int, char *, size_t,
                   long long, td_queue_callback_t, void *);
+void td_panic(void);
 
 #endif
index 0284ca0121dd26429984b0184d7413d45105efce..6ae7f34965c0db4294b08da9bcb76198fc7454cc 100644 (file)
@@ -1,22 +1,48 @@
-/* Copyright (c) 2008, XenSource Inc.
+/*
+ * Copyright (c) 2008, 2009, XenSource Inc.
  * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
 #include <stdlib.h>
-#include <string.h>
+#include <unistd.h>
+#include <errno.h>
 #include <stdarg.h>
 #include <syslog.h>
-#include <inttypes.h>
-#include <time.h>
 #include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
+#include "blktaplib.h"
 #include "tapdisk-log.h"
 #include "tapdisk-utils.h"
+#include "tapdisk-logfile.h"
 #include "tapdisk-vbd-stats.h"
 
+#define TLOG_LOGFILE_BUFSZ (16<<10)
+
 #define MAX_ENTRY_LEN      512
 #define MAX_ERROR_MESSAGES 16
 
@@ -35,57 +61,189 @@ struct ehandle {
 };
 
 struct tlog {
-       char          *p;
-       int            size;
-       uint64_t       cnt;
-       char          *buf;
+       char          *ident;
+       td_logfile_t   logfile;
+       int            precious;
        int            level;
-       char          *file;
-       int            append;
 };
 
 static struct ehandle tapdisk_err;
 static struct tlog tapdisk_log;
 
-void
-open_tlog(char *file, size_t bytes, int level, int append)
+static void
+tlog_logfile_vprint(const char *fmt, va_list ap)
 {
-       int i;
+       tapdisk_logfile_vprintf(&tapdisk_log.logfile, fmt, ap);
+}
 
-       tapdisk_log.size = ((bytes + 511) & (~511));
+static void
+__attribute__((format(printf, 1, 2)))
+tlog_logfile_print(const char *fmt, ...)
+{
+       va_list ap;
 
-       if (asprintf(&tapdisk_log.file, "%s.%d", file, getpid()) == -1)
-               return;
+       va_start(ap, fmt);
+       tlog_logfile_vprint(fmt, ap);
+       va_end(ap);
+}
 
-       if (posix_memalign((void **)&tapdisk_log.buf, 512, tapdisk_log.size)) {
-               free(tapdisk_log.file);
-               tapdisk_log.buf = NULL;
-               return;
+static void
+tlog_logfile_save(void)
+{
+       td_logfile_t *logfile = &tapdisk_log.logfile;
+       const char *ident = tapdisk_log.ident;
+       int err;
+
+       tlog_logfile_print("%s: saving log, %d errors",
+                          tapdisk_syslog_ident(ident), tapdisk_err.cnt);
+
+       tapdisk_logfile_flush(logfile);
+
+       err = tapdisk_logfile_rename(logfile,
+                                    TLOG_DIR, ident, ".log");
+#if 0
+       tlog_syslog("logfile saved to %s: %d\n", logfile->path, err);
+#endif
+}
+
+static void
+tlog_logfile_close(void)
+{
+       td_logfile_t *logfile = &tapdisk_log.logfile;
+       const char *ident = tapdisk_log.ident;
+       int keep, err;
+
+       keep = tapdisk_log.precious || tapdisk_err.cnt;
+
+       tlog_logfile_print("%s: closing log, %d errors",
+                          tapdisk_syslog_ident(ident), tapdisk_err.cnt);
+
+       if (keep) {
+               tlog_logfile_save();
+               DPRINTF("logfile kept as %s\n", logfile->path);
+       }
+
+       tapdisk_logfile_close(logfile);
+
+       if (!keep)
+               tapdisk_logfile_unlink(logfile);
+}
+
+static int
+tlog_logfile_open(const char *ident, int level)
+{
+       td_logfile_t *logfile = &tapdisk_log.logfile;
+       int mode, err;
+
+       err = mkdir(TLOG_DIR, 0755);
+       if (err) {
+               err = -errno;
+               if (err != -EEXIST)
+                       goto fail;
        }
 
-       memset(tapdisk_log.buf, 0, tapdisk_log.size);
+       err = tapdisk_logfile_open(logfile,
+                                  TLOG_DIR, ident, ".tmp",
+                                  TLOG_LOGFILE_BUFSZ);
+       if (err)
+               goto fail;
+
+       mode = (level == TLOG_DBG) ? _IOLBF : _IOFBF;
+
+       err = tapdisk_logfile_setvbuf(logfile, mode);
+       if (err)
+               goto fail;
+
+       tlog_logfile_print("%s: log start, level %d",
+                          tapdisk_syslog_ident(ident), level);
+
+       return 0;
+
+fail:
+       tlog_logfile_close();
+       return err;
+}
+
+static void
+tlog_logfile_error(int err, const char *func, const char *fmt, va_list ap)
+{
+       td_logfile_t *logfile = &tapdisk_log.logfile;
+       char buf[MAX_ENTRY_LEN+1];
+
+       vsnprintf(buf, sizeof(buf), fmt, ap);
 
-       tapdisk_log.p      = tapdisk_log.buf;
-       tapdisk_log.level  = level;
-       tapdisk_log.append = append;
+       tlog_logfile_print("ERROR: errno %d at %s: %s", err, func, buf);
+
+       tlog_precious();
+}
+
+static void
+tlog_errors_init(const char *ident, int facility)
+{
+       int i;
 
        for (i = 0; i < MAX_ERROR_MESSAGES; ++i)
                td_dispersion_init(&tapdisk_err.errors[i].st);
 }
 
+int
+tlog_open(const char *ident, int facility, int level)
+{
+       int err;
+
+       DPRINTF("tlog starting, level %d\n", level);
+
+       tapdisk_log.level = level;
+       tapdisk_log.ident = strdup(ident);
+
+       if (!tapdisk_log.ident) {
+               err = -errno;
+               goto fail;
+       }
+
+       err = tlog_logfile_open(ident, level);
+       if (err)
+               goto fail;
+
+       tlog_errors_init(ident, facility);
+
+       return 0;
+
+fail:
+       tlog_close();
+       return err;
+}
+
 void
-close_tlog(void)
+tlog_close(void)
 {
-       if (!tapdisk_log.buf)
-               return;
+       DPRINTF("tlog closing with %d errors\n", tapdisk_err.cnt);
 
-       if (tapdisk_log.append)
-               tlog_flush();
+       tlog_logfile_close();
 
-       free(tapdisk_log.buf);
-       free(tapdisk_log.file);
+       free(tapdisk_log.ident);
+       tapdisk_log.ident = NULL;
+}
 
-       memset(&tapdisk_log, 0, sizeof(struct tlog));
+void
+tlog_precious(void)
+{
+       if (!tapdisk_log.precious)
+               tlog_logfile_save();
+
+       tapdisk_log.precious = 1;
+}
+
+void
+__tlog_write(int prio, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (prio <= tapdisk_log.level) {
+               va_start(ap, fmt);
+               tlog_logfile_vprint(fmt, ap);
+               va_end(ap);
+       }
 }
 
 static void
@@ -110,44 +268,6 @@ tlog_strtime(char *tstr, size_t len)
        __tlog_strtime(tstr, len, &tv);
 }
 
-void
-__tlog_write(int level, const char *func, const char *fmt, ...)
-{
-       char *buf;
-       va_list ap;
-       int ret, len, avail;
-       char tstr[64];
-
-       if (!tapdisk_log.buf)
-               return;
-
-       if (level > tapdisk_log.level)
-               return;
-
-       avail = tapdisk_log.size - (tapdisk_log.p - tapdisk_log.buf);
-       if (avail < MAX_ENTRY_LEN) {
-               if (tapdisk_log.append)
-                       tlog_flush();
-               tapdisk_log.p = tapdisk_log.buf;
-       }
-
-       buf = tapdisk_log.p;
-       tlog_strtime(tstr, sizeof(tstr));
-       len = snprintf(buf, MAX_ENTRY_LEN - 1, "%08"PRIu64":[%s]:%s ",
-                      tapdisk_log.cnt, tstr, func);
-
-       va_start(ap, fmt);
-       ret = vsnprintf(buf + len, MAX_ENTRY_LEN - (len + 1), fmt, ap);
-       va_end(ap);
-
-       len = (ret < MAX_ENTRY_LEN - (len + 1) ?
-              len + ret : MAX_ENTRY_LEN - 1);
-       buf[len] = '\0';
-
-       tapdisk_log.cnt++;
-       tapdisk_log.p += len;
-}
-
 void
 __tlog_error(int err, const char *func, const char *fmt, ...)
 {
@@ -157,6 +277,10 @@ __tlog_error(int err, const char *func, const char *fmt, ...)
 
        err = (err > 0 ? err : -err);
 
+       va_start(ap, fmt);
+       tlog_logfile_error(err, func, fmt, ap);
+       va_end(ap);
+
        for (i = 0; i < tapdisk_err.cnt; i++) {
                e = &tapdisk_err.errors[i];
                if (e->err == err && e->func == func) {
@@ -214,73 +338,24 @@ tlog_print_errors(void)
 }
 
 void
-tlog_flush_errors(void)
-{
-       int i;
-       struct error *e;
-
-       for (i = 0; i < tapdisk_err.cnt; i++) {
-               e = &tapdisk_err.errors[i];
-               tlog_write(TLOG_WARN, "TAPDISK ERROR: errno %d at %s "
-                          "(cnt = %d): %s\n", e->err, e->func, e->cnt,
-                          e->msg);
-       }
-
-       if (tapdisk_err.dropped)
-               tlog_write(TLOG_WARN, "TAPDISK ERROR: %d other error messages "
-                      "dropped\n", tapdisk_err.dropped);
-}
-
-void
-tlog_flush(void)
-{
-       int fd, flags;
-       size_t size, wsize;
-
-       if (!tapdisk_log.buf)
-               return;
-
-       flags = O_CREAT | O_WRONLY | O_DIRECT | O_NONBLOCK;
-       if (!tapdisk_log.append)
-               flags |= O_TRUNC;
-
-       fd = open(tapdisk_log.file, flags, 0644);
-       if (fd == -1)
-               return;
-
-       if (tapdisk_log.append)
-               if (lseek64(fd, 0, SEEK_END) == (loff_t)-1)
-                       goto out;
-
-       tlog_flush_errors();
-
-       size  = tapdisk_log.p - tapdisk_log.buf;
-       wsize = ((size + 511) & (~511));
-
-       memset(tapdisk_log.buf + size, '\n', wsize - size);
-       write(fd, tapdisk_log.buf, wsize);
-
-       tapdisk_log.p = tapdisk_log.buf;
-
-out:
-       close(fd);
-}
-
-void
-tapdisk_start_logging(const char *ident, const char *facility)
+tapdisk_start_logging(const char *ident, const char *_facility)
 {
        static char buf[128];
+       int facility, err;
 
-       snprintf(buf, sizeof(buf), "%s[%d]", ident, getpid());
+       facility = tapdisk_syslog_facility(_facility);
 
-       openlog(buf, LOG_CONS|LOG_ODELAY, tapdisk_syslog_facility(facility));
+       snprintf(buf, sizeof(buf), "%s[%d]", ident, getpid());
+       openlog(buf, LOG_CONS|LOG_ODELAY, facility);
 
-       open_tlog("/tmp/tapdisk.log", (64 << 10), TLOG_WARN, 0);
+       err = tlog_open(ident, facility, TLOG_WARN);
+       if (err)
+               EPRINTF("tlog open failure: %d\n", err);
 }
 
 void
 tapdisk_stop_logging(void)
 {
-       close_tlog();
+       tlog_close();
        closelog();
 }
index 0851df6b3a81a5444196f08c8d35529dc67156ed..492e9f0132de271bb19f7446423004231d548632 100644 (file)
@@ -1,5 +1,29 @@
-/* Copyright (c) 2008, XenSource Inc.
+/*
+ * Copyright (c) 2009, XenSource Inc.
  * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of XenSource Inc. nor the names of its contributors
+ *       may be used to endorse or promote products derived from this software
+ *       without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef _TAPDISK_LOG_H_
 #define TLOG_INFO       1
 #define TLOG_DBG        2
 
-void open_tlog(char *file, size_t bytes, int level, int append);
-void close_tlog(void);
-void tlog_flush(void);
+#define TLOG_DIR "/var/log/blktap"
+
+int  tlog_open(const char *, int, int);
+int  tlog_setvbuf(void);
+void tlog_close(void);
+void tlog_precious(void);
 void tlog_print_errors(void);
 
-void __tlog_write(int level, const char *func, const char *fmt, ...)
-  __attribute__((format(printf, 3, 4)));
+void __tlog_write(int, const char *, ...)
+       __attribute__((format(printf, 2, 3)));
+
 void __tlog_error(int err, const char *func, const char *fmt, ...)
   __attribute__((format(printf, 3, 4)));
 
 #define tlog_write(_level, _f, _a...)                  \
-       __tlog_write(_level, __func__, _f, ##_a)
+       __tlog_write(_level, "%s: " _f,  __func__, ##_a)
 
 #define tlog_error(_err, _f, _a...)                    \
        __tlog_error(_err, __func__, _f, ##_a)
index a01e28f8d1ffe257f9e560b1284fee9b9940375c..b7f800b5771e1eae7a89618e7079c99c26fffc50 100644 (file)
@@ -131,7 +131,8 @@ tapdisk_server_debug(void)
        tapdisk_server_for_each_vbd(vbd, tmp)
                tapdisk_vbd_debug(vbd);
 
-       tlog_flush();
+       DBG(TLOG_INFO, "debug log completed\n");
+       tlog_precious();
 }
 
 void
@@ -337,6 +338,7 @@ tapdisk_server_signal_handler(int signal)
                break;
 
        case SIGUSR1:
+               DBG(TLOG_INFO, "debugging on signal %d\n", signal);
                tapdisk_server_debug();
                break;
        }
index 939a2da582f2c5578d754061a2a6328ea19e0114..4238b4134c87fb175331ff734780d7c570781476 100644 (file)
@@ -80,6 +80,26 @@ tapdisk_syslog_facility(const char *arg)
        return LOG_DAEMON;
 }
 
+#define TD_SYSLOG_IDENT_MAX 32
+
+const char*
+tapdisk_syslog_ident(const char *name)
+{
+       static char ident[TD_SYSLOG_IDENT_MAX];
+       size_t size, len;
+       pid_t pid;
+
+       pid  = getpid();
+       size = sizeof(ident);
+       len  = 0;
+
+       len  = snprintf(NULL, 0, "[%d]", pid);
+       len  = snprintf(ident, size - len, name);
+       len += snprintf(ident + len, size - len, "[%d]", pid);
+
+       return ident;
+}
+
 int
 tapdisk_set_resource_limits(void)
 {
index 1debae995211ac6912920b9a258695e5d14766ed..c150a1b8b9cc2a4f55202d25883f053bd2727b23 100644 (file)
@@ -33,6 +33,7 @@
 #define MAX_NAME_LEN                 1000
 
 int tapdisk_syslog_facility(const char *);
+const char* tapdisk_syslog_ident(const char *);
 int tapdisk_set_resource_limits(void);
 int tapdisk_namedup(char **, const char *);
 int tapdisk_parse_disk_type(const char *, char **, int *);
index 9c27fb7c96c87fcdfee432a9cc88c2cc1da912bd..9a023c8c9c3b557920755d7fa4d695fd199113c5 100644 (file)
@@ -938,7 +938,7 @@ tapdisk_vbd_drop_log(td_vbd_t *vbd)
                return;
 
        tapdisk_vbd_debug(vbd);
-       tlog_flush();
+       tlog_precious();
        td_flag_set(vbd->state, TD_VBD_LOG_DROPPED);
 }