Cole Robinson
2008-Feb-11 18:09 UTC
[Xen-devel] [PATCH] Add timestamp option to xenconsoled
Add an option to xenconsoled to timestamp logged messages. 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 Patch is against unstable cset 17015. Hypervisor logging in general doesn''t seem to be working at the moment, but I confirmed this does its job for guest logging. Thanks, Cole diff -r bab9e298450a -r 5e302ccd1109 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Feb 11 10:57:17 2008 +0000 +++ b/tools/console/daemon/io.c Mon Feb 11 11:27:43 2008 -0500 @@ -60,6 +60,8 @@ extern int log_reload; 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,52 @@ 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 +183,13 @@ static void buffer_append(struct domain * 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 +246,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 +289,15 @@ static int create_domain_log(struct doma 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 +886,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 -r bab9e298450a -r 5e302ccd1109 tools/console/daemon/main.c --- a/tools/console/daemon/main.c Mon Feb 11 10:57:17 2008 +0000 +++ b/tools/console/daemon/main.c Mon Feb 11 11:27:43 2008 -0500 @@ -35,6 +35,8 @@ int log_reload = 0; 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; @@ -102,6 +105,19 @@ int main(int argc, char **argv) break; 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, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel