Cole Robinson
2008-Feb-19 20:30 UTC
[Xen-devel] [PATCH] xenconsoled: don''t force newline with timestamps
The patch below changes xenconsoled to not force a newline at the end of buffers being sent to timestamped logs. Previously a newline was forced after every call to write_with_timestamp. This could result in some ugly logs when a single console line stetched over multiple calls. This change carries some extra state to determine if we ended the last call to write_with_timestamp on a newline, and prints the timestamp as appropriate. This also fixes a bug where logging hv messages was dependent on the guest timestamp flag. Signed-off-by: Cole Robinson <crobinso@redhat.com> diff -r 8848d9e07584 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Mon Feb 18 21:26:57 2008 +0000 +++ b/tools/console/daemon/io.c Tue Feb 19 10:25:23 2008 -0500 @@ -64,6 +64,8 @@ extern int log_time_guest; extern int log_time_guest; extern char *log_dir; +static int log_time_hv_needts = 1; +static int log_time_guest_needts = 1; static int log_hv_fd = -1; static evtchn_port_or_error_t log_hv_evtchn = -1; static int xc_handle = -1; @@ -116,30 +118,32 @@ static int write_all(int fd, const char* return 0; } -static int write_with_timestamp(int fd, const char *data, size_t sz) +static int write_with_timestamp(int fd, const char *data, size_t sz, + int *needts) { - 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), "[%Y-%m-%d %H:%M:%S] ", tmnow); + const char *last_byte = data + sz - 1; - 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 (data <= last_byte) { + const char *nl = memchr(data, ''\n'', sz); + int found_nl = (nl != NULL); + if (!found_nl) + nl = last_byte; - while (sz > 0) { - const char *nl = strchr(data, ''\n'') + 1; - size_t towrite = nl - data; - if (write_all(fd, ts, tslen) < 0) + if ((*needts && write_all(fd, ts, tslen)) + || write_all(fd, data, nl + 1 - data)) return -1; - if (write_all(fd, data, towrite)) - return -1; - sz -= towrite; - data = nl; + + *needts = found_nl; + data = nl + 1; + if (found_nl) { + // If we printed a newline, strip all \r following it + while (data <= last_byte && *data == ''\r'') + data++; + } } return 0; @@ -183,7 +187,7 @@ static void buffer_append(struct domain if (dom->log_fd != -1) { int logret; if (log_time_guest) { - logret = write_with_timestamp(dom->log_fd, buffer->data + buffer->size - size, size); + logret = write_with_timestamp(dom->log_fd, buffer->data + buffer->size - size, size, &log_time_guest_needts); } else { logret = write_all(dom->log_fd, buffer->data + buffer->size - size, size); } @@ -246,7 +250,8 @@ static int create_hv_log(void) logfile, errno, strerror(errno)); if (fd != -1 && log_time_hv) { if (write_with_timestamp(fd, "Logfile Opened", - strlen("Logfile Opened")) < 0) { + strlen("Logfile Opened"), + &log_time_hv_needts) < 0) { dolog(LOG_ERR, "Failed to log opening timestamp " "in %s: %d (%s)", logfile, errno, strerror(errno)); @@ -289,7 +294,8 @@ static int create_domain_log(struct doma logfile, errno, strerror(errno)); if (fd != -1 && log_time_guest) { if (write_with_timestamp(fd, "Logfile Opened", - strlen("Logfile Opened")) < 0) { + strlen("Logfile Opened"), + &log_time_guest_needts) < 0) { dolog(LOG_ERR, "Failed to log opening timestamp " "in %s: %d (%s)", logfile, errno, strerror(errno)); @@ -886,8 +892,9 @@ static void handle_hv_logs(void) 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); + if (log_time_hv) + logret = write_with_timestamp(log_hv_fd, buffer, size, + &log_time_hv_needts); else logret = write_all(log_hv_fd, buffer, size); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel