]> xenbits.xensource.com Git - qemu-xen-4.0-testing.git/commitdiff
Store pty name in xenstore for the benefit of the tools.
authorIan Jackson <iwj@mariner.uk.xensource.com>
Wed, 9 Jul 2008 11:32:09 +0000 (12:32 +0100)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 9 Jul 2008 11:32:09 +0000 (12:32 +0100)
This is a rather intrusive patch, because we need a mechanism to get
the ptsname out of the guts of the qemu startup code.  This is a
first cut of such a thing which might eventually go upstream.

The main new interface is chr_getname, a new CharDriverState method.
If implemented it returns "<type> <name>" where currently "<type>" is
"pty" for ptys.  If not implemented the function pointer may be null.

We import store_dev_info from xen-unstable (17987:9b35ae586cb8) and
eviscerate it appropriately.

qemu-char.h
vl.c
xen-config-host.h
xenstore.c

index 41936bc9f0caa77b4752c0aacaf7a7f765c7f58d..ef98ed52d85e1992a38038122951e32e977957b6 100644 (file)
@@ -44,6 +44,7 @@ struct CharDriverState {
     void (*chr_send_event)(struct CharDriverState *chr, int event);
     void (*chr_close)(struct CharDriverState *chr);
     void (*chr_accept_input)(struct CharDriverState *chr);
+    int (*chr_getname)(struct CharDriverState *s, char *buf, size_t buflen);
     void *opaque;
     int focus;
     QEMUBH *bh;
diff --git a/vl.c b/vl.c
index 0add8b602b6a1be0ed86c56e57fa6f8caa416627..442faf8f003f060241bb6f4812fe13ca3d2da94a 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2338,10 +2338,20 @@ void cfmakeraw (struct termios *termios_p)
 #endif
 
 #if defined(__linux__) || defined(__sun__) || defined(__NetBSD__) || defined(__OpenBSD__)
+static int pty_getname(struct CharDriverState *chr, char *buf, size_t len) {
+    char *name;
+    FDCharDriver *s = chr->opaque;
+
+    name = ptsname(s->fd_in);
+    if (!name) return -1;
+    return snprintf(buf,len, "pty %s", name);
+}
+
 static CharDriverState *qemu_chr_open_pty(void)
 {
     struct termios tty;
     int master_fd, slave_fd;
+    CharDriverState *chr;
 
     if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {
         return NULL;
@@ -2352,7 +2362,9 @@ static CharDriverState *qemu_chr_open_pty(void)
     tcsetattr(slave_fd, TCSAFLUSH, &tty);
 
     fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));
-    return qemu_chr_open_fd(master_fd, master_fd);
+    chr = qemu_chr_open_fd(master_fd, master_fd);
+    chr->chr_getname = pty_getname;
+    return chr;
 }
 
 static void tty_serial_init(int fd, int speed,
@@ -8767,6 +8779,7 @@ int main(int argc, char **argv)
             }
             if (strstart(devname, "vc", 0))
                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
+           xenstore_store_serial_port_info(i, serial_hds[i], devname);
         }
     }
 
index 2237756603f74ad9e3d60609e4e3d295f4da2361..6e84a98142a84d9932d089230a3a46ca27315d4d 100644 (file)
@@ -32,3 +32,6 @@ extern int vcpus;
 
 void xenstore_parse_domain_config(int domid);
 void xenstore_read_vncpasswd(int domid, char *pwbuf, size_t pwbuflen);
+struct CharDriverState;
+void xenstore_store_serial_port_info(int i, struct CharDriverState *chr,
+                                    const char *devname);
index 78f39d037c0c4c26feb8351cc80b1d3664666dea..059e519d82cbd7fd105be859588cb4053cef93eb 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include "qemu-common.h"
+#include "qemu-char.h"
 
 #include "block_int.h"
 #include <unistd.h>
@@ -974,3 +975,89 @@ int xenstore_vm_write(int domid, char *key, char *value)
     free(buf);
     return rc;
 }
+
+
+/*
+ * Create a store entry for a device (e.g., 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(const char *devName, int domid,
+                          CharDriverState *cState, const char *storeString)
+{
+#ifdef CONFIG_STUBDOM
+    fprintf(logfile, "can't store dev %s name for domid %d in %s from a stub domain\n", devName, domid, storeString);
+    return ENOSYS;
+#else
+    int xc_handle;
+    struct xs_handle *xs;
+    char *path;
+    char *newpath;
+    char *pts;
+    char namebuf[128];
+    int ret;
+
+    /*
+     * Only continue if we're talking to a pty
+     */
+    if (!cState->chr_getname) return 0;
+    ret = cState->chr_getname(cState, namebuf, sizeof(namebuf));
+    if (ret < 0) {
+        fprintf(logfile, "ptsname failed (for '%s'): %s\n",
+                storeString, strerror(errno));
+        return 0;
+    }
+    if (memcmp(namebuf, "pty ", 4)) return 0;
+    pts = namebuf + 4;
+
+    /* We now have everything we need to set the xenstore entry. */
+    xs = xs_daemon_open();
+    if (xs == NULL) {
+        fprintf(logfile, "Could not contact XenStore\n");
+        return -1;
+    }
+
+    xc_handle = xc_interface_open();
+    if (xc_handle == -1) {
+        fprintf(logfile, "xc_interface_open() error\n");
+        return -1;
+    }
+
+    path = xs_get_domain_path(xs, domid);
+    if (path == NULL) {
+        fprintf(logfile, "xs_get_domain_path() error\n");
+        return -1;
+    }
+    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;
+    }
+    path = newpath;
+
+    strcat(path, storeString);
+    strcat(path, "/tty");
+    if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
+        fprintf(logfile, "xs_write for '%s' fail", storeString);
+        return -1;
+    }
+
+    free(path);
+    xs_daemon_close(xs);
+    close(xc_handle);
+
+    return 0;
+#endif
+}
+
+void xenstore_store_serial_port_info(int i, CharDriverState *chr,
+                                    const char *devname) {
+    char buf[16];
+
+    snprintf(buf, sizeof(buf), "/serial/%d", i);
+    store_dev_info(devname, domid, chr, buf);
+    if (i == 0) /* serial 0 is also called the console */
+        store_dev_info(devname, domid, chr, "/console");
+}