This patch guts the xenconsoled daemon, removing all code related to processing
the paravirt guest text console. This capability is now provided by QEMU so
using
a separate daemon is redundant. The only thing left in xenconsoled is the code
for
persistently logging the hypervisor messages. If this isn't desired, then there
is
no need to launch xenconsoled at all. In fact this code could easily just be
pushed
into XenD it is so small.
a/tools/console/daemon/io.c | 831 -------------------------------------------
a/tools/console/daemon/io.h | 27 -
tools/console/daemon/main.c | 62 ++-
tools/console/daemon/utils.c | 28 -
tools/console/daemon/utils.h | 3
5 files changed, 46 insertions(+), 905 deletions(-)
Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx>
Dan.
diff -r fda4d94ca31d tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Aug 14 19:55:04 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) International Business Machines Corp., 2005
- * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
- *
- * Xen Console Daemon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define _GNU_SOURCE
-
-#include "utils.h"
-#include "io.h"
-#include <xs.h>
-#include <xen/io/console.h>
-#include <xenctrl.h>
-
-#include <malloc.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <sys/select.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <termios.h>
-#include <stdarg.h>
-#include <sys/mman.h>
-
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-/* Each 10 bits takes ~ 3 digits, plus one, plus one for nul terminator. */
-#define MAX_STRLEN(x) ((sizeof(x) * CHAR_BIT + CHAR_BIT-1) / 10 * 3 + 2)
-
-extern int log_reload;
-extern int log_guest;
-extern int log_hv;
-extern char *log_dir;
-
-static int log_hv_fd = -1;
-static int xc_handle = -1;
-
-struct buffer
-{
- char *data;
- size_t consumed;
- size_t size;
- size_t capacity;
- size_t max_capacity;
-};
-
-struct domain
-{
- int domid;
- int tty_fd;
- int log_fd;
- bool is_dead;
- struct buffer buffer;
- struct domain *next;
- char *conspath;
- char *serialpath;
- int use_consolepath;
- int ring_ref;
- evtchn_port_t local_port;
- evtchn_port_t remote_port;
- int xce_handle;
- struct xencons_interface *interface;
-};
-
-static struct domain *dom_head;
-
-static void buffer_append(struct domain *dom)
-{
- struct buffer *buffer = &dom->buffer;
- XENCONS_RING_IDX cons, prod, size;
- struct xencons_interface *intf = dom->interface;
-
- cons = intf->out_cons;
- prod = intf->out_prod;
- mb();
-
- size = prod - cons;
- if ((size == 0) || (size > sizeof(intf->out)))
- return;
-
- if ((buffer->capacity - buffer->size) < size) {
- buffer->capacity += (size + 1024);
- buffer->data = realloc(buffer->data, buffer->capacity);
- if (buffer->data == NULL) {
- dolog(LOG_ERR, "Memory allocation failed");
- exit(ENOMEM);
- }
- }
-
- while (cons != prod)
- buffer->data[buffer->size++] = intf->out[
- MASK_XENCONS_IDX(cons++, intf->out)];
-
- mb();
- intf->out_cons = cons;
- xc_evtchn_notify(dom->xce_handle, dom->local_port);
-
- /* Get the data to the logfile as early as possible because if
- * no one is listening on the console pty then it will fill up
- * and handle_tty_write will stop being called.
- */
- if (dom->log_fd != -1) {
- int len = write(dom->log_fd,
- buffer->data + buffer->size - size,
- size);
- if (len < 0)
- dolog(LOG_ERR, "Write to log failed on domain %d: %d
(%s)\n",
- dom->domid, errno, strerror(errno));
- }
-
- if (buffer->max_capacity &&
- buffer->size > buffer->max_capacity) {
- /* Discard the middle of the data. */
-
- size_t over = buffer->size - buffer->max_capacity;
- char *maxpos = buffer->data + buffer->max_capacity;
-
- memmove(maxpos - over, maxpos, over);
- buffer->data = realloc(buffer->data, buffer->max_capacity);
- buffer->size = buffer->capacity = buffer->max_capacity;
-
- if (buffer->consumed > buffer->max_capacity - over)
- buffer->consumed = buffer->max_capacity - over;
- }
-}
-
-static bool buffer_empty(struct buffer *buffer)
-{
- return buffer->size == 0;
-}
-
-static void buffer_advance(struct buffer *buffer, size_t len)
-{
- buffer->consumed += len;
- if (buffer->consumed == buffer->size) {
- buffer->consumed = 0;
- buffer->size = 0;
- }
-}
-
-static bool domain_is_valid(int domid)
-{
- bool ret;
- xc_dominfo_t info;
-
- ret = (xc_domain_getinfo(xc, domid, 1, &info) == 1 &&
- info.domid == domid);
-
- return ret;
-}
-
-static int create_hv_log(void)
-{
- char logfile[PATH_MAX];
- int fd;
- snprintf(logfile, PATH_MAX-1, "%s/hypervisor.log", log_dir);
- logfile[PATH_MAX-1] = '\0';
-
- fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
- if (fd == -1)
- dolog(LOG_ERR, "Failed to open log %s: %d (%s)",
- logfile, errno, strerror(errno));
- return fd;
-}
-
-static int create_domain_log(struct domain *dom)
-{
- char logfile[PATH_MAX];
- char *namepath, *data, *s;
- int fd;
- unsigned int len;
-
- namepath = xs_get_domain_path(xs, dom->domid);
- s = realloc(namepath, strlen(namepath) + 6);
- if (s == NULL) {
- free(namepath);
- return -1;
- }
- namepath = s;
- strcat(namepath, "/name");
- data = xs_read(xs, XBT_NULL, namepath, &len);
- if (!data)
- return -1;
- if (!len) {
- free(data);
- return -1;
- }
-
- snprintf(logfile, PATH_MAX-1, "%s/guest-%s.log", log_dir, data);
- free(data);
- logfile[PATH_MAX-1] = '\0';
-
- fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
- if (fd == -1)
- dolog(LOG_ERR, "Failed to open log %s: %d (%s)",
- logfile, errno, strerror(errno));
- return fd;
-}
-
-
-static int domain_create_tty(struct domain *dom)
-{
- char *path;
- int master;
- bool success;
-
- if ((master = open("/dev/ptmx",O_RDWR|O_NOCTTY)) == -1 ||
- grantpt(master) == -1 || unlockpt(master) == -1) {
- dolog(LOG_ERR, "Failed to create tty for domain-%d",
- dom->domid);
- master = -1;
- } else {
- const char *slave = ptsname(master);
- struct termios term;
- char *data;
- unsigned int len;
-
- if (tcgetattr(master, &term) != -1) {
- cfmakeraw(&term);
- tcsetattr(master, TCSAFLUSH, &term);
- }
-
- if (dom->use_consolepath) {
- success = asprintf(&path, "%s/limit", dom->conspath) !=
- -1;
- if (!success)
- goto out;
- data = xs_read(xs, XBT_NULL, path, &len);
- if (data) {
- dom->buffer.max_capacity = strtoul(data, 0, 0);
- free(data);
- }
- free(path);
- }
-
- success = asprintf(&path, "%s/limit", dom->serialpath) != -1;
- if (!success)
- goto out;
- data = xs_read(xs, XBT_NULL, path, &len);
- if (data) {
- dom->buffer.max_capacity = strtoul(data, 0, 0);
- free(data);
- }
- free(path);
-
- success = asprintf(&path, "%s/tty", dom->serialpath) != -1;
- if (!success)
- goto out;
- success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
- free(path);
- if (!success)
- goto out;
-
- if (dom->use_consolepath) {
- success = asprintf(&path, "%s/tty", dom->conspath) !=
- -1;
- if (!success)
- goto out;
- success = xs_write(xs, XBT_NULL, path, slave,
- strlen(slave));
- free(path);
- if (!success)
- goto out;
- }
-
- if (fcntl(master, F_SETFL, O_NONBLOCK) == -1)
- goto out;
- }
-
- return master;
- out:
- close(master);
- return -1;
-}
-
-/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
-int xs_gather(struct xs_handle *xs, const char *dir, ...)
-{
- va_list ap;
- const char *name;
- char *path;
- int ret = 0;
-
- va_start(ap, dir);
- while (ret == 0 && (name = va_arg(ap, char *)) != NULL) {
- const char *fmt = va_arg(ap, char *);
- void *result = va_arg(ap, void *);
- char *p;
-
- if (asprintf(&path, "%s/%s", dir, name) == -1) {
- ret = ENOMEM;
- break;
- }
- p = xs_read(xs, XBT_NULL, path, NULL);
- free(path);
- if (p == NULL) {
- ret = ENOENT;
- break;
- }
- if (fmt) {
- if (sscanf(p, fmt, result) == 0)
- ret = EINVAL;
- free(p);
- } else
- *(char **)result = p;
- }
- va_end(ap);
- return ret;
-}
-
-static int domain_create_ring(struct domain *dom)
-{
- int err, remote_port, ring_ref, rc;
-
- err = xs_gather(xs, dom->serialpath,
- "ring-ref", "%u", &ring_ref,
- "port", "%i", &remote_port,
- NULL);
- if (err) {
- err = xs_gather(xs, dom->conspath,
- "ring-ref", "%u", &ring_ref,
- "port", "%i", &remote_port,
- NULL);
- if (err)
- goto out;
- dom->use_consolepath = 1;
- } else
- dom->use_consolepath = 0;
-
- if ((ring_ref == dom->ring_ref) && (remote_port == dom->remote_port))
- goto out;
-
- if (ring_ref != dom->ring_ref) {
- if (dom->interface != NULL)
- munmap(dom->interface, getpagesize());
- dom->interface = xc_map_foreign_range(
- xc, dom->domid, getpagesize(),
- PROT_READ|PROT_WRITE,
- (unsigned long)ring_ref);
- if (dom->interface == NULL) {
- err = EINVAL;
- goto out;
- }
- dom->ring_ref = ring_ref;
- }
-
- dom->local_port = -1;
- dom->remote_port = -1;
- if (dom->xce_handle != -1)
- xc_evtchn_close(dom->xce_handle);
-
- /* Opening evtchn independently for each console is a bit
- * wasteful, but that's how the code is structured... */
- dom->xce_handle = xc_evtchn_open();
- if (dom->xce_handle == -1) {
- err = errno;
- goto out;
- }
-
- rc = xc_evtchn_bind_interdomain(dom->xce_handle,
- dom->domid, remote_port);
-
- if (rc == -1) {
- err = errno;
- xc_evtchn_close(dom->xce_handle);
- dom->xce_handle = -1;
- goto out;
- }
- dom->local_port = rc;
- dom->remote_port = remote_port;
-
- if (dom->tty_fd == -1) {
- dom->tty_fd = domain_create_tty(dom);
-
- if (dom->tty_fd == -1) {
- err = errno;
- xc_evtchn_close(dom->xce_handle);
- dom->xce_handle = -1;
- dom->local_port = -1;
- dom->remote_port = -1;
- goto out;
- }
- }
-
- if (log_guest)
- dom->log_fd = create_domain_log(dom);
-
- out:
- return err;
-}
-
-static bool watch_domain(struct domain *dom, bool watch)
-{
- char domid_str[3 + MAX_STRLEN(dom->domid)];
- bool success;
-
- sprintf(domid_str, "dom%u", dom->domid);
- if (watch) {
- success = xs_watch(xs, dom->serialpath, domid_str);
- if (success) {
- success = xs_watch(xs, dom->conspath, domid_str);
- if (success)
- domain_create_ring(dom);
- else
- xs_unwatch(xs, dom->serialpath, domid_str);
- }
- } else {
- success = xs_unwatch(xs, dom->serialpath, domid_str);
- success = xs_unwatch(xs, dom->conspath, domid_str);
- }
-
- return success;
-}
-
-
-static struct domain *create_domain(int domid)
-{
- struct domain *dom;
- char *s;
-
- dom = (struct domain *)malloc(sizeof(struct domain));
- if (dom == NULL) {
- dolog(LOG_ERR, "Out of memory %s:%s():L%d",
- __FILE__, __FUNCTION__, __LINE__);
- exit(ENOMEM);
- }
-
- dom->domid = domid;
-
- dom->serialpath = xs_get_domain_path(xs, dom->domid);
- s = realloc(dom->serialpath, strlen(dom->serialpath) +
- strlen("/serial/0") + 1);
- if (s == NULL)
- goto out;
- dom->serialpath = s;
- strcat(dom->serialpath, "/serial/0");
-
- dom->conspath = xs_get_domain_path(xs, dom->domid);
- s = realloc(dom->conspath, strlen(dom->conspath) +
- strlen("/console") + 1);
- if (s == NULL)
- goto out;
- dom->conspath = s;
- strcat(dom->conspath, "/console");
-
- dom->tty_fd = -1;
- dom->log_fd = -1;
-
- dom->is_dead = false;
- dom->buffer.data = 0;
- dom->buffer.consumed = 0;
- dom->buffer.size = 0;
- dom->buffer.capacity = 0;
- dom->buffer.max_capacity = 0;
- dom->next = NULL;
-
- dom->ring_ref = -1;
- dom->local_port = -1;
- dom->remote_port = -1;
- dom->interface = NULL;
- dom->xce_handle = -1;
-
- if (!watch_domain(dom, true))
- goto out;
-
- dom->next = dom_head;
- dom_head = dom;
-
- dolog(LOG_DEBUG, "New domain %d", domid);
-
- return dom;
- out:
- free(dom->serialpath);
- free(dom->conspath);
- free(dom);
- return NULL;
-}
-
-static struct domain *lookup_domain(int domid)
-{
- struct domain *dom;
-
- for (dom = dom_head; dom; dom = dom->next)
- if (dom->domid == domid)
- return dom;
- return NULL;
-}
-
-static void remove_domain(struct domain *dom)
-{
- struct domain **pp;
-
- dolog(LOG_DEBUG, "Removing domain-%d", dom->domid);
-
- for (pp = &dom_head; *pp; pp = &(*pp)->next) {
- if (dom == *pp) {
- *pp = dom->next;
- free(dom);
- break;
- }
- }
-}
-
-static void cleanup_domain(struct domain *d)
-{
- if (d->tty_fd != -1) {
- close(d->tty_fd);
- d->tty_fd = -1;
- }
- if (d->log_fd != -1) {
- close(d->log_fd);
- d->log_fd = -1;
- }
-
- free(d->buffer.data);
- d->buffer.data = NULL;
-
- free(d->serialpath);
- d->serialpath = NULL;
-
- free(d->conspath);
- d->conspath = NULL;
-
- remove_domain(d);
-}
-
-static void shutdown_domain(struct domain *d)
-{
- d->is_dead = true;
- watch_domain(d, false);
- if (d->interface != NULL)
- munmap(d->interface, getpagesize());
- d->interface = NULL;
- if (d->xce_handle != -1)
- xc_evtchn_close(d->xce_handle);
- d->xce_handle = -1;
- cleanup_domain(d);
-}
-
-void enum_domains(void)
-{
- int domid = 1;
- xc_dominfo_t dominfo;
- struct domain *dom;
-
- while (xc_domain_getinfo(xc, domid, 1, &dominfo) == 1) {
- dom = lookup_domain(dominfo.domid);
- if (dominfo.dying) {
- if (dom)
- shutdown_domain(dom);
- } else {
- if (dom == NULL)
- create_domain(dominfo.domid);
- }
- domid = dominfo.domid + 1;
- }
-}
-
-static int ring_free_bytes(struct domain *dom)
-{
- struct xencons_interface *intf = dom->interface;
- XENCONS_RING_IDX cons, prod, space;
-
- cons = intf->in_cons;
- prod = intf->in_prod;
- mb();
-
- space = prod - cons;
- if (space > sizeof(intf->in))
- return 0; /* ring is screwed: ignore it */
-
- return (sizeof(intf->in) - space);
-}
-
-static void handle_tty_read(struct domain *dom)
-{
- ssize_t len = 0;
- char msg[80];
- int i;
- struct xencons_interface *intf = dom->interface;
- XENCONS_RING_IDX prod;
-
- len = ring_free_bytes(dom);
- if (len == 0)
- return;
-
- if (len > sizeof(msg))
- len = sizeof(msg);
-
- len = read(dom->tty_fd, msg, len);
- if (len < 1) {
- close(dom->tty_fd);
- dom->tty_fd = -1;
-
- if (domain_is_valid(dom->domid)) {
- dom->tty_fd = domain_create_tty(dom);
- } else {
- shutdown_domain(dom);
- }
- } else if (domain_is_valid(dom->domid)) {
- prod = intf->in_prod;
- for (i = 0; i < len; i++) {
- intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
- msg[i];
- }
- wmb();
- intf->in_prod = prod;
- xc_evtchn_notify(dom->xce_handle, dom->local_port);
- } else {
- close(dom->tty_fd);
- dom->tty_fd = -1;
- shutdown_domain(dom);
- }
-}
-
-static void handle_tty_write(struct domain *dom)
-{
- ssize_t len;
-
- len = write(dom->tty_fd, dom->buffer.data + dom->buffer.consumed,
- dom->buffer.size - dom->buffer.consumed);
- if (len < 1) {
- dolog(LOG_DEBUG, "Write failed on domain %d: %zd, %d\n",
- dom->domid, len, errno);
-
- close(dom->tty_fd);
- dom->tty_fd = -1;
-
- if (domain_is_valid(dom->domid)) {
- dom->tty_fd = domain_create_tty(dom);
- } else {
- shutdown_domain(dom);
- }
- } else {
- buffer_advance(&dom->buffer, len);
- }
-}
-
-static void handle_ring_read(struct domain *dom)
-{
- evtchn_port_t port;
-
- if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
- return;
-
- buffer_append(dom);
-
- (void)xc_evtchn_unmask(dom->xce_handle, port);
-}
-
-static void handle_xs(void)
-{
- char **vec;
- int domid;
- struct domain *dom;
- unsigned int num;
-
- vec = xs_read_watch(xs, &num);
- if (!vec)
- return;
-
- if (!strcmp(vec[XS_WATCH_TOKEN], "domlist"))
- enum_domains();
- else if (sscanf(vec[XS_WATCH_TOKEN], "dom%u", &domid) == 1) {
- dom = lookup_domain(domid);
- /* We may get watches firing for domains that have recently
- been removed, so dom may be NULL here. */
- if (dom && dom->is_dead == false)
- domain_create_ring(dom);
- }
-
- free(vec);
-}
-
-static void handle_hv_logs(void)
-{
- char buffer[1024*16];
- char *bufptr = buffer;
- unsigned int size = sizeof(buffer);
- if (xc_readconsolering(xc_handle, &bufptr, &size, 1) == 0) {
- int len = write(log_hv_fd, buffer, size);
- if (len < 0)
- dolog(LOG_ERR, "Failed to write hypervisor log: %d
(%s)",
- errno, strerror(errno));
- }
-}
-
-static void handle_log_reload(void)
-{
- if (log_guest) {
- struct domain *d;
- for (d = dom_head; d; d = d->next) {
- if (d->log_fd != -1)
- close(d->log_fd);
- d->log_fd = create_domain_log(d);
- }
- }
-
- if (log_hv) {
- if (log_hv_fd != -1)
- close(log_hv_fd);
- log_hv_fd = create_hv_log();
- }
-}
-
-void handle_io(void)
-{
- fd_set readfds, writefds;
- int ret;
-
- if (log_hv) {
- xc_handle = xc_interface_open();
- if (xc_handle == -1)
- dolog(LOG_ERR, "Failed to open xc handle: %d (%s)",
- errno, strerror(errno));
- else
- log_hv_fd = create_hv_log();
- }
-
- for (;;) {
- struct domain *d, *n;
- struct timeval timeout = { 1, 0 }; /* Read HV logs every 1
second */
- int max_fd = -1;
-
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
-
- FD_SET(xs_fileno(xs), &readfds);
- max_fd = MAX(xs_fileno(xs), max_fd);
-
- for (d = dom_head; d; d = d->next) {
- if (d->xce_handle != -1) {
- int evtchn_fd = xc_evtchn_fd(d->xce_handle);
- FD_SET(evtchn_fd, &readfds);
- max_fd = MAX(evtchn_fd, max_fd);
- }
-
- if (d->tty_fd != -1) {
- if (!d->is_dead && ring_free_bytes(d))
- FD_SET(d->tty_fd, &readfds);
-
- if (!buffer_empty(&d->buffer))
- FD_SET(d->tty_fd, &writefds);
- max_fd = MAX(d->tty_fd, max_fd);
- }
- }
-
- /* XXX I wish we didn't have to busy wait for hypervisor logs
- * but there's no obvious way to get event channel notifications
- * for new HV log data as we can with guest */
- ret = select(max_fd + 1, &readfds, &writefds, 0,
- log_hv_fd != -1 ? &timeout : NULL);
-
- if (log_reload) {
- handle_log_reload();
- log_reload = 0;
- }
-
- /* Abort if select failed, except for EINTR cases
- which indicate a possible log reload */
- if (ret == -1) {
- if (errno == EINTR)
- continue;
- dolog(LOG_ERR, "Failure in select: %d (%s)",
- errno, strerror(errno));
- break;
- }
-
- /* Always process HV logs even if not a timeout */
- if (log_hv_fd != -1)
- handle_hv_logs();
-
- /* Must not check returned FDSET if it was a timeout */
- if (ret == 0)
- continue;
-
- if (FD_ISSET(xs_fileno(xs), &readfds))
- handle_xs();
-
- for (d = dom_head; d; d = n) {
- n = d->next;
- if (d->xce_handle != -1 &&
- FD_ISSET(xc_evtchn_fd(d->xce_handle), &readfds))
- handle_ring_read(d);
-
- if (d->tty_fd != -1 && FD_ISSET(d->tty_fd, &readfds))
- handle_tty_read(d);
-
- if (d->tty_fd != -1 && FD_ISSET(d->tty_fd, &writefds))
- handle_tty_write(d);
-
- if (d->is_dead)
- cleanup_domain(d);
- }
- }
-
- if (log_hv_fd != -1) {
- close(log_hv_fd);
- log_hv_fd = -1;
- }
- if (xc_handle != -1) {
- xc_interface_close(xc_handle);
- xc_handle = -1;
- }
-}
-
-/*
- * Local variables:
- * c-file-style: "linux"
- * indent-tabs-mode: t
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- */
diff -r fda4d94ca31d tools/console/daemon/io.h
--- a/tools/console/daemon/io.h Tue Aug 14 19:55:04 2007 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-/*\
- * Copyright (C) International Business Machines Corp., 2005
- * Author(s): Anthony Liguori <aliguori@xxxxxxxxxx>
- *
- * Xen Console Daemon
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; under version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-\*/
-
-#ifndef CONSOLED_IO_H
-#define CONSOLED_IO_H
-
-void enum_domains(void);
-void handle_io(void);
-
-#endif
diff -r fda4d94ca31d tools/console/daemon/main.c
--- a/tools/console/daemon/main.c Tue Aug 14 19:55:04 2007 -0400
+++ b/tools/console/daemon/main.c Tue Aug 14 20:09:28 2007 -0400
@@ -26,15 +26,14 @@
#include <string.h>
#include <signal.h>
#include <sys/types.h>
+#include <limits.h>
+#include <fcntl.h>
#include "xenctrl.h"
#include "utils.h"
-#include "io.h"
int log_reload = 0;
-int log_guest = 0;
-int log_hv = 0;
char *log_dir = NULL;
static void handle_hup(int sig)
@@ -44,13 +43,41 @@ static void handle_hup(int sig)
static void usage(char *name)
{
- printf("Usage: %s [-h] [-V] [-v] [-i] [--log=none|guest|hv|all]
[--log-dir=DIR] [--pid-file=PATH]\n", name);
+ printf("Usage: %s [-h] [-V] [-v] [-i] [--log-dir=DIR]
[--pid-file=PATH]\n", name);
}
static void version(char *name)
{
printf("Xen Console Daemon 3.0\n");
}
+
+static int create_hv_log(void)
+{
+ char logfile[PATH_MAX];
+ int fd;
+ snprintf(logfile, PATH_MAX-1, "%s/hypervisor.log", log_dir);
+ logfile[PATH_MAX-1] = '\0';
+
+ fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0644);
+ if (fd == -1)
+ dolog(LOG_ERR, "Failed to open log %s: %d (%s)",
+ logfile, errno, strerror(errno));
+ return fd;
+}
+
+static void handle_hv_logs(int log_hv_fd)
+{
+ char buffer[1024*16];
+ char *bufptr = buffer;
+ unsigned int size = sizeof(buffer);
+ if (xc_readconsolering(xc, &bufptr, &size, 1) == 0) {
+ int len = write(log_hv_fd, buffer, size);
+ if (len < 0)
+ dolog(LOG_ERR, "Failed to write hypervisor log: %d
(%s)",
+ errno, strerror(errno));
+ }
+}
+
int main(int argc, char **argv)
{
@@ -60,7 +87,6 @@ int main(int argc, char **argv)
{ "version", 0, 0, 'V' },
{ "verbose", 0, 0, 'v' },
{ "interactive", 0, 0, 'i' },
- { "log", 1, 0, 'l' },
{ "log-dir", 1, 0, 'r' },
{ "pid-file", 1, 0, 'p' },
{ 0 },
@@ -71,6 +97,7 @@ int main(int argc, char **argv)
int syslog_mask = LOG_WARNING;
int opt_ind = 0;
char *pidfile = NULL;
+ int log_hv_fd = -1;
while ((ch = getopt_long(argc, argv, sopts, lopts, &opt_ind)) != -1) {
switch (ch) {
@@ -86,16 +113,6 @@ int main(int argc, char **argv)
break;
case 'i':
is_interactive = true;
- break;
- case 'l':
- if (!strcmp(optarg, "all")) {
- log_hv = 1;
- log_guest = 1;
- } else if (!strcmp(optarg, "hv")) {
- log_hv = 1;
- } else if (!strcmp(optarg, "guest")) {
- log_guest = 1;
- }
break;
case 'r':
log_dir = strdup(optarg);
@@ -132,9 +149,20 @@ int main(int argc, char **argv)
if (!xen_setup())
exit(1);
- enum_domains();
+ log_hv_fd = create_hv_log();
- handle_io();
+ for (;;) {
+ /* Wish we didn't have to spin for HV logs */
+ sleep(1);
+
+ if (log_reload) {
+ close(log_hv_fd);
+ log_hv_fd = create_hv_log();
+ log_reload = 0;
+ }
+
+ handle_hv_logs(log_hv_fd);
+ }
closelog();
free(log_dir);
diff -r fda4d94ca31d tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c Tue Aug 14 19:55:04 2007 -0400
+++ b/tools/console/daemon/utils.c Tue Aug 14 19:59:38 2007 -0400
@@ -36,7 +36,6 @@
#include "xenctrl.h"
#include "utils.h"
-struct xs_handle *xs;
int xc;
static void child_exit(int sig)
@@ -107,37 +106,12 @@ void daemonize(const char *pidfile)
bool xen_setup(void)
{
-
- xs = xs_daemon_open();
- if (xs == NULL) {
- dolog(LOG_ERR,
- "Failed to contact xenstore (%m). Is it running?");
- goto out;
- }
-
xc = xc_interface_open();
if (xc == -1) {
dolog(LOG_ERR, "Failed to contact hypervisor (%m)");
- goto out;
- }
-
- if (!xs_watch(xs, "@introduceDomain", "domlist")) {
- dolog(LOG_ERR, "xenstore watch on @introduceDomain fails.");
- goto out;
- }
-
- if (!xs_watch(xs, "@releaseDomain", "domlist")) {
- dolog(LOG_ERR, "xenstore watch on @releaseDomain fails.");
- goto out;
+ return false;
}
return true;
-
- out:
- if (xs)
- xs_daemon_close(xs);
- if (xc != -1)
- xc_interface_close(xc);
- return false;
}
diff -r fda4d94ca31d tools/console/daemon/utils.h
--- a/tools/console/daemon/utils.h Tue Aug 14 19:55:04 2007 -0400
+++ b/tools/console/daemon/utils.h Tue Aug 14 19:59:51 2007 -0400
@@ -25,12 +25,9 @@
#include <syslog.h>
#include <stdio.h>
-#include "xs.h"
-
void daemonize(const char *pidfile);
bool xen_setup(void);
-extern struct xs_handle *xs;
extern int xc;
#if 1
--
|=- Red Hat, Engineering, Emerging Technologies, Boston. +1 978 392 2496 -=|
|=- Perl modules: http://search.cpan.org/~danberr/ -=|
|=- Projects: http://freshmeat.net/~danielpb/ -=|
|=- GnuPG: 7D3B9505 F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 -=|
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|