Although the LXC driver can cope with libvirtd restarts, there is one small problem relating to the XML format. The XML format as stored in /etc/libvirtd/lxc/NAME.xml is the canonical 'inactive' configuration data. There are a few pieces of data which are filled in at runtime, such as the current /dev/pty/XXX path, and vethXXX inteface name. Previously, the LXC drive would re-write /etc/libvirtd/lxc/NAME.xml to add in this data, but this is not good practice. Even though we tell sysadmins not to change this files directly, many people do, and this obliterates data important to libvirt. The 'controller' process however knows what the live config data is since it has a copy of the virDomainDefPtr object from when it was started up. The controller process stays around even across restarts of the libvirtd daemon. So this patch updates the handshake between the libvirtd LXC driver & controller, so that as well as sending back the PID, it also sends back the live XML configuration. So when starting up, libvirtd can get back a guarenteed accurate XML doc for the current live container config. I'm not entirely happy with this approach though - I'd ideally like to avoid having communications between the libvirtd & the controller process if practical, because it forms an ABI we have to preserve across daemon upgrades. So I'm sort of inclined to change this so that the 'live' XML config and PID are simply kept on disk in the paths /var/run/libvirt/lxc/NAME.{xml,pid} alongside the UNIX socket, and then just keep the UNIX socket connection as a way for getting notification of container shutdown (via POLLHUP). domain_conf.c | 6 +---- lxc_controller.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++----- lxc_controller.h | 1 lxc_driver.c | 20 ++++++++++++++++ 4 files changed, 83 insertions(+), 10 deletions(-) Daniel diff -r 33a641a0a0d9 src/domain_conf.c --- a/src/domain_conf.c Mon Jul 14 21:34:07 2008 +0100 +++ b/src/domain_conf.c Tue Jul 15 11:35:10 2008 +0100 @@ -1078,13 +1078,11 @@ break; case VIR_DOMAIN_CHR_TYPE_PTY: - /* @path attribute is an output only property - pty is auto-allocted */ - break; - case VIR_DOMAIN_CHR_TYPE_DEV: case VIR_DOMAIN_CHR_TYPE_FILE: case VIR_DOMAIN_CHR_TYPE_PIPE: - if (path == NULL) { + if (path == NULL && + def->type != VIR_DOMAIN_CHR_TYPE_PTY) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", _("Missing source path attribute for char device")); goto error; diff -r 33a641a0a0d9 src/lxc_controller.c --- a/src/lxc_controller.c Mon Jul 14 21:34:07 2008 +0100 +++ b/src/lxc_controller.c Tue Jul 15 11:35:10 2008 +0100 @@ -54,6 +54,55 @@ return -1; return pid; +} + +char *lxcControllerLiveConfig(int monitor) +{ + unsigned int len; + char *data; + + if (saferead(monitor, &len, sizeof(len)) != sizeof(len)) + return NULL; + + /* Refuse stupid size allocations */ + if (len > (1024 * 1024)) + return NULL; + + if (VIR_ALLOC_N(data, len+1) < 0) + return NULL; + + if (saferead(monitor, data, len) != len) { + VIR_FREE(data); + return NULL; + } + data[len] = '\0'; + printf("[%s]\n", data); + return data; +} + + +static int lxcControllerSendGreeting(int client, + virDomainDefPtr def) +{ + pid_t pid = getpid(); + char *xml; + int ret = -1; + unsigned int len; + + /* Sync up with libvirtd LXC driver to tell it our PID */ + if (safewrite(client, &pid, sizeof(pid)) != sizeof(pid)) + return -1; + + if (!(xml = virDomainDefFormat(NULL, def, VIR_DOMAIN_XML_SECURE))) + return -1; + + len = strlen(xml); + if (safewrite(client, &len, sizeof(len)) == sizeof(len) && + safewrite(client, xml, len) == len) + ret = 0; + VIR_FREE(xml); + + return ret; } /** @@ -110,7 +159,8 @@ * * Returns 0 on success or -1 in case of error */ -static int lxcControllerMain(int monitor, +static int lxcControllerMain(virDomainDefPtr def, + int monitor, int client, int appPty, int contPty) @@ -178,13 +228,11 @@ fprintf(stderr, "%d %d\n", epollEvent.data.fd, epollEvent.events); if (epollEvent.data.fd == monitor) { int fd = accept(monitor, NULL, 0); - pid_t pid = getpid(); if (client != -1) { close(fd); continue; } - /* Sync up with libvirtd LXC driver to tell it our PID */ - if (safewrite(fd, &pid, sizeof(pid)) != sizeof(pid)) { + if (lxcControllerSendGreeting(fd, def) < 0) { close(fd); continue; } @@ -362,7 +410,11 @@ if (lxcContainerSendContinue(control[0]) < 0) goto cleanup; - rc = lxcControllerMain(monitor, client, appPty, containerPty); + rc = lxcControllerMain(def, + monitor, + client, + appPty, + containerPty); cleanup: if (control[0] != -1) @@ -463,8 +515,10 @@ _exit(-1); /* Sync up with libvirtd LXC driver to tell it our PID */ - if (safewrite(client, &pid, sizeof(pid)) != sizeof(pid)) + if (lxcControllerSendGreeting(client, def) < 0) { + close(client); _exit(-1); + } /* Controlling libvirtd LXC driver now knows what our PID is, and is able to cleanup after diff -r 33a641a0a0d9 src/lxc_controller.h --- a/src/lxc_controller.h Mon Jul 14 21:34:07 2008 +0100 +++ b/src/lxc_controller.h Tue Jul 15 11:35:10 2008 +0100 @@ -29,6 +29,7 @@ #include "lxc_conf.h" pid_t lxcControllerPID(int monitor); +char *lxcControllerLiveConfig(int monitor); int lxcControllerStart(virDomainDefPtr def, int nveths, diff -r 33a641a0a0d9 src/lxc_driver.c --- a/src/lxc_driver.c Mon Jul 14 21:34:07 2008 +0100 +++ b/src/lxc_driver.c Tue Jul 15 11:35:10 2008 +0100 @@ -874,6 +874,8 @@ vm = lxc_driver->domains; while (vm) { pid_t pid; + char *xml; + virDomainDefPtr def; if ((vm->monitor = lxcMonitorClient(NULL, lxc_driver, vm)) < 0) { vm = vm->next; continue; @@ -881,10 +883,28 @@ /* Read pid from controller */ if ((pid = lxcControllerPID(vm->monitor)) < 0) { + printf("Failed to get PID\n"); close(vm->monitor); vm->monitor = -1; vm = vm->next; continue; + } + + /* Fetch and load the live container config */ + if ((xml = lxcControllerLiveConfig(vm->monitor)) == NULL) { + printf("Failed to get config\n"); + /* XXX should we kill off the container if this + happens ? */ + vm = vm->next; + continue; + } + def = virDomainDefParseString(NULL, lxc_driver->caps, xml); + VIR_FREE(xml); + if (def) { + vm->newDef = vm->def; + vm->def = def; + } else { + printf("Failed to pase config\n"); } vm->pid = vm->def->id = pid; -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list