diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9ff38195cb..10dbabda44 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -14634,7 +14634,7 @@ virDomainObjParseNode(xmlDocPtr xml, } -static virDomainObjPtr +virDomainObjPtr virDomainObjParseFile(const char *filename, virCapsPtr caps, virDomainXMLOptionPtr xmlopt, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 09ab194461..563c18bdbe 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2489,6 +2489,11 @@ virDomainDefPtr virDomainDefParseNode(xmlDocPtr doc, virDomainXMLOptionPtr xmlopt, unsigned int expectedVirtTypes, unsigned int flags); +virDomainObjPtr virDomainObjParseFile(const char *filename, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + unsigned int expectedVirtTypes, + unsigned int flags); bool virDomainDefCheckABIStability(virDomainDefPtr src, virDomainDefPtr dst); diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 53a2c8d67f..f2c0b57853 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -100,6 +100,7 @@ typedef struct _virLXCController virLXCController; typedef virLXCController *virLXCControllerPtr; struct _virLXCController { char *name; + virDomainObjPtr vm; virDomainDefPtr def; int handshakeFd; @@ -175,11 +176,12 @@ static virLXCControllerPtr virLXCControllerNew(const char *name) ctrl->name)) == NULL) goto error; - if ((ctrl->def = virDomainDefParseFile(configFile, - caps, xmlopt, - 1 << VIR_DOMAIN_VIRT_LXC, - 0)) == NULL) + if ((ctrl->vm = virDomainObjParseFile(configFile, + caps, xmlopt, + 1 << VIR_DOMAIN_VIRT_LXC, + 0)) == NULL) goto error; + ctrl->def = ctrl->vm->def; if ((ctrl->timerShutdown = virEventAddTimeout(-1, virLXCControllerQuitTimer, ctrl, @@ -269,7 +271,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl) VIR_FREE(ctrl->devptmx); - virDomainDefFree(ctrl->def); + virObjectUnref(ctrl->vm); VIR_FREE(ctrl->name); if (ctrl->timerShutdown != -1) diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 5517cdab4d..01da344829 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -821,6 +821,9 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver, virCommandSetPidFile(cmd, pidfile); virCommandSetOutputFD(cmd, &logfd); virCommandSetErrorFD(cmd, &logfd); + /* So we can pause before exec'ing the controller to + * write the live domain status XML with the PID */ + virCommandRequireHandshake(cmd); return cmd; cleanup: @@ -1169,10 +1172,6 @@ int virLXCProcessStart(virConnectPtr conn, if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0) goto cleanup; - /* Save the configuration for the controller */ - if (virDomainSaveConfig(cfg->stateDir, vm->def) < 0) - goto cleanup; - if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR|S_IWUSR)) < 0) { virReportSystemError(errno, @@ -1271,6 +1270,23 @@ int virLXCProcessStart(virConnectPtr conn, goto error; } + if (VIR_CLOSE(handshakefds[1]) < 0) { + virReportSystemError(errno, "%s", _("could not close handshake fd")); + goto error; + } + + if (virCommandHandshakeWait(cmd) < 0) + goto error; + + /* Write domain status to disk for the controller to + * read when it starts */ + if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) + goto error; + + /* Allow the child to exec the controller */ + if (virCommandHandshakeNotify(cmd) < 0) + goto error; + if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback) driver->inhibitCallback(true, driver->inhibitOpaque); @@ -1328,15 +1344,6 @@ int virLXCProcessStart(virConnectPtr conn, /* We don't need the temporary NIC names anymore, clear them */ virLXCProcessCleanInterfaces(vm->def); - /* Write domain status to disk. - * - * XXX: Earlier we wrote the plain "live" domain XML to this - * location for the benefit of libvirt_lxc. We're now overwriting - * it with the live status XML instead. This is a (currently - * harmless) inconsistency we should fix one day */ - if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0) - goto error; - /* finally we can call the 'started' hook script if any */ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) { char *xml = virDomainDefFormat(vm->def, 0);