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