For completeness, we should be freeing up memory(malloced for dev) in case of an error in xencons_ring_init. There could be other such instances.
  Also, is it too difficult to create a consfront_dev for the first console and get rid of those !dev checks. 
 -dulloor
 
 On Thu, Jun 11, 2009 at 11:07 AM, Stefano Stabellini  <stefano.stabellini@xxxxxxxxxxxxx> wrote:
 This patch implements support for more than one serial in MiniOS console 
frontend. 
The code to setup the first console remains a little bit different from 
the rest because of the particular way the first console is provided to 
a pv guests. 
The new code to handle secondary consoles is much more similar to other 
frontends. 
 
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> 
 
--- 
 
diff -r 112680f620bf extras/mini-os/console/console.c 
--- a/extras/mini-os/console/console.c  Mon Jun 08 18:23:57 2009 +0100 
+++ b/extras/mini-os/console/console.c  Thu Jun 11 15:19:43 2009 +0100 
@@ -76,11 +76,11 @@ 
 #endif 
 
 
-void console_print(char *data, int length) 
+void console_print(struct consfront_dev *dev, char *data, int length) 
 { 
     char *curr_char, saved_char; 
     int part_len; 
-    int (*ring_send_fn)(const char *data, unsigned length); 
+    int (*ring_send_fn)(struct consfront_dev *dev, const char *data, unsigned length); 
 
     if(!console_initialised) 
         ring_send_fn = xencons_ring_send_no_notify; 
@@ -94,17 +94,17 @@ 
             saved_char = *(curr_char+1); 
             *(curr_char+1) = '\r'; 
             part_len = curr_char - data + 2; 
-            ring_send_fn(data, part_len); 
+            ring_send_fn(dev, data, part_len); 
             *(curr_char+1) = saved_char; 
             data = "">
             length -= part_len - 1; 
         } 
     } 
 
-    ring_send_fn(data, length); 
+    ring_send_fn(dev, data, length); 
 
     if(data[length-1] == '\n') 
-        ring_send_fn("\r", 1); 
+        ring_send_fn(dev, "\r", 1); 
 } 
 
 void print(int direct, const char *fmt, va_list args) 
@@ -123,7 +123,7 @@ 
 #endif 
             (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf); 
 
-        console_print(buf, strlen(buf)); 
+        console_print(NULL, buf, strlen(buf)); 
     } 
 } 
 
@@ -151,7 +151,7 @@ 
     printk("done.\n"); 
 } 
 
-void fini_console(void) 
+void fini_console(struct consfront_dev *dev) 
 { 
-    /* Destruct the console and get the parameters of the restarted one */ 
+    if (dev) free_consfront(dev); 
 } 
diff -r 112680f620bf extras/mini-os/console/xencons_ring.c 
--- a/extras/mini-os/console/xencons_ring.c     Mon Jun 08 18:23:57 2009 +0100 
+++ b/extras/mini-os/console/xencons_ring.c     Thu Jun 11 15:19:43 2009 +0100 
@@ -7,25 +7,38 @@ 
 #include <lib.h> 
 #include <xenbus.h> 
 #include <xen/io/console.h> 
+#include <xen/io/protocols.h> 
+#include <xen/io/ring.h> 
+#include <xmalloc.h> 
+#include <gnttab.h> 
 
 DECLARE_WAIT_QUEUE_HEAD(console_queue); 
