[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |