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