WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH] 1 of 5: secondary consoles in minos

To: Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>, xen-devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: Re: [Xen-devel] [PATCH] 1 of 5: secondary consoles in minos
From: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Date: Tue, 16 Jun 2009 11:27:11 +0100
Cc:
Delivery-date: Tue, 16 Jun 2009 03:27:49 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <C65D30D6.7F05%keir.fraser@xxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: Acnqpv2aqEL7OG2QSb+FgSLSZVbNjADxUngEAAAupHE=
Thread-topic: [Xen-devel] [PATCH] 1 of 5: secondary consoles in minos
User-agent: Microsoft-Entourage/12.17.0.090302
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@xxxxxxxxxxxxx> 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@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 = 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@xxxxxxxxxxxxxxxxxxx
>> http://lists.xensource.com/xen-devel
> 
> 
> 
> _______________________________________________
> 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

<Prev in Thread] Current Thread [Next in Thread>