+ 
+static inline void notify_daemon(struct consfront_dev *dev) 
+{ 
+    /* Use evtchn: this is called early, before irq is set up. */ 
+    if (!dev) 
+        notify_remote_via_evtchn(start_info.console.domU.evtchn); 
+    else 
+        notify_remote_via_evtchn(dev->evtchn); 
+} 
 
 static inline struct xencons_interface *xencons_interface(void) 
 { 
     return mfn_to_virt(start_info.console.domU.mfn); 
-} 
- 
-static inline void notify_daemon(void) 
-{ 
-    /* Use evtchn: this is called early, before irq is set up. */ 
-    notify_remote_via_evtchn(start_info.console.domU.evtchn); 
-} 
- 
-int xencons_ring_send_no_notify(const char *data, unsigned len) 
+} 
+ 
+int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len) 
 { 
     int sent = 0; 
-       struct xencons_interface *intf = xencons_interface(); 
+       struct xencons_interface *intf; 
        XENCONS_RING_IDX cons, prod; 
+ 
+       if (!dev) 
+            intf = xencons_interface(); 
+        else 
+            intf = dev->ring; 
+ 
        cons = intf->out_cons; 
        prod = intf->out_prod; 
        mb(); 
@@ -40,20 +53,27 @@ 
     return sent; 
 } 
 
-int xencons_ring_send(const char *data, unsigned len) 
+int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len) 
 { 
     int sent; 
-    sent = xencons_ring_send_no_notify(data, len); 
-       notify_daemon(); 
 
-       return sent; 
+    sent = xencons_ring_send_no_notify(dev, data, len); 
+    notify_daemon(dev); 
+ 
+    return sent; 
 } 
 
 
 
-static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign) 
+static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *data) 
 { 
 #ifdef HAVE_LIBC 
+       struct consfront_dev *dev = (struct consfront_dev *) data; 
+        int fd = dev ? dev->fd : -1; 
+ 
+        if (fd != -1) 
+            files[fd].read = 1; 
+ 
         wake_up(&console_queue); 
 #else 
        struct xencons_interface *intf = xencons_interface(); 
@@ -72,17 +92,22 @@ 
        mb(); 
        intf->in_cons = cons; 
 
-       notify_daemon(); 
+       notify_daemon(dev); 
 
        xencons_tx(); 
 #endif 
 } 
 
 #ifdef HAVE_LIBC 
-int xencons_ring_avail(void) 
+int xencons_ring_avail(struct consfront_dev *dev) 
 { 
-       struct xencons_interface *intf = xencons_interface(); 
+       struct xencons_interface *intf; 
        XENCONS_RING_IDX cons, prod; 
+ 
+        if (!dev) 
+            intf = xencons_interface(); 
+        else 
+            intf = dev->ring; 
 
        cons = intf->in_cons; 
        prod = intf->in_prod; 
@@ -92,11 +117,16 @@ 
         return prod - cons; 
 } 
 
-int xencons_ring_recv(char *data, unsigned len) 
+int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len) 
 { 
-       struct xencons_interface *intf = xencons_interface(); 
+       struct xencons_interface *intf; 
        XENCONS_RING_IDX cons, prod; 
         unsigned filled = 0; 
+ 
+        if (!dev) 
+            intf = xencons_interface(); 
+        else 
+            intf = dev->ring; 
 
        cons = intf->in_cons; 
        prod = intf->in_prod; 
@@ -111,31 +141,188 @@ 
        mb(); 
         intf->in_cons = cons + filled; 
 
-       notify_daemon(); 
+       notify_daemon(dev); 
 
         return filled; 
 } 
 #endif 
 
-int xencons_ring_init(void) 
+struct consfront_dev *xencons_ring_init(void) 
 { 
        int err; 
+       struct consfront_dev *dev; 
 
        if (!start_info.console.domU.evtchn) 
                return 0; 
 
-       err = bind_evtchn(start_info.console.domU.evtchn, handle_input, 
-                         NULL); 
+       dev = malloc(sizeof(struct consfront_dev)); 
+       memset(dev, 0, sizeof(struct consfront_dev)); 
+       dev->nodename = "device/console"; 
+       dev->dom = 0; 
+       dev->backend = 0; 
+       dev->ring_ref = 0; 
+ 
+#ifdef HAVE_LIBC 
+       dev->fd = -1; 
+#endif 
+       dev->evtchn = start_info.console.domU.evtchn; 
+       dev->ring = (struct xencons_interface *) mfn_to_virt(start_info.console.domU.mfn); 
+ 
+       err = bind_evtchn(dev->evtchn, handle_input, dev); 
        if (err <= 0) { 
                printk("XEN console request chn bind failed %i\n", err); 
-               return err; 
+               return NULL; 
        } 
-        unmask_evtchn(start_info.console.domU.evtchn); 
+        unmask_evtchn(dev->evtchn); 
 
        /* In case we have in-flight data after save/restore... */ 
-       notify_daemon(); 
+       notify_daemon(dev); 
 
-       return 0; 
+       return dev; 
+} 
+ 
+static void free_consfront(struct consfront_dev *dev) 
+{ 
+    mask_evtchn(dev->evtchn); 
+ 
+    free(dev->backend); 
+ 
+    gnttab_end_access(dev->ring_ref); 
+    free_page(dev->ring); 
+ 
+    unbind_evtchn(dev->evtchn); 
+ 
+    free(dev->nodename); 
+    free(dev); 
+} 
+ 
+struct consfront_dev *init_consfront(char *_nodename) 
+{ 
+    xenbus_transaction_t xbt; 
+    char* err; 
+    char* message=NULL; 
+    int retry=0; 
+    char* msg; 
+    char nodename[256]; 
+    char path[256]; 
+    static int consfrontends = 1; 
+    struct consfront_dev *dev; 
+    int res; 
+ 
+    if (!_nodename) 
+        snprintf(nodename, sizeof(nodename), "device/console/%d", consfrontends); 
+    else 
+        strncpy(nodename, _nodename, sizeof(nodename)); 
+ 
+    printk("******************* CONSFRONT for %s **********\n\n\n", nodename); 
+ 
+    dev = malloc(sizeof(*dev)); 
+    memset(dev, 0, sizeof(*dev)); 
+    dev->nodename = strdup(nodename); 
+#ifdef HAVE_LIBC 
+    dev->fd = -1; 
+#endif 
+ 
+    snprintf(path, sizeof(path), "%s/backend-id", nodename); 
+    if ((res = xenbus_read_integer(path)) < 0) 
+        return NULL; 
+    else 
+        dev->dom = res; 
+    evtchn_alloc_unbound(dev->dom, handle_input, dev, &dev->evtchn); 
+ 
+    dev->ring = (struct xencons_interface *) alloc_page(); 
+    memset(dev->ring, 0, PAGE_SIZE); 
+    dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_mfn(dev->ring), 0); 
+ 
+    dev->events = NULL; 
+ 
+again: 
+    err = xenbus_transaction_start(&xbt); 
+    if (err) { 
+        printk("starting transaction\n"); 
+    } 
+ 
+    err = xenbus_printf(xbt, nodename, "ring-ref","%u", 
+                dev->ring_ref); 
+    if (err) { 
+        message = "writing ring-ref"; 
+        goto abort_transaction; 
+    } 
+    err = xenbus_printf(xbt, nodename, 
+                "port", "%u", dev->evtchn); 
+    if (err) { 
+        message = "writing event-channel"; 
+        goto abort_transaction; 
+    } 
+    err = xenbus_printf(xbt, nodename, 
+                "protocol", "%s", XEN_IO_PROTO_ABI_NATIVE); 
+    if (err) { 
+        message = "writing protocol"; 
+        goto abort_transaction; 
+    } 
+ 
+    err = xenbus_printf(xbt, nodename, "type", "%s", "ioemu"); 
+    if (err) { 
+        message = "writing type"; 
+        goto abort_transaction; 
+    } 
+ 
+    snprintf(path, sizeof(path), "%s/state", nodename); 
+    err = xenbus_switch_state(xbt, path, XenbusStateConnected); 
+    if (err) { 
+        message = "switching state"; 
+        goto abort_transaction; 
+    } 
+ 
+ 
+    err = xenbus_transaction_end(xbt, 0, &retry); 
+    if (retry) { 
+            goto again; 
+        printk("completing transaction\n"); 
+    } 
+ 
+    goto done; 
+ 
+abort_transaction: 
+    xenbus_transaction_end(xbt, 1, &retry); 
+    goto error; 
+ 
+done: 
+ 
+    snprintf(path, sizeof(path), "%s/backend", nodename); 
+    msg = xenbus_read(XBT_NIL, path, &dev->backend); 
+    if (msg) { 
+        printk("Error %s when reading the backend path %s\n", msg, path); 
+        goto error; 
+    } 
+ 
+    printk("backend at %s\n", dev->backend); 
+ 
+    { 
+        XenbusState state; 
+        char path[strlen(dev->backend) + 1 + 19 + 1]; 
+        snprintf(path, sizeof(path), "%s/state", dev->backend); 
+ 
+       xenbus_watch_path_token(XBT_NIL, path, path, &dev->events); 
+        msg = NULL; 
+        state = xenbus_read_integer(path); 
+        while (msg == NULL && state < XenbusStateConnected) 
+            msg = xenbus_wait_for_state_change(path, &state, &dev->events); 
+        if (msg != NULL || state != XenbusStateConnected) { 
+            printk("backend not available, state=%d\n", state); 
+            xenbus_unwatch_path(XBT_NIL, path); 
+            goto error; 
+        } 
+    } 
+    unmask_evtchn(dev->evtchn); 
+ 
+    printk("**************************\n"); 
+ 
+    return dev; 
+ 
+error: 
+    free_consfront(dev); 
+    return NULL; 
 } 
 
 void xencons_resume(void) 
