[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] xenconsoled: add ability to log guest consoles
We already have a logging capability in xenconsoled, albeit enabled globally via a command-line switch and no direct control over log-file naming. But do we really need a second method? K. On 20/05/2010 13:08, "Ian Campbell" <ian.campbell@xxxxxxxxxx> wrote: > This is useful as a debugging aid when guests die too quickly to catch > their console or produce so much spew that the ring has been recycled > etc. > > Logging is enable by writing the filename of the logfile to the node > /local/logconsole/<domid> in xenstore. > > Writing the empty string or removing the node stops logging. > > Writing the same path to the node causes the daemon to close and > reopen the file -- this can be used to logrotate the file. > > The /local/logconsole directory should not be removed as otherwise all > console logging will not work until xenconsoled is restarted. > > Logging can also be enabled by writing a filename containing %d to the > node /local/logconsole/@ in xenstore. This enables logging for > domains for which no /local/logconsole/<domid> node exists. The > filename is expanded by replacing %d with the domain id. > > Original patch by Christian Limpach. > > Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > > diff -r 2c5201796a2c -r 4997d5743bc3 tools/console/daemon/io.c > --- a/tools/console/daemon/io.c Thu May 20 12:55:56 2010 +0100 > +++ b/tools/console/daemon/io.c Thu May 20 13:07:25 2010 +0100 > @@ -97,7 +97,11 @@ > struct xencons_interface *interface; > int event_count; > long long next_period; > + FILE *logfile; > }; > + > +static void update_logconsole(struct domain *); > +static char *wildcard_logfile = NULL; > > static struct domain *dom_head; > > @@ -152,6 +156,7 @@ > struct buffer *buffer = &dom->buffer; > XENCONS_RING_IDX cons, prod, size; > struct xencons_interface *intf = dom->interface; > + size_t begin; > > cons = intf->out_cons; > prod = intf->out_prod; > @@ -170,9 +175,15 @@ > } > } > > + begin = buffer->size; > while (cons != prod) > buffer->data[buffer->size++] = intf->out[ > MASK_XENCONS_IDX(cons++, intf->out)]; > + if (dom->logfile && buffer->size != begin) { > + fwrite(&buffer->data[begin], buffer->size - begin, 1, > + dom->logfile); > + fflush(dom->logfile); > + } > > xen_mb(); > intf->out_cons = cons; > @@ -699,6 +710,9 @@ > if (!watch_domain(dom, true)) > goto out; > > + dom->logfile = NULL; > + update_logconsole(dom); > + > dom->next = dom_head; > dom_head = dom; > > @@ -725,12 +739,17 @@ > static void remove_domain(struct domain *dom) > { > struct domain **pp; > + FILE *oldfile; > > dolog(LOG_DEBUG, "Removing domain-%d", dom->domid); > > for (pp = &dom_head; *pp; pp = &(*pp)->next) { > if (dom == *pp) { > *pp = dom->next; > + oldfile = dom->logfile; > + dom->logfile = NULL; > + if (oldfile) > + fclose(oldfile); > free(dom); > break; > } > @@ -782,6 +801,36 @@ > } > domid = dominfo.domid + 1; > } > +} > + > +static void update_logconsole(struct domain *dom) > +{ > + char *fname = NULL, *path = NULL; > + FILE *oldfile; > + > + oldfile = dom->logfile; > + > + if (asprintf(&path, "/local/logconsole/%d", dom->domid) == -1) > + goto out; > + > + fname = xs_read(xs, XBT_NULL, path, NULL); > + if (!fname && wildcard_logfile) > + asprintf(&fname, wildcard_logfile, dom->domid); > + if (!fname || !fname[0]) > + goto out; > + > + dom->logfile = fopen(fname, "a"); > + if (!dom->logfile) > + dolog(LOG_ERR, "fopen %s failed", fname); > + > + out: > + if (oldfile && dom->logfile == oldfile) { > + dom->logfile = NULL; > + fclose(oldfile); > + } > + free(fname); > + free(path); > + return; > } > > static int ring_free_bytes(struct domain *dom) > @@ -909,6 +958,19 @@ > been removed, so dom may be NULL here. */ > if (dom && dom->is_dead == false) > domain_create_ring(dom); > + } else if (!strcmp(vec[XS_WATCH_TOKEN], "logconsole")) { > + if (sscanf(vec[XS_WATCH_PATH], "/local/logconsole/%u", > + &domid) == 1) { > + dom = lookup_domain(domid); > + if (dom && dom->is_dead == false) > + update_logconsole(dom); > + } else if (!strcmp(vec[XS_WATCH_PATH], > + "/local/logconsole/@")) { > + free(wildcard_logfile); > + wildcard_logfile = xs_read(xs, XBT_NULL, > + "/local/logconsole/@", > + NULL); > + } > } > > free(vec); > @@ -1128,6 +1190,17 @@ > log_hv_evtchn = -1; > } > > +void watch_logconsole(void) > +{ > + bool success; > + > + success = xs_watch(xs, "/local/logconsole", "logconsole"); > + if (!success) > + dolog(LOG_ERR, "logconsole watch failed"); > + wildcard_logfile = xs_read(xs, XBT_NULL, "/local/logconsole/@", NULL); > +} > + > + > /* > * Local variables: > * c-file-style: "linux" > diff -r 2c5201796a2c -r 4997d5743bc3 tools/console/daemon/io.h > --- a/tools/console/daemon/io.h Thu May 20 12:55:56 2010 +0100 > +++ b/tools/console/daemon/io.h Thu May 20 13:07:25 2010 +0100 > @@ -23,5 +23,6 @@ > > void enum_domains(void); > void handle_io(void); > +void watch_logconsole(void); > > #endif > diff -r 2c5201796a2c -r 4997d5743bc3 tools/console/daemon/main.c > --- a/tools/console/daemon/main.c Thu May 20 12:55:56 2010 +0100 > +++ b/tools/console/daemon/main.c Thu May 20 13:07:25 2010 +0100 > @@ -159,6 +159,8 @@ > if (!xen_setup()) > exit(1); > > + watch_logconsole(); > + > enum_domains(); > > handle_io(); > > _______________________________________________ > 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 |