qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH V2] Support logging xen-guest console


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH V2] Support logging xen-guest console
Date: Wed, 22 Jun 2011 13:22:37 -0500
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110424 Lightning/1.0b2 Thunderbird/3.1.10

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.

Regards,

Anthony Liguori


Signed-off-by: Chunyan Liu<address@hidden>
---
  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)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]