On Thursday, June 23, 2011 02:22:37 AM Anthony Liguori wrote: > On 06/22/2011 02:26 AM, Chunyan Liu wrote: > > Add code to support logging xen-domU console, as what xenconsoled does. > > Log info will be saved in /var/log/xen/console/guest-domUname.log. > > It needs to be specified by command line. It's not appropriate to > assume qemu is running as root with access to a non-user directory.
Sorry, I'm late to reply. I just come back from vocation. Thanks for your remindness. But I think adding a command line option to qemu seems not proper, after all, it's a function to xen only. Like XENCONSOLED_TRACE, use XENCONSOLED_LOGDIR environment variable instead. Will post V3. Thanks, Chunyan > Regards, > > Anthony Liguori > > > Signed-off-by: Chunyan Liu<cy...@novell.com> > > --- > > > > hw/xen_console.c | 71 > > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files > > changed, 71 insertions(+), 0 deletions(-) > > > > diff --git a/hw/xen_console.c b/hw/xen_console.c > > index c6c8163..f898e4f 100644 > > --- a/hw/xen_console.c > > +++ b/hw/xen_console.c > > @@ -36,6 +36,8 @@ > > > > #include "qemu-char.h" > > #include "xen_backend.h" > > > > +static int log_guest = 0; > > + > > > > struct buffer { > > > > uint8_t *data; > > size_t consumed; > > > > @@ -52,8 +54,24 @@ struct XenConsole { > > > > void *sring; > > CharDriverState *chr; > > int backlog; > > > > + int log_fd; > > > > }; > > > > +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 void buffer_append(struct XenConsole *con) > > { > > > > struct buffer *buffer =&con->buffer; > > > > @@ -81,6 +99,15 @@ static void buffer_append(struct XenConsole *con) > > > > intf->out_cons = cons; > > xen_be_send_notify(&con->xendev); > > > > + if (con->log_fd != -1) { > > + int logret; > > + logret = write_all(con->log_fd, buffer->data + buffer->size - > > size, size); + if (logret< 0) { > > + xen_be_printf(&con->xendev, 1, "Write to log failed on > > domain %d: %d (%s)\n", + con->xendev.dom, errno, > > strerror(errno)); + } > > + } > > + > > > > if (buffer->max_capacity&& > > > > buffer->size> buffer->max_capacity) { > > /* Discard the middle of the data. */ > > > > @@ -174,12 +201,43 @@ static void xencons_send(struct XenConsole *con) > > > > } > > > > } > > > > +static int create_domain_log(struct XenConsole *con) > > +{ > > + char *logfile; > > + char *path, *domname; > > + int fd; > > + const char *logdir = "/var/log/xen/console"; > > + > > + path = xs_get_domain_path(xenstore, con->xendev.dom); > > + domname = xenstore_read_str(path, "name"); > > + free(path); > > + if (!domname) > > + return -1; > > + > > + if (mkdir(logdir, 0755)&& errno != EEXIST) > > + { > > + xen_be_printf(&con->xendev, 1, "Directory %s does not exist and > > fail to create it!", logdir); + return -1; > > + } > > + > > + asprintf(&logfile, "%s/guest-%s.log", logdir, domname); > > + qemu_free(domname); > > + > > + fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644); > > + free(logfile); > > + if (fd == -1) > > + xen_be_printf(&con->xendev, 1, "Failed to open log %s: %d > > (%s)", logfile, errno, strerror(errno)); + > > + return fd; > > +} > > + > > > > /* -------------------------------------------------------------------- > > */ > > > > static int con_init(struct XenDevice *xendev) > > { > > > > struct XenConsole *con = container_of(xendev, struct XenConsole, > > xendev); char *type, *dom; > > > > + char *logenv = NULL; > > > > /* setup */ > > dom = xs_get_domain_path(xenstore, con->xendev.dom); > > > > @@ -198,6 +256,10 @@ static int con_init(struct XenDevice *xendev) > > > > else > > > > con->chr = serial_hds[con->xendev.dev]; > > > > + logenv = getenv("XENCONSOLED_TRACE"); > > + if (logenv != NULL&& strlen(logenv) == strlen("guest")&& > > !strcmp(logenv, "guest")) { + log_guest = 1; > > + } > > > > return 0; > > > > } > > > > @@ -230,6 +292,9 @@ static int con_connect(struct XenDevice *xendev) > > > > con->xendev.remote_port, > > con->xendev.local_port, > > con->buffer.max_capacity); > > > > + con->log_fd = -1; > > + if (log_guest) > > + con->log_fd = create_domain_log(con); > > > > return 0; > > > > } > > > > @@ -245,6 +310,12 @@ static void con_disconnect(struct XenDevice *xendev) > > > > munmap(con->sring, XC_PAGE_SIZE); > > con->sring = NULL; > > > > } > > > > + > > + if (con->log_fd != -1) { > > + close(con->log_fd); > > + con->log_fd = -1; > > + } > > + > > > > } > > > > static void con_event(struct XenDevice *xendev)