1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-03-14 12:58:33 +03:00

lxc: only write XML once for lxc controller

Currently when launching the LXC controller we first write out
the plain, inactive XML configuration, then launch the controller,
then replace the file with the live status XML configuration.
By good fortune this hasn't caused any problems other than some
misleading error messages during failure scenarios.

This simplifies the code so it only writes out the XML once and
always writes the live status XML. To do this we need to handshake
with the child process, to make execution pause just before exec()
so we can write the XML status with the child PID present.
This commit is contained in:
Daniel P. Berrange 2015-01-16 16:39:57 +00:00
parent e1de552150
commit 0a8addc103
4 changed files with 33 additions and 19 deletions

View File

@ -14634,7 +14634,7 @@ virDomainObjParseNode(xmlDocPtr xml,
} }
static virDomainObjPtr virDomainObjPtr
virDomainObjParseFile(const char *filename, virDomainObjParseFile(const char *filename,
virCapsPtr caps, virCapsPtr caps,
virDomainXMLOptionPtr xmlopt, virDomainXMLOptionPtr xmlopt,

View File

@ -2489,6 +2489,11 @@ virDomainDefPtr virDomainDefParseNode(xmlDocPtr doc,
virDomainXMLOptionPtr xmlopt, virDomainXMLOptionPtr xmlopt,
unsigned int expectedVirtTypes, unsigned int expectedVirtTypes,
unsigned int flags); unsigned int flags);
virDomainObjPtr virDomainObjParseFile(const char *filename,
virCapsPtr caps,
virDomainXMLOptionPtr xmlopt,
unsigned int expectedVirtTypes,
unsigned int flags);
bool virDomainDefCheckABIStability(virDomainDefPtr src, bool virDomainDefCheckABIStability(virDomainDefPtr src,
virDomainDefPtr dst); virDomainDefPtr dst);

View File

@ -100,6 +100,7 @@ typedef struct _virLXCController virLXCController;
typedef virLXCController *virLXCControllerPtr; typedef virLXCController *virLXCControllerPtr;
struct _virLXCController { struct _virLXCController {
char *name; char *name;
virDomainObjPtr vm;
virDomainDefPtr def; virDomainDefPtr def;
int handshakeFd; int handshakeFd;
@ -175,11 +176,12 @@ static virLXCControllerPtr virLXCControllerNew(const char *name)
ctrl->name)) == NULL) ctrl->name)) == NULL)
goto error; goto error;
if ((ctrl->def = virDomainDefParseFile(configFile, if ((ctrl->vm = virDomainObjParseFile(configFile,
caps, xmlopt, caps, xmlopt,
1 << VIR_DOMAIN_VIRT_LXC, 1 << VIR_DOMAIN_VIRT_LXC,
0)) == NULL) 0)) == NULL)
goto error; goto error;
ctrl->def = ctrl->vm->def;
if ((ctrl->timerShutdown = virEventAddTimeout(-1, if ((ctrl->timerShutdown = virEventAddTimeout(-1,
virLXCControllerQuitTimer, ctrl, virLXCControllerQuitTimer, ctrl,
@ -269,7 +271,7 @@ static void virLXCControllerFree(virLXCControllerPtr ctrl)
VIR_FREE(ctrl->devptmx); VIR_FREE(ctrl->devptmx);
virDomainDefFree(ctrl->def); virObjectUnref(ctrl->vm);
VIR_FREE(ctrl->name); VIR_FREE(ctrl->name);
if (ctrl->timerShutdown != -1) if (ctrl->timerShutdown != -1)

View File

@ -821,6 +821,9 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
virCommandSetPidFile(cmd, pidfile); virCommandSetPidFile(cmd, pidfile);
virCommandSetOutputFD(cmd, &logfd); virCommandSetOutputFD(cmd, &logfd);
virCommandSetErrorFD(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; return cmd;
cleanup: cleanup:
@ -1169,10 +1172,6 @@ int virLXCProcessStart(virConnectPtr conn,
if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0) if (virLXCProcessSetupInterfaces(conn, vm->def, &nveths, &veths) < 0)
goto cleanup; 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, if ((logfd = open(logfile, O_WRONLY | O_APPEND | O_CREAT,
S_IRUSR|S_IWUSR)) < 0) { S_IRUSR|S_IWUSR)) < 0) {
virReportSystemError(errno, virReportSystemError(errno,
@ -1271,6 +1270,23 @@ int virLXCProcessStart(virConnectPtr conn,
goto error; 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) if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
driver->inhibitCallback(true, driver->inhibitOpaque); driver->inhibitCallback(true, driver->inhibitOpaque);
@ -1328,15 +1344,6 @@ int virLXCProcessStart(virConnectPtr conn,
/* We don't need the temporary NIC names anymore, clear them */ /* We don't need the temporary NIC names anymore, clear them */
virLXCProcessCleanInterfaces(vm->def); 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 */ /* finally we can call the 'started' hook script if any */
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) { if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
char *xml = virDomainDefFormat(vm->def, 0); char *xml = virDomainDefFormat(vm->def, 0);