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

[Xen-devel] [PATCH] [qemu] Modify mechanism by which serial console information is passed.



Modify the mechanism by which the serial console information is passed.

First, fix a potential memory leak in handling a realloc failure.

Next, the main point of this patch. qemu sets a store path of
<domain-path>/console/tty for every pty device that it creates.
This has the side effect of rewriting the entry if there is more than
one pty-based device.  The monitor, serial lines (can be several) and
parallel ports (can be several) may all use pty devices. In the face
of these multiple potential uses, the path may get overwritten and
contain incorrect information.  The routine writing the store entry
does not know which type of device (monitor, serial, parallel) that
it's creating, and simply always writes the console/tty entry.

Resolve this issue by having the request to create the devices also
call a routine to create the store entries. The new code will create
entries specific to the device, and will also preserve the existing
console/tty entry (and prevent it from being overwritten). The entries
are:

<domain-path>/console/tty
<domain-path>/monitor/tty
<domain-path>/serial/<n>/tty
<domain-path>/parallel/<n>/tty

For instance, a selection from a xenstore-ls output:

   console = ""
    port = "3"
    limit = "1048576"
    tty = "/dev/pts/2"
   domid = "2"
   cpu = ""
    0 = ""
     availability = "online"
   serial = ""
    0 = ""
     tty = "/dev/pts/2"

The console/tty entry is preserved, and should match the serial/0/tty
entry for the case of a serial console mapped to a pty.

This patch makes each of the device entries unambiguous, provides
specific information for the additional devices, and maintains
compatibility with existing expectations about the console/tty
entry.

Signed-off-by: Ben Thomas (ben@xxxxxxxxxxxxxxx)

--
------------------------------------------------------------------------
Ben Thomas                                         Virtual Iron Software
bthomas@xxxxxxxxxxxxxxx                            Tower 1, Floor 2
978-849-1214                                       900 Chelmsford Street
                                                   Lowell, MA 01851
# HG changeset patch
# User ben@xxxxxxxxxxxxxxx
# Date 1172699118 18000
# Node ID 2af753b0efee06f4c7e59d8ea24cb9ff7450a3f8
# Parent  8ba425b640b3c7f81c17eb45972eff6eabe9f94d
Modify the mechanism by which the serial console information is passed.

First, fix a potential memory leak in handling a realloc failure.

Next, the main point of this patch. qemu sets a store path of
<domain-path>/console/tty for every pty device that it creates.
This has the side effect of rewriting the entry if there is more than
one pty-based device.  The monitor, serial lines (can be several) and
parallel ports (can be several) may all create pty devices.  In the face of
these multiple potential cases, the path may get overwritten and contain
incorrect information.  The routine writing the store entry does not know
which type of device (monitor, serial, parallel) that it's creating, and
simply always writes the console/tty entry.

Resolve this issue by having the request to create the devices also
call a routine to create the store entries. The new code will create
entries specific to the device, and will also preserve the existing
console/tty entry (and prevent it from being overwritten). The entries
are:

<domain-path>/console/tty
<domain-path>/monitor/tty
<domain-path>/serial/<n>/tty
<domain-path>/parallel/<n>/tty

For instance, a selection from a xenstore-ls output:

   console = ""
    port = "3"
    limit = "1048576"
    tty = "/dev/pts/2"
   domid = "2"
   cpu = ""
    0 = ""
     availability = "online"
   serial = ""
    0 = ""
     tty = "/dev/pts/2"

The console/tty entry is preserved, and should match the serial/0/tty
entry for the case of a serial console mapped to a pty.

This patch makes each of the device entries unambiguous, as well as provides
specific information for the additional devices.

Signed-off-by: Ben Thomas (ben@xxxxxxxxxxxxxxx)


diff -r 8ba425b640b3 -r 2af753b0efee tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Wed Feb 28 11:13:49 2007 -0500
+++ b/tools/ioemu/vl.c  Wed Feb 28 16:45:18 2007 -0500
@@ -1565,11 +1565,49 @@ CharDriverState *qemu_chr_open_stdio(voi
     return chr;
 }
 
-int store_console_dev(int domid, char *pts)
+/* Create a store entry for a device(monitor, serial/parallel lines).
+ * The entry is <domain-path><storeString>/tty and the value is the name
+ * of the pty associated with the device.
+ */
+
+static int store_dev_info(char *devName, int domid, CharDriverState *cState, 
char *storeString)
 {
     int xc_handle;
     struct xs_handle *xs;
     char *path;
+    char *newpath;
+    FDCharDriver *s;
+    char *pts;
+
+    // Check for valid arguments (at least, prevent segfaults)
+
+    if ( (devName == NULL) || (cState == NULL) || (storeString == NULL) ) {
+      fprintf(logfile, "%s - invalid arguments\n", __FUNCTION__);
+      return EINVAL;
+    }
+
+    // Only continue if we're talking to a pty
+    //  Actually, the following code works for any CharDriverState using 
FDCharDriver,
+    //  but we really only care about pty's here
+
+    if (strcmp(devName, "pty") != 0)
+      return 0;
+    
+    s = cState->opaque;
+    if (s == NULL) {
+      fprintf(logfile, "%s - unable to retrieve fd for '%s'/'%s'\n",
+             __FUNCTION__, storeString, devName);
+      return EBADF;
+    }
+
+    pts = ptsname(s->fd_in);
+    if (pts == NULL) {
+      fprintf(logfile, "%s - unable to determine ptsname '%s'/'%s', error %d 
(%s)\n",
+             __FUNCTION__, storeString, devName, errno, strerror(errno));
+      return errno;
+    }
+
+    // We now have everything we need to set the xenstore entry
 
     xs = xs_daemon_open();
     if (xs == NULL) {
@@ -1588,14 +1626,18 @@ int store_console_dev(int domid, char *p
         fprintf(logfile, "xs_get_domain_path() error\n");
         return -1;
     }
-    path = realloc(path, strlen(path) + strlen("/console/tty") + 1);
-    if (path == NULL) {
+    newpath = realloc(path, strlen(path) + strlen(storeString) + 
strlen("/tty") + 1);
+    if (newpath == NULL) {
+        free(path);                    // realloc errors leave old block
         fprintf(logfile, "realloc error\n");
         return -1;
     }
-    strcat(path, "/console/tty");
+    path = newpath;
+
+    strcat(path, storeString);
+    strcat(path, "/tty");
     if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
-        fprintf(logfile, "xs_write for console fail");
+        fprintf(logfile, "xs_write for '%s' fail", storeString);
         return -1;
     }
 
@@ -1622,7 +1664,6 @@ CharDriverState *qemu_chr_open_pty(void)
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
     
     fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    store_console_dev(domid, ptsname(master_fd));
 
     return qemu_chr_open_fd(master_fd, master_fd);
 }
@@ -6694,16 +6735,22 @@ int main(int argc, char **argv)
         fprintf(stderr, "qemu: could not open monitor device '%s'\n", 
monitor_device);
         exit(1);
     }
+    store_dev_info(monitor_device, domid, monitor_hd, "/monitor");
     monitor_init(monitor_hd, !nographic);
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_devices[i][0] != '\0') {
+         char buf[16];
             serial_hds[i] = qemu_chr_open(serial_devices[i]);
             if (!serial_hds[i]) {
                 fprintf(stderr, "qemu: could not open serial device '%s'\n", 
                         serial_devices[i]);
                 exit(1);
             }
+           snprintf(buf, sizeof(buf), "/serial/%d", i);
+           store_dev_info(serial_devices[i], domid, serial_hds[i], buf);
+           if (i == 0)                         // serial 0 is also called the 
console
+             store_dev_info(serial_devices[i], domid, serial_hds[i], 
"/console");
             if (!strcmp(serial_devices[i], "vc"))
                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
         }
@@ -6711,12 +6758,15 @@ int main(int argc, char **argv)
 
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         if (parallel_devices[i][0] != '\0') {
+            char buf[16];
             parallel_hds[i] = qemu_chr_open(parallel_devices[i]);
             if (!parallel_hds[i]) {
                 fprintf(stderr, "qemu: could not open parallel device '%s'\n", 
                         parallel_devices[i]);
                 exit(1);
             }
+           snprintf(buf, sizeof(buf), "/parallel/%d", i);
+           store_dev_info(parallel_devices[i], domid, parallel_hds[i], buf);
             if (!strcmp(parallel_devices[i], "vc"))
                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
         }
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.