All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] 1 of 5: secondary consoles in minos
@ 2009-06-11 15:07 Stefano Stabellini
  2009-06-12  4:55 ` Dulloor
  2009-06-16 10:21 ` Keir Fraser
  0 siblings, 2 replies; 5+ messages in thread
From: Stefano Stabellini @ 2009-06-11 15:07 UTC (permalink / raw)
  To: xen-devel

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@eu.citrix.com>

---

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 = curr_char+1;
             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);

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 1 of 5: secondary consoles in minos
  2009-06-11 15:07 [PATCH] 1 of 5: secondary consoles in minos Stefano Stabellini
@ 2009-06-12  4:55 ` Dulloor
  2009-06-15  9:49   ` Stefano Stabellini
  2009-06-16 10:21 ` Keir Fraser
  1 sibling, 1 reply; 5+ messages in thread
From: Dulloor @ 2009-06-12  4:55 UTC (permalink / raw)
  To: Stefano Stabellini; +Cc: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 17065 bytes --]

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@eu.citrix.com> 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@eu.citrix.com>
>
> ---
>
> 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 = curr_char+1;
>             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@lists.xensource.com
> http://lists.xensource.com/xen-devel
>

[-- Attachment #1.2: Type: text/html, Size: 19988 bytes --]

[-- Attachment #2: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 1 of 5: secondary consoles in minos
  2009-06-12  4:55 ` Dulloor
@ 2009-06-15  9:49   ` Stefano Stabellini
  0 siblings, 0 replies; 5+ messages in thread
From: Stefano Stabellini @ 2009-06-15  9:49 UTC (permalink / raw)
  To: Dulloor; +Cc: xen-devel

Dulloor wrote:

> 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.

Good point.

> Also, is it too difficult to create a consfront_dev for the first
> console and get rid of those !dev checks.


No, it is not difficult, I actually wrote it that way the first time.
However I would need to keep the checks anyway because the first console
is used even before init_console is called. Therefore I decided to avoid
calling init_console for the first console and use the !dev checks for it.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 1 of 5: secondary consoles in minos
  2009-06-11 15:07 [PATCH] 1 of 5: secondary consoles in minos Stefano Stabellini
  2009-06-12  4:55 ` Dulloor
@ 2009-06-16 10:21 ` Keir Fraser
  2009-06-16 10:27   ` Keir Fraser
  1 sibling, 1 reply; 5+ messages in thread
From: Keir Fraser @ 2009-06-16 10:21 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel

Patches 1/5 and 3/5 did not apply. I have applied patch 2/5 however.

 -- Keir

On 11/06/2009 18:07, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
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@eu.citrix.com>
> 
> ---
> 
> 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 = curr_char+1;
>              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@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] 1 of 5: secondary consoles in minos
  2009-06-16 10:21 ` Keir Fraser
@ 2009-06-16 10:27   ` Keir Fraser
  0 siblings, 0 replies; 5+ messages in thread
From: Keir Fraser @ 2009-06-16 10:27 UTC (permalink / raw)
  To: Stefano Stabellini, xen-devel

Actually I have applied 3/5 okay after all. Just patch 1/5 needs refreshing
(and of course the qemu patches are handled by Ian Jackson).

 -- Keir

On 16/06/2009 11:21, "Keir Fraser" <keir.fraser@eu.citrix.com> wrote:

> Patches 1/5 and 3/5 did not apply. I have applied patch 2/5 however.
> 
>  -- Keir
> 
> On 11/06/2009 18:07, "Stefano Stabellini" <stefano.stabellini@eu.citrix.com>
> 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@eu.citrix.com>
>> 
>> ---
>> 
>> 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 = curr_char+1;
>>              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@lists.xensource.com
>> http://lists.xensource.com/xen-devel
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-06-16 10:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-11 15:07 [PATCH] 1 of 5: secondary consoles in minos Stefano Stabellini
2009-06-12  4:55 ` Dulloor
2009-06-15  9:49   ` Stefano Stabellini
2009-06-16 10:21 ` Keir Fraser
2009-06-16 10:27   ` Keir Fraser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.