diff -r 112680f620bf extras/mini-os/include/console.h 
--- a/extras/mini-os/include/console.h  Mon Jun 08 18:23:57 2009 +0100 
+++ b/extras/mini-os/include/console.h  Thu Jun 11 15:19:43 2009 +0100 
@@ -36,9 +36,32 @@ 
 #ifndef _LIB_CONSOLE_H_ 
 #define _LIB_CONSOLE_H_ 
 
-#include<mini-os/os.h> 
-#include<mini-os/traps.h> 
-#include<stdarg.h> 
+#include <mini-os/os.h> 
+#include <mini-os/traps.h> 
+#include <mini-os/types.h> 
+#include <xen/grant_table.h> 
+#include <xenbus.h> 
+#include <xen/io/console.h> 
+#include <stdarg.h> 
+ 
+struct consfront_dev { 
+    domid_t dom; 
+ 
+    struct xencons_interface *ring; 
+    grant_ref_t ring_ref; 
+    evtchn_port_t evtchn; 
+ 
+    char *nodename; 
+    char *backend; 
+ 
+    xenbus_event_queue events; 
+ 
+#ifdef HAVE_LIBC 
+    int fd; 
+#endif 
+}; 
+ 
+ 
 
 void print(int direct, const char *fmt, va_list args); 
 void printk(const char *fmt, ...); 
@@ -50,16 +73,17 @@ 
 void xencons_tx(void); 
 
 void init_console(void); 
-void console_print(char *data, int length); 
-void fini_console(void); 
+void console_print(struct consfront_dev *dev, char *data, int length); 
+void fini_console(struct consfront_dev *dev); 
 
 /* Low level functions defined in xencons_ring.c */ 
 extern struct wait_queue_head console_queue; 
-int xencons_ring_init(void); 
-int xencons_ring_send(const char *data, unsigned len); 
-int xencons_ring_send_no_notify(const char *data, unsigned len); 
-int xencons_ring_avail(void); 
-int xencons_ring_recv(char *data, unsigned len); 
+struct consfront_dev *xencons_ring_init(void); 
+struct consfront_dev *init_consfront(char *_nodename); 
+int xencons_ring_send(struct consfront_dev *dev, const char *data, unsigned len); 
+int xencons_ring_send_no_notify(struct consfront_dev *dev, const char *data, unsigned len); 
+int xencons_ring_avail(struct consfront_dev *dev); 
+int xencons_ring_recv(struct consfront_dev *dev, char *data, unsigned len); 
 
 
 #endif /* _LIB_CONSOLE_H_ */ 
diff -r 112680f620bf extras/mini-os/include/lib.h 
--- a/extras/mini-os/include/lib.h      Mon Jun 08 18:23:57 2009 +0100 
+++ b/extras/mini-os/include/lib.h      Thu Jun 11 15:19:43 2009 +0100 
@@ -101,6 +101,7 @@ 
 char  *strdup(const char *s); 
 #endif 
 #include <mini-os/console.h> 
+int openpty(void); 
 
 #define RAND_MIX 2654435769U 
 
@@ -183,6 +184,9 @@ 
        struct { 
            struct fbfront_dev *dev; 
        } fb; 
+       struct { 
+           struct consfront_dev *dev; 
+       } cons; 
         struct { 
             /* To each xenbus FD is associated a queue of watch events for this 
              * FD.  */ 
diff -r 112680f620bf extras/mini-os/lib/sys.c 
--- a/extras/mini-os/lib/sys.c  Mon Jun 08 18:23:57 2009 +0100 
+++ b/extras/mini-os/lib/sys.c  Thu Jun 11 15:19:43 2009 +0100 
@@ -167,6 +167,18 @@ 
     return 0; 
 } 
 
+int openpty(void) 
+{ 
+    struct consfront_dev *dev; 
+ 
+    dev = init_consfront(NULL); 
+    dev->fd = alloc_fd(FTYPE_CONSOLE); 
+    files[dev->fd].cons.dev = dev; 
+ 
+    printk("fd(%d) = openpty\n", dev->fd); 
+    return(dev->fd); 
+} 
+ 
 int open(const char *pathname, int flags, ...) 
 { 
     int fs_fd, fd; 
@@ -219,7 +231,7 @@ 
             DEFINE_WAIT(w); 
             while(1) { 
                 add_waiter(w, console_queue); 
-                ret = xencons_ring_recv(buf, nbytes); 
+                ret = xencons_ring_recv(files[fd].cons.dev, buf, nbytes); 
                 if (ret) 
                     break; 
                 schedule(); 
@@ -286,7 +298,7 @@ 
 { 
     switch (files[fd].type) { 
        case FTYPE_CONSOLE: 
-           console_print((char *)buf, nbytes); 
+           console_print(files[fd].cons.dev, (char *)buf, nbytes); 
            return nbytes; 
        case FTYPE_FILE: { 
            ssize_t ret; 
@@ -414,6 +426,10 @@ 
             return 0; 
        case FTYPE_FB: 
             shutdown_fbfront(files[fd].fb.dev); 
+            files[fd].type = FTYPE_NONE; 
+            return 0; 
+        case FTYPE_CONSOLE: 
+            fini_console(files[fd].fb.dev); 
             files[fd].type = FTYPE_NONE; 
             return 0; 
        case FTYPE_NONE: 
@@ -735,7 +751,7 @@ 
            break; 
        case FTYPE_CONSOLE: 
            if (FD_ISSET(i, readfds)) { 
-                if (xencons_ring_avail()) 
+                if (xencons_ring_avail(files[i].cons.dev)) 
                    n++; 
                else 
                    FD_CLR(i, readfds); 
diff -r 112680f620bf stubdom/grub/mini-os.c 
--- a/stubdom/grub/mini-os.c    Mon Jun 08 18:23:57 2009 +0100 
+++ b/stubdom/grub/mini-os.c    Thu Jun 11 15:19:43 2009 +0100 
@@ -329,7 +329,7 @@ 
 serial_hw_put (int _c) 
 { 
   char c = _c; 
-  console_print(&c, 1); 
+  console_print(NULL, &c, 1); 
 } 
 
 int 
@@ -337,7 +337,7 @@ 
 { 
     char key; 
 
-    if (!xencons_ring_avail()) 
+    if (!xencons_ring_avail(NULL)) 
         return -1; 
 
     read(STDIN_FILENO, &key, 1); 
 
_______________________________________________ 
Xen-devel mailing list 
Xen-devel@xxxxxxxxxxxxxxxxxxx 
http://lists.xensource.com/xen-devel 
  
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
 
 |