[libvirt] [PATCH 15/16] Convert the LXC driver to use virNetClient

Daniel P. Berrange berrange at redhat.com
Wed Jul 18 16:32:36 UTC 2012


From: "Daniel P. Berrange" <berrange at redhat.com>

Update the LXC driver to use the virNetClient APIs for
connecting to the libvirt_lxc monitor, instead of the
low-level socket APIs. This is a step towards running
a full RPC protocol with libvirt_lxc

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 src/lxc/lxc_domain.c  |    3 -
 src/lxc/lxc_domain.h  |    5 +-
 src/lxc/lxc_process.c |  161 +++++++++++++++++--------------------------------
 3 files changed, 58 insertions(+), 111 deletions(-)

diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 0376f0b..ec450f0 100644
--- a/src/lxc/lxc_domain.c
+++ b/src/lxc/lxc_domain.c
@@ -32,9 +32,6 @@ static void *virLXCDomainObjPrivateAlloc(void)
     if (VIR_ALLOC(priv) < 0)
         return NULL;
 
-    priv->monitor = -1;
-    priv->monitorWatch = -1;
-
     return priv;
 }
 
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 08d09c1..845d85a 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -24,12 +24,13 @@
 # define __LXC_DOMAIN_H__
 
 # include "lxc_conf.h"
+# include "rpc/virnetclient.h"
+
 
 typedef struct _lxcDomainObjPrivate lxcDomainObjPrivate;
 typedef lxcDomainObjPrivate *lxcDomainObjPrivatePtr;
 struct _lxcDomainObjPrivate {
-    int monitor;
-    int monitorWatch;
+    virNetClientPtr monitor;
 };
 
 void virLXCDomainSetPrivateDataHooks(virCapsPtr caps);
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index f8e2e31..cc276b7 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -178,8 +178,9 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
     /* Stop autodestroy in case guest is restarted */
     virLXCProcessAutoDestroyRemove(driver, vm);
 
-    virEventRemoveHandle(priv->monitorWatch);
-    VIR_FORCE_CLOSE(priv->monitor);
+    virNetClientClose(priv->monitor);
+    virNetClientFree(priv->monitor);
+    priv->monitor = NULL;
 
     virPidFileDelete(driver->stateDir, vm->def->name);
     virDomainDeleteConfig(driver->stateDir, NULL, vm);
@@ -187,8 +188,6 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
     virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
     vm->pid = -1;
     vm->def->id = -1;
-    priv->monitor = -1;
-    priv->monitorWatch = -1;
 
     for (i = 0 ; i < vm->def->nnets ; i++) {
         virDomainNetDefPtr iface = vm->def->nets[i];
@@ -472,60 +471,69 @@ cleanup:
 }
 
 
-static int virLXCProcessMonitorClient(virLXCDriverPtr  driver,
-                                      virDomainObjPtr vm)
+extern virLXCDriverPtr lxc_driver;
+static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
+                                          void *opaque)
+{
+    virLXCDriverPtr driver = lxc_driver;
+    virDomainObjPtr vm = opaque;
+    virDomainEventPtr event = NULL;
+
+    lxcDriverLock(driver);
+    virDomainObjLock(vm);
+    lxcDriverUnlock(driver);
+
+    virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+    event = virDomainEventNewFromObj(vm,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
+    virDomainAuditStop(vm, "shutdown");
+    if (!vm->persistent) {
+        virDomainRemoveInactive(&driver->domains, vm);
+        vm = NULL;
+    }
+
+    if (vm)
+        virDomainObjUnlock(vm);
+    if (event) {
+        lxcDriverLock(driver);
+        virDomainEventStateQueue(driver->domainEventState, event);
+        lxcDriverUnlock(driver);
+    }
+}
+
+
+static virNetClientPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
+                                                   virDomainObjPtr vm)
 {
     char *sockpath = NULL;
-    int fd = -1;
-    struct sockaddr_un addr;
+    virNetClientPtr monitor = NULL;
 
     if (virAsprintf(&sockpath, "%s/%s.sock",
                     driver->stateDir, vm->def->name) < 0) {
         virReportOOMError();
-        return -1;
+        return NULL;
     }
 
-    if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0) {
-        VIR_ERROR(_("Failed to set security context for monitor for %s"),
-                  vm->def->name);
-        goto error;
-    }
+    if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
+        goto cleanup;
 
-    fd = socket(PF_UNIX, SOCK_STREAM, 0);
+    monitor = virNetClientNewUNIX(sockpath, false, NULL);
 
     if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
-        VIR_ERROR(_("Failed to clear security context for monitor for %s"),
-                  vm->def->name);
-        goto error;
-    }
-
-    if (fd < 0) {
-        virReportSystemError(errno, "%s",
-                             _("Failed to create client socket"));
-        goto error;
-    }
-
-    memset(&addr, 0, sizeof(addr));
-    addr.sun_family = AF_UNIX;
-    if (virStrcpyStatic(addr.sun_path, sockpath) == NULL) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Socket path %s too big for destination"), sockpath);
-        goto error;
+        virNetClientFree(monitor);
+        monitor = NULL;
+        goto cleanup;
     }
 
-    if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
-        virReportSystemError(errno, "%s",
-                             _("Failed to connect to client socket"));
-        goto error;
-    }
+    if (!monitor)
+        goto cleanup;
 
-    VIR_FREE(sockpath);
-    return fd;
+    virNetClientSetEOFNotify(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
 
-error:
+cleanup:
     VIR_FREE(sockpath);
-    VIR_FORCE_CLOSE(fd);
-    return -1;
+    return monitor;
 }
 
 
@@ -581,51 +589,6 @@ cleanup:
     return rc;
 }
 
-extern virLXCDriverPtr lxc_driver;
-static void virLXCProcessMonitorEvent(int watch,
-                                      int fd,
-                                      int events ATTRIBUTE_UNUSED,
-                                      void *data)
-{
-    virLXCDriverPtr driver = lxc_driver;
-    virDomainObjPtr vm = data;
-    virDomainEventPtr event = NULL;
-    lxcDomainObjPrivatePtr priv;
-
-    lxcDriverLock(driver);
-    virDomainObjLock(vm);
-    lxcDriverUnlock(driver);
-
-    priv = vm->privateData;
-
-    if (priv->monitor != fd || priv->monitorWatch != watch) {
-        virEventRemoveHandle(watch);
-        goto cleanup;
-    }
-
-    if (virLXCProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN) < 0) {
-        virEventRemoveHandle(watch);
-    } else {
-        event = virDomainEventNewFromObj(vm,
-                                         VIR_DOMAIN_EVENT_STOPPED,
-                                         VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
-        virDomainAuditStop(vm, "shutdown");
-    }
-    if (!vm->persistent) {
-        virDomainRemoveInactive(&driver->domains, vm);
-        vm = NULL;
-    }
-
-cleanup:
-    if (vm)
-        virDomainObjUnlock(vm);
-    if (event) {
-        lxcDriverLock(driver);
-        virDomainEventStateQueue(driver->domainEventState, event);
-        lxcDriverUnlock(driver);
-    }
-}
-
 
 static virCommandPtr
 virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,
@@ -1003,7 +966,7 @@ int virLXCProcessStart(virConnectPtr conn,
     /* Connect to the controller as a client *first* because
      * this will block until the child has written their
      * pid file out to disk */
-    if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
+    if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
         goto cleanup;
 
     /* And get its pid */
@@ -1028,14 +991,6 @@ int virLXCProcessStart(virConnectPtr conn,
         goto error;
     }
 
-    if ((priv->monitorWatch = virEventAddHandle(
-             priv->monitor,
-             VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
-             virLXCProcessMonitorEvent,
-             vm, NULL)) < 0) {
-        goto error;
-    }
-
     if (autoDestroy &&
         virLXCProcessAutoDestroyAdd(driver, vm, conn) < 0)
         goto error;
@@ -1085,7 +1040,9 @@ cleanup:
         VIR_FREE(veths[i]);
     }
     if (rc != 0) {
-        VIR_FORCE_CLOSE(priv->monitor);
+        virNetClientClose(priv->monitor);
+        virNetClientFree(priv->monitor);
+        priv->monitor = NULL;
         virDomainConfVMNWFilterTeardown(vm);
 
         virSecurityManagerRestoreAllLabel(driver->securityManager,
@@ -1191,14 +1148,7 @@ virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
                              VIR_DOMAIN_RUNNING_UNKNOWN);
 
-        if ((priv->monitor = virLXCProcessMonitorClient(driver, vm)) < 0)
-            goto error;
-
-        if ((priv->monitorWatch = virEventAddHandle(
-                 priv->monitor,
-                 VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
-                 virLXCProcessMonitorEvent,
-                 vm, NULL)) < 0)
+        if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm)))
             goto error;
 
         if (virSecurityManagerReserveLabel(driver->securityManager,
@@ -1221,7 +1171,6 @@ virLXCProcessReconnectDomain(void *payload, const void *name ATTRIBUTE_UNUSED, v
 
     } else {
         vm->def->id = -1;
-        VIR_FORCE_CLOSE(priv->monitor);
     }
 
 cleanup:
-- 
1.7.10.4




More information about the libvir-list mailing list