mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00: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:
parent
e1de552150
commit
0a8addc103
@ -14634,7 +14634,7 @@ virDomainObjParseNode(xmlDocPtr xml,
|
||||
}
|
||||
|
||||
|
||||
static virDomainObjPtr
|
||||
virDomainObjPtr
|
||||
virDomainObjParseFile(const char *filename,
|
||||
virCapsPtr caps,
|
||||
virDomainXMLOptionPtr xmlopt,
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user