[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] 1 of 5: secondary consoles in minos
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |