[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 21/25 v6] xen/arm: vpl011: Add support for multiple consoles in xenconsole
On Mon, 17 Jul 2017, Bhupinder Thakur wrote: > This patch adds the support for multiple consoles and introduces the iterator > functions to operate on multiple consoles. > > This patch is in preparation to support a new vuart console. > > Signed-off-by: Bhupinder Thakur <bhupinder.thakur@xxxxxxxxxx> > --- > CC: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> > CC: Wei Liu <wei.liu2@xxxxxxxxxx> > CC: Stefano Stabellini <sstabellini@xxxxxxxxxx> > CC: Julien Grall <julien.grall@xxxxxxx> > > Changes since v5: > - Split this patch in multiple smaller patches. > > Changes since v4: > - Changes to make event channel handling per console rather than per domain. > > Changes since v3: > - The changes in xenconsole have been split into four patches. This is the > third patch. > > tools/console/daemon/io.c | 174 > +++++++++++++++++++++++++++++++++++----------- > 1 file changed, 134 insertions(+), 40 deletions(-) > > diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c > index 54c91aa..49f085c 100644 > --- a/tools/console/daemon/io.c > +++ b/tools/console/daemon/io.c > @@ -90,12 +90,14 @@ struct buffer { > }; > > struct console { > + const char *const ttyname; > int master_fd; > int master_pollfd_idx; > int slave_fd; > int log_fd; > struct buffer buffer; > - char *xspath; > + const char *const xspath; > + const char *const log_suffix; > int ring_ref; > xenevtchn_handle *xce_handle; > int xce_pollfd_idx; > @@ -107,21 +109,112 @@ struct console { > struct domain *d; > }; > > +struct console_data { > + const char *const xsname; > + const char *const ttyname; > + const char *const log_suffix; > +}; > + > +static struct console_data console_data[] = { > + { > + .xsname = "/console", > + .ttyname = "tty", > + .log_suffix = "", > + }, > +}; > + > +#define MAX_CONSOLE (sizeof(console_data)/sizeof(struct console_data)) > + > struct domain { > int domid; > bool is_dead; > unsigned last_seen; > struct domain *next; > - struct console console; > + struct console console[MAX_CONSOLE]; > }; > > static struct domain *dom_head; > > +typedef void (*VOID_ITER_FUNC_ARG1)(struct console *); > +typedef bool (*BOOL_ITER_FUNC_ARG1)(struct console *); > +typedef int (*INT_ITER_FUNC_ARG1)(struct console *); > +typedef void (*VOID_ITER_FUNC_ARG2)(struct console *, void *); > +typedef int (*INT_ITER_FUNC_ARG3)(struct console *, > + struct domain *dom, void **); > + > static inline bool console_enabled(struct console *con) > { > return con->local_port != -1; > } > > +static inline void console_iter_void_arg1(struct domain *d, > + VOID_ITER_FUNC_ARG1 iter_func) > +{ > + int i = 0; > + struct console *con = &d->console[0]; > + > + for (i = 0; i < MAX_CONSOLE; i++, con++) > + { This is the wrong code style, it should be "for (X) {" > + iter_func(con); > + } > +} > + > +static inline void console_iter_void_arg2(struct domain *d, > + VOID_ITER_FUNC_ARG2 iter_func, > + void *iter_data) > +{ > + int i = 0; > + struct console *con = &d->console[0]; > + > + for (i = 0; i < MAX_CONSOLE; i++, con++) > + { > + iter_func(con, iter_data); > + } > +} > + > +static inline bool console_iter_bool_arg1(struct domain *d, > + BOOL_ITER_FUNC_ARG1 iter_func) > +{ > + int i = 0; > + struct console *con = &d->console[0]; > + > + for (i = 0; i < MAX_CONSOLE; i++, con++) > + { > + if (iter_func(con)) > + return true; > + } > + return false; > +} > + > +static inline int console_iter_int_arg1(struct domain *d, > + INT_ITER_FUNC_ARG1 iter_func) > +{ > + int i = 0; > + struct console *con = &d->console[0]; > + > + for (i = 0; i < MAX_CONSOLE; i++, con++) > + { > + if (iter_func(con)) > + return 1; > + } > + return 0; > +} > + > +static inline int console_iter_int_arg3(struct domain *d, > + INT_ITER_FUNC_ARG3 iter_func, > + void **iter_data) > +{ > + int i = 0; > + struct console *con = &d->console[0]; > + > + for (i = 0; i < MAX_CONSOLE; i++, con++) > + { > + if (iter_func(con, d, iter_data)) > + return 1; > + } > + return 0; > +} > + > static int write_all(int fd, const char* buf, size_t len) > { > while (len) { > @@ -336,7 +429,7 @@ static int create_console_log(struct console *con) > return -1; > } > > - snprintf(logfile, PATH_MAX-1, "%s/guest-%s.log", log_dir, data); > + snprintf(logfile, PATH_MAX-1, "%s/guest-%s%s.log", log_dir, data, > con->log_suffix); > free(data); > logfile[PATH_MAX-1] = '\0'; > > @@ -488,7 +581,7 @@ static int console_create_tty(struct console *con) > } > free(path); > > - success = (asprintf(&path, "%s/tty", con->xspath) != -1); > + success = (asprintf(&path, "%s/%s", con->xspath, con->ttyname) != -1); > if (!success) > goto out; > success = xs_write(xs, XBT_NULL, path, slave, strlen(slave)); > @@ -654,13 +747,13 @@ static bool watch_domain(struct domain *dom, bool watch) > { > char domid_str[3 + MAX_STRLEN(dom->domid)]; > bool success; > - struct console *con = &dom->console; > + struct console *con = &dom->console[0]; > > snprintf(domid_str, sizeof(domid_str), "dom%u", dom->domid); > if (watch) { > success = xs_watch(xs, con->xspath, domid_str); > if (success) > - console_create_ring(con); > + console_iter_int_arg1(dom, console_create_ring); > else > xs_unwatch(xs, con->xspath, domid_str); > } else { > @@ -670,15 +763,18 @@ static bool watch_domain(struct domain *dom, bool watch) > return success; > } > > -static int console_init(struct console *con, struct domain *dom) > +static int console_init(struct console *con, struct domain *dom, void **data) > { > char *s; > + int err = -1; > struct timespec ts; > + struct console_data **con_data = (struct console_data **)data; > + char *xsname, *xspath; > > if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) { > dolog(LOG_ERR, "Cannot get time of day %s:%s:L%d", > __FILE__, __FUNCTION__, __LINE__); > - return NULL; > + return err; > } > > con->master_fd = -1; > @@ -691,30 +787,37 @@ static int console_init(struct console *con, struct > domain *dom) > con->xce_pollfd_idx = -1; > con->next_period = ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / > 1000000) + RATE_LIMIT_PERIOD; > con->d = dom; > - con->xspath = xs_get_domain_path(xs, dom->domid); > - s = realloc(con->xspath, strlen(con->xspath) + > - strlen("/console") + 1); > + *(char **)&con->ttyname = (char *)(*con_data)->ttyname; > + *(char **)&con->log_suffix = (char *)(*con_data)->log_suffix; This is horrible, please remove the consts and the casts. > + con->optional = (*con_data)->optional; > + con->prefer_gnttab = (*con_data)->prefer_gnttab; > + xsname = (char *)(*con_data)->xsname; > + xspath = xs_get_domain_path(xs, dom->domid); > + s = realloc(xspath, strlen(xspath) + > + strlen(xsname) + 1); > if (s) > { > - con->xspath = s; > - strcat(con->xspath, "/console"); > + xspath = s; > + strcat(xspath, xsname); > + *(char **)&con->xspath = xspath; same here > err = 0; > } > > + (*con_data)++; > + > return err; > } > > static void console_free(struct console *con) > { > if (con->xspath) > - free(con->xspath); > + free((char *)con->xspath); same here > } > > static struct domain *create_domain(int domid) > { > struct domain *dom; > - char *s; > - struct console *con; > + struct console_data *con_data = &console_data[0]; > > dom = calloc(1, sizeof *dom); > if (dom == NULL) { > @@ -724,9 +827,8 @@ static struct domain *create_domain(int domid) > } > > dom->domid = domid; > - con = &dom->console; > > - if (console_init(con, dom)) > + if (console_iter_int_arg3(dom, console_init, (void **)&con_data)) > goto out; > > if (!watch_domain(dom, true)) > @@ -739,7 +841,7 @@ static struct domain *create_domain(int domid) > > return dom; > out: > - console_free(con); > + console_iter_void_arg1(dom, console_free); > free(dom); > return NULL; > } > @@ -784,18 +886,16 @@ static void console_cleanup(struct console *con) > > if (con->xspath) > { > - free(con->xspath); > - con->xspath = NULL; > + free((char *)con->xspath); > + *(char **)&con->xspath = (char *)NULL; same here > } > } > > static void cleanup_domain(struct domain *d) > { > - struct console *con = &d->console; > - > - console_close_tty(con); > + console_iter_void_arg1(d, console_close_tty); > > - console_cleanup(con); > + console_iter_void_arg1(d, console_cleanup); > > remove_domain(d); > } > @@ -810,12 +910,10 @@ static void console_close_evtchn(struct console *con) > > static void shutdown_domain(struct domain *d) > { > - struct console *con = &d->console; > - > d->is_dead = true; > watch_domain(d, false); > - console_unmap_interface(con); > - console_close_evtchn(con); > + console_iter_void_arg1(d, console_unmap_interface); > + console_iter_void_arg1(d, console_close_evtchn); > } > > static unsigned enum_pass = 0; > @@ -1011,7 +1109,7 @@ static void handle_xs(void) > /* We may get watches firing for domains that have recently > been removed, so dom may be NULL here. */ > if (dom && dom->is_dead == false) > - console_create_ring(&dom->console); > + console_iter_int_arg1(dom, console_create_ring); > } > > free(vec); > @@ -1067,9 +1165,7 @@ static void handle_log_reload(void) > if (log_guest) { > struct domain *d; > for (d = dom_head; d; d = d->next) { > - struct console *con = &d->console; > - > - console_open_log(con); > + console_iter_void_arg1(d, console_open_log); > } > } > > @@ -1233,13 +1329,12 @@ void handle_io(void) > /* Re-calculate any event counter allowances & unblock > domains with new allowance */ > for (d = dom_head; d; d = d->next) { > - struct console *con = &d->console; > > - console_evtchn_unmask(con, (void *)now); > + console_iter_void_arg2(d, console_evtchn_unmask, (void > *)now); > > - add_console_evtchn_fd(con, (void *)&next_timeout); > + console_iter_void_arg2(d, add_console_evtchn_fd, (void > *)&next_timeout); > > - add_console_tty_fd(con); > + console_iter_void_arg1(d, add_console_tty_fd); > } > > /* If any domain has been rate limited, we need to work > @@ -1300,13 +1395,12 @@ void handle_io(void) > } > > for (d = dom_head; d; d = n) { > - struct console *con = &d->console; > > n = d->next; > > - handle_console_ring(con); > + console_iter_void_arg1(d, handle_console_ring); > > - handle_console_tty(con); > + console_iter_void_arg1(d, handle_console_tty); > > if (d->last_seen != enum_pass) > shutdown_domain(d); > -- > 2.7.4 > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |