[libvirt] [PATCH 07/11] Move LXC monitor code out into separate file

Daniel P. Berrange berrange at redhat.com
Tue Jul 24 13:22:49 UTC 2012


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

Move the code that handles the LXC monitor out of the
lxc_process.c file and into lxc_monitor.{c,h}

Signed-off-by: Daniel P. Berrange <berrange at redhat.com>
---
 po/POTFILES.in        |    1 +
 src/Makefile.am       |    1 +
 src/lxc/lxc_domain.h  |    4 +-
 src/lxc/lxc_monitor.c |  163 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/lxc_monitor.h |   54 ++++++++++++++++
 src/lxc/lxc_process.c |   70 ++++++++++++---------
 6 files changed, 262 insertions(+), 31 deletions(-)
 create mode 100644 src/lxc/lxc_monitor.c
 create mode 100644 src/lxc/lxc_monitor.h

diff --git a/po/POTFILES.in b/po/POTFILES.in
index 7587c61..025d7fa 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -47,6 +47,7 @@ src/lxc/lxc_container.c
 src/lxc/lxc_conf.c
 src/lxc/lxc_controller.c
 src/lxc/lxc_driver.c
+src/lxc/lxc_monitor.c
 src/lxc/lxc_process.c
 src/libxl/libxl_driver.c
 src/libxl/libxl_conf.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 93fcf3b..a910aa1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -352,6 +352,7 @@ LXC_DRIVER_SOURCES =						\
 		lxc/lxc_container.c lxc/lxc_container.h		\
 		lxc/lxc_cgroup.c lxc/lxc_cgroup.h		\
 		lxc/lxc_domain.c lxc/lxc_domain.h		\
+		lxc/lxc_monitor.c lxc/lxc_monitor.h		\
 		lxc/lxc_process.c lxc/lxc_process.h		\
 		lxc/lxc_driver.c lxc/lxc_driver.h
 
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 799248d..ff7c96f 100644
--- a/src/lxc/lxc_domain.h
+++ b/src/lxc/lxc_domain.h
@@ -24,13 +24,13 @@
 # define __LXC_DOMAIN_H__
 
 # include "lxc_conf.h"
-# include "rpc/virnetclient.h"
+# include "lxc_monitor.h"
 
 
 typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
 typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
 struct _virLXCDomainObjPrivate {
-    virNetClientPtr monitor;
+    virLXCMonitorPtr monitor;
 };
 
 void virLXCDomainSetPrivateDataHooks(virCapsPtr caps);
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
new file mode 100644
index 0000000..6740aa7
--- /dev/null
+++ b/src/lxc/lxc_monitor.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2010-2012 Red Hat, Inc.
+ *
+ * lxc_monitor.c: client for LXC controller monitor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <config.h>
+
+#include "lxc_monitor.h"
+#include "lxc_conf.h"
+
+#include "memory.h"
+
+#include "virterror_internal.h"
+#include "logging.h"
+#include "threads.h"
+#include "rpc/virnetclient.h"
+
+#define VIR_FROM_THIS VIR_FROM_LXC
+
+struct _virLXCMonitor {
+    int refs;
+
+    virMutex lock; /* also used to protect fd */
+
+    virDomainObjPtr vm;
+    virLXCMonitorCallbacksPtr cb;
+
+    virNetClientPtr client;
+};
+
+static void virLXCMonitorFree(virLXCMonitorPtr mon);
+
+
+static void virLXCMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
+                                   int reason ATTRIBUTE_UNUSED,
+                                   void *opaque)
+{
+    virLXCMonitorPtr mon = opaque;
+    virLXCMonitorCallbackEOFNotify eofNotify;
+    virDomainObjPtr vm;
+
+    virLXCMonitorLock(mon);
+    eofNotify = mon->cb->eofNotify;
+    vm = mon->vm;
+    virLXCMonitorUnlock(mon);
+
+    eofNotify(mon, vm);
+}
+
+
+virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm,
+                                  const char *socketdir,
+                                  virLXCMonitorCallbacksPtr cb)
+{
+    virLXCMonitorPtr mon;
+    char *sockpath = NULL;
+
+    if (VIR_ALLOC(mon) < 0)
+        return NULL;
+
+    if (virMutexInit(&mon->lock) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("cannot initialize monitor mutex"));
+        VIR_FREE(mon);
+        return NULL;
+    }
+
+    if (virAsprintf(&sockpath, "%s/%s.sock",
+                    socketdir, vm->def->name) < 0)
+        goto no_memory;
+
+    if (!(mon->client = virNetClientNewUNIX(sockpath, false, NULL)))
+        goto error;
+
+
+    mon->vm = vm;
+    mon->cb = cb;
+
+    virNetClientSetCloseCallback(mon->client, virLXCMonitorEOFNotify, mon, NULL);
+
+cleanup:
+    VIR_FREE(sockpath);
+    return mon;
+
+no_memory:
+    virReportOOMError();
+error:
+    virLXCMonitorClose(mon);
+    virLXCMonitorFree(mon);
+    mon = NULL;
+    goto cleanup;
+}
+
+
+static void virLXCMonitorFree(virLXCMonitorPtr mon)
+{
+    VIR_DEBUG("mon=%p", mon);
+    if (mon->client)
+        virLXCMonitorClose(mon);
+
+    if (mon->cb && mon->cb->destroy)
+        (mon->cb->destroy)(mon, mon->vm);
+    virMutexDestroy(&mon->lock);
+    virNetClientFree(mon->client);
+    VIR_FREE(mon);
+}
+
+
+int virLXCMonitorRef(virLXCMonitorPtr mon)
+{
+    mon->refs++;
+    return mon->refs;
+}
+
+int virLXCMonitorUnref(virLXCMonitorPtr mon)
+{
+    mon->refs--;
+
+    if (mon->refs == 0) {
+        virLXCMonitorUnlock(mon);
+        virLXCMonitorFree(mon);
+        return 0;
+    }
+
+    return mon->refs;
+}
+
+
+void virLXCMonitorClose(virLXCMonitorPtr mon)
+{
+    if (mon->client) {
+        virNetClientClose(mon->client);
+        virNetClientFree(mon->client);
+        mon->client = NULL;
+    }
+}
+
+
+void virLXCMonitorLock(virLXCMonitorPtr mon)
+{
+    virMutexLock(&mon->lock);
+}
+
+
+void virLXCMonitorUnlock(virLXCMonitorPtr mon)
+{
+    virMutexUnlock(&mon->lock);
+}
diff --git a/src/lxc/lxc_monitor.h b/src/lxc/lxc_monitor.h
new file mode 100644
index 0000000..32b8d36
--- /dev/null
+++ b/src/lxc/lxc_monitor.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010-2012 Red Hat, Inc.
+ *
+ * lxc_monitor.h: client for LXC controller monitor
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __LXC_MONITOR_H__
+# define __LXC_MONITOR_H__
+
+# include "domain_conf.h"
+
+typedef struct _virLXCMonitor virLXCMonitor;
+typedef virLXCMonitor *virLXCMonitorPtr;
+
+typedef struct _virLXCMonitorCallbacks virLXCMonitorCallbacks;
+typedef virLXCMonitorCallbacks *virLXCMonitorCallbacksPtr;
+
+typedef void (*virLXCMonitorCallbackDestroy)(virLXCMonitorPtr mon,
+                                             virDomainObjPtr vm);
+typedef void (*virLXCMonitorCallbackEOFNotify)(virLXCMonitorPtr mon,
+                                               virDomainObjPtr vm);
+
+struct _virLXCMonitorCallbacks {
+    virLXCMonitorCallbackDestroy destroy;
+    virLXCMonitorCallbackEOFNotify eofNotify;
+};
+
+virLXCMonitorPtr virLXCMonitorNew(virDomainObjPtr vm,
+                                  const char *socketdir,
+                                  virLXCMonitorCallbacksPtr cb);
+
+void virLXCMonitorClose(virLXCMonitorPtr mon);
+
+void virLXCMonitorLock(virLXCMonitorPtr mon);
+void virLXCMonitorUnlock(virLXCMonitorPtr mon);
+
+int virLXCMonitorRef(virLXCMonitorPtr mon);
+int virLXCMonitorUnref(virLXCMonitorPtr mon);
+
+#endif /* __LXC_MONITOR_H__ */
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 3a1959f..1bfd032 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -178,9 +178,11 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
     /* Stop autodestroy in case guest is restarted */
     virLXCProcessAutoDestroyRemove(driver, vm);
 
-    virNetClientClose(priv->monitor);
-    virNetClientFree(priv->monitor);
-    priv->monitor = NULL;
+    if (priv->monitor) {
+        virLXCMonitorClose(priv->monitor);
+        virLXCMonitorUnref(priv->monitor);
+        priv->monitor = NULL;
+    }
 
     virPidFileDelete(driver->stateDir, vm->def->name);
     virDomainDeleteConfig(driver->stateDir, NULL, vm);
@@ -471,13 +473,25 @@ cleanup:
 }
 
 
+static void virLXCProcessMonitorDestroy(virLXCMonitorPtr mon,
+                                        virDomainObjPtr vm)
+{
+    virLXCDomainObjPrivatePtr priv;
+
+    virDomainObjLock(vm);
+    priv = vm->privateData;
+    if (priv->monitor == mon)
+        priv->monitor = NULL;
+    if (virDomainObjUnref(vm) > 0)
+        virDomainObjUnlock(vm);
+}
+
+
 extern virLXCDriverPtr lxc_driver;
-static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSED,
-                                          int reason ATTRIBUTE_UNUSED,
-                                          void *opaque)
+static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
+                                          virDomainObjPtr vm)
 {
     virLXCDriverPtr driver = lxc_driver;
-    virDomainObjPtr vm = opaque;
     virDomainEventPtr event = NULL;
 
     lxcDriverLock(driver);
@@ -504,36 +518,32 @@ static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSE
 }
 
 
-static virNetClientPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
-                                                   virDomainObjPtr vm)
-{
-    char *sockpath = NULL;
-    virNetClientPtr monitor = NULL;
+static virLXCMonitorCallbacks monitorCallbacks = {
+    .eofNotify = virLXCProcessMonitorEOFNotify,
+    .destroy = virLXCProcessMonitorDestroy,
+};
 
-    if (virAsprintf(&sockpath, "%s/%s.sock",
-                    driver->stateDir, vm->def->name) < 0) {
-        virReportOOMError();
-        return NULL;
-    }
+
+static virLXCMonitorPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
+                                                    virDomainObjPtr vm)
+{
+    virLXCMonitorPtr monitor = NULL;
 
     if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
         goto cleanup;
 
-    monitor = virNetClientNewUNIX(sockpath, false, NULL);
+    monitor = virLXCMonitorNew(vm, driver->stateDir, &monitorCallbacks);
 
     if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
-        virNetClientFree(monitor);
-        monitor = NULL;
+        if (monitor) {
+            virLXCMonitorClose(monitor);
+            virLXCMonitorUnref(monitor);
+            monitor = NULL;
+        }
         goto cleanup;
     }
 
-    if (!monitor)
-        goto cleanup;
-
-    virNetClientSetCloseCallback(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
-
 cleanup:
-    VIR_FREE(sockpath);
     return monitor;
 }
 
@@ -1041,9 +1051,11 @@ cleanup:
         VIR_FREE(veths[i]);
     }
     if (rc != 0) {
-        virNetClientClose(priv->monitor);
-        virNetClientFree(priv->monitor);
-        priv->monitor = NULL;
+        if (priv->monitor) {
+            virLXCMonitorClose(priv->monitor);
+            virLXCMonitorUnref(priv->monitor);
+            priv->monitor = NULL;
+        }
         virDomainConfVMNWFilterTeardown(vm);
 
         virSecurityManagerRestoreAllLabel(driver->securityManager,
-- 
1.7.10.4




More information about the libvir-list mailing list