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