From 2bba474f8f2ce5e16919f1c98219237fbbbb3520 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Tue, 12 Feb 2008 10:16:20 +0000 Subject: Add timestamp option to xenconsoled Similar to the --log option, --timestamp or -t takes: - none : No timestamping - hv : Timestamp hypervisor logs - guest: Timestamp guest logs - all : Timestamp guest and hypervisor logs From: Cole Robinson Signed-off-by: Keir Fraser --- tools/console/daemon/io.c | 90 ++++++++++++++++++++++++++++++++++++++++----- tools/console/daemon/main.c | 20 +++++++++- 2 files changed, 99 insertions(+), 11 deletions(-) (limited to 'tools/console') diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 735a77b0e6..52df19ed34 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -60,6 +60,8 @@ extern int log_reload; extern int log_guest; extern int log_hv; +extern int log_time_hv; +extern int log_time_guest; extern char *log_dir; static int log_hv_fd = -1; @@ -99,6 +101,50 @@ struct domain static struct domain *dom_head; +static int write_all(int fd, const char* buf, size_t len) +{ + while (len) { + ssize_t ret = write(fd, buf, len); + if (ret == -1 && errno == EINTR) + continue; + if (ret <= 0) + return -1; + len -= ret; + buf += ret; + } + + return 0; +} + +static int write_with_timestamp(int fd, const char *data, size_t sz) +{ + char buf[sz+1]; + char ts[32]; + time_t now = time(NULL); + const struct tm *tmnow = localtime(&now); + size_t tslen = strftime(ts, sizeof(ts), "[%d-%m-%Y %H:%M:%S] ", tmnow); + + memcpy(buf, data, sz); + while (sz > 0 && buf[sz-1] == '\r') + sz--; // Don't print trailing \r's + if (sz > 0 && buf[sz-1] != '\n') + buf[sz++] = '\n'; // Force ending newline + data = buf; + + while (sz > 0) { + const char *nl = strchr(data, '\n') + 1; + size_t towrite = nl - data; + if (write_all(fd, ts, tslen) < 0) + return -1; + if (write_all(fd, data, towrite)) + return -1; + sz -= towrite; + data = nl; + } + + return 0; +} + static void buffer_append(struct domain *dom) { struct buffer *buffer = &dom->buffer; @@ -135,10 +181,13 @@ static void buffer_append(struct domain *dom) * and handle_tty_write will stop being called. */ if (dom->log_fd != -1) { - int len = write(dom->log_fd, - buffer->data + buffer->size - size, - size); - if (len < 0) + int logret; + if (log_time_guest) { + logret = write_with_timestamp(dom->log_fd, buffer->data + buffer->size - size, size); + } else { + logret = write_all(dom->log_fd, buffer->data + buffer->size - size, size); + } + if (logret < 0) dolog(LOG_ERR, "Write to log failed on domain %d: %d (%s)\n", dom->domid, errno, strerror(errno)); } @@ -195,6 +244,15 @@ static int create_hv_log(void) if (fd == -1) dolog(LOG_ERR, "Failed to open log %s: %d (%s)", logfile, errno, strerror(errno)); + if (fd != -1 && log_time_hv) { + if (write_with_timestamp(fd, "Logfile Opened", + strlen("Logfile Opened")) < 0) { + dolog(LOG_ERR, "Failed to log opening timestamp " + "in %s: %d (%s)", logfile, errno, + strerror(errno)); + return -1; + } + } return fd; } @@ -229,6 +287,15 @@ static int create_domain_log(struct domain *dom) if (fd == -1) dolog(LOG_ERR, "Failed to open log %s: %d (%s)", logfile, errno, strerror(errno)); + if (fd != -1 && log_time_guest) { + if (write_with_timestamp(fd, "Logfile Opened", + strlen("Logfile Opened")) < 0) { + dolog(LOG_ERR, "Failed to log opening timestamp " + "in %s: %d (%s)", logfile, errno, + strerror(errno)); + return -1; + } + } return fd; } @@ -817,11 +884,16 @@ static void handle_hv_logs(void) if ((port = xc_evtchn_pending(xce_handle)) == -1) return; - if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0) { - int len = write(log_hv_fd, buffer, size); - if (len < 0) - dolog(LOG_ERR, "Failed to write hypervisor log: %d (%s)", - errno, strerror(errno)); + if (xc_readconsolering(xc_handle, &bufptr, &size, 0, 1, &index) == 0 && size > 0) { + int logret; + if (log_time_guest) + logret = write_with_timestamp(log_hv_fd, buffer, size); + else + logret = write_all(log_hv_fd, buffer, size); + + if (logret < 0) + dolog(LOG_ERR, "Failed to write hypervisor log: " + "%d (%s)", errno, strerror(errno)); } (void)xc_evtchn_unmask(xce_handle, port); diff --git a/tools/console/daemon/main.c b/tools/console/daemon/main.c index ea0648f400..c66642ff46 100644 --- a/tools/console/daemon/main.c +++ b/tools/console/daemon/main.c @@ -35,6 +35,8 @@ int log_reload = 0; int log_guest = 0; int log_hv = 0; +int log_time_hv = 0; +int log_time_guest = 0; char *log_dir = NULL; static void handle_hup(int sig) @@ -44,7 +46,7 @@ static void handle_hup(int sig) static void usage(char *name) { - printf("Usage: %s [-h] [-V] [-v] [-i] [--log=none|guest|hv|all] [--log-dir=DIR] [--pid-file=PATH]\n", name); + printf("Usage: %s [-h] [-V] [-v] [-i] [--log=none|guest|hv|all] [--log-dir=DIR] [--pid-file=PATH] [-t, --timestamp=none|guest|hv|all]\n", name); } static void version(char *name) @@ -54,7 +56,7 @@ static void version(char *name) int main(int argc, char **argv) { - const char *sopts = "hVvi"; + const char *sopts = "hVvit:"; struct option lopts[] = { { "help", 0, 0, 'h' }, { "version", 0, 0, 'V' }, @@ -63,6 +65,7 @@ int main(int argc, char **argv) { "log", 1, 0, 'l' }, { "log-dir", 1, 0, 'r' }, { "pid-file", 1, 0, 'p' }, + { "timestamp", 1, 0, 't' }, { 0 }, }; bool is_interactive = false; @@ -103,6 +106,19 @@ int main(int argc, char **argv) case 'p': pidfile = strdup(optarg); break; + case 't': + if (!strcmp(optarg, "all")) { + log_time_hv = 1; + log_time_guest = 1; + } else if (!strcmp(optarg, "hv")) { + log_time_hv = 1; + } else if (!strcmp(optarg, "guest")) { + log_time_guest = 1; + } else if (!strcmp(optarg, "none")) { + log_time_guest = 0; + log_time_hv = 0; + } + break; case '?': fprintf(stderr, "Try `%s --help' for more information\n", -- cgit v1.2.3