[PATCH 06/11] Convert the LXC driver to use virNetClient

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: "Daniel P. Berrange" <berrange@xxxxxxxxxx>

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@xxxxxxxxxx>
---
 src/lxc/lxc_domain.c  |    3 -
 src/lxc/lxc_domain.h  |    5 +-
 src/lxc/lxc_process.c |  162 +++++++++++++++++--------------------------------
 3 files changed, 59 insertions(+), 111 deletions(-)

diff --git a/src/lxc/lxc_domain.c b/src/lxc/lxc_domain.c
index 847aac7..2ce2a18 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 8a2c892..799248d 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 _virLXCDomainObjPrivate virLXCDomainObjPrivate;
 typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
 struct _virLXCDomainObjPrivate {
-    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 de11725..3a1959f 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,70 @@ cleanup:
 }
 
 
-static int virLXCProcessMonitorClient(virLXCDriverPtr  driver,
-                                      virDomainObjPtr vm)
+extern virLXCDriverPtr lxc_driver;
+static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
+                                          int reason 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;
+    virNetClientSetCloseCallback(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
 
-error:
+cleanup:
     VIR_FREE(sockpath);
-    VIR_FORCE_CLOSE(fd);
-    return -1;
+    return monitor;
 }
 
 
@@ -581,51 +590,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;
-    virLXCDomainObjPrivatePtr 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 +967,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 +992,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 +1041,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 +1149,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 +1172,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

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]