]> xenbits.xensource.com Git - libvirt.git/commitdiff
lxc: only write XML once for lxc controller
authorDaniel P. Berrange <berrange@redhat.com>
Fri, 16 Jan 2015 16:39:57 +0000 (16:39 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 27 Jan 2015 13:57:02 +0000 (13:57 +0000)
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.

src/conf/domain_conf.c
src/conf/domain_conf.h
src/lxc/lxc_controller.c
src/lxc/lxc_process.c

index 9ff38195cb66f53d0c3c92c75a2a9c9c849cf5ac..10dbabda4465980bf4da954f0066f43a8656b7c9 100644 (file)
@@ -14634,7 +14634,7 @@ virDomainObjParseNode(xmlDocPtr xml,
 }
 
 
-static virDomainObjPtr
+virDomainObjPtr
 virDomainObjParseFile(const char *filename,
                       virCapsPtr caps,
                       virDomainXMLOptionPtr xmlopt,
index 09ab194461f68c26f628f135efaa07bbcc651c32..563c18bdbe3058ffd9d6233a519d8ffde8f966de 100644 (file)
@@ -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);
index 53a2c8d67f1599ba94bcb0cefa72980440a6ec30..f2c0b578532296099772455d339752445ed89083 100644 (file)
@@ -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)
index 5517cdab4d5d3c168f34b1a57aa0dfe834e44835..01da344829031fed5a7ba967957c1179d03bc479 100644 (file)
@@ -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);