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

Daniel P. Berrange berrange at redhat.com
Wed Jul 18 16:32:37 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>
---
 src/Makefile.am       |    1 +
 src/lxc/lxc_domain.h  |    4 +-
 src/lxc/lxc_monitor.c |  160 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/lxc_monitor.h |   54 +++++++++++++++++
 src/lxc/lxc_process.c |   49 +++++++++------
 5 files changed, 249 insertions(+), 19 deletions(-)
 create mode 100644 src/lxc/lxc_monitor.c
 create mode 100644 src/lxc/lxc_monitor.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 59f1ac8..6cec08e 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 845d85a..cbe19f5 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 _lxcDomainObjPrivate lxcDomainObjPrivate;
 typedef lxcDomainObjPrivate *lxcDomainObjPrivatePtr;
 struct _lxcDomainObjPrivate {
-    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..fef985a
--- /dev/null
+++ b/src/lxc/lxc_monitor.c
@@ -0,0 +1,160 @@
+/*
+ * 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,
+                                   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;
+
+    virNetClientSetEOFNotify(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)
+{
+    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..c2448bb
--- /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 cc276b7..ba7f3e0 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -178,8 +178,8 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver,
     /* Stop autodestroy in case guest is restarted */
     virLXCProcessAutoDestroyRemove(driver, vm);
 
-    virNetClientClose(priv->monitor);
-    virNetClientFree(priv->monitor);
+    virLXCMonitorClose(priv->monitor);
+    virLXCMonitorUnref(priv->monitor);
     priv->monitor = NULL;
 
     virPidFileDelete(driver->stateDir, vm->def->name);
@@ -471,12 +471,25 @@ cleanup:
 }
 
 
+static void virLXCProcessMonitorDestroy(virLXCMonitorPtr mon,
+                                        virDomainObjPtr vm)
+{
+    lxcDomainObjPrivatePtr 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,
-                                          void *opaque)
+static void virLXCProcessMonitorEOFNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED,
+                                          virDomainObjPtr vm)
 {
     virLXCDriverPtr driver = lxc_driver;
-    virDomainObjPtr vm = opaque;
     virDomainEventPtr event = NULL;
 
     lxcDriverLock(driver);
@@ -503,11 +516,17 @@ static void virLXCProcessMonitorEOFNotify(virNetClientPtr client ATTRIBUTE_UNUSE
 }
 
 
-static virNetClientPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
-                                                   virDomainObjPtr vm)
+static virLXCMonitorCallbacks monitorCallbacks = {
+    .eofNotify = virLXCProcessMonitorEOFNotify,
+    .destroy = virLXCProcessMonitorDestroy,
+};
+
+
+static virLXCMonitorPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
+                                                    virDomainObjPtr vm)
 {
     char *sockpath = NULL;
-    virNetClientPtr monitor = NULL;
+    virLXCMonitorPtr monitor = NULL;
 
     if (virAsprintf(&sockpath, "%s/%s.sock",
                     driver->stateDir, vm->def->name) < 0) {
@@ -518,19 +537,15 @@ static virNetClientPtr virLXCProcessConnectMonitor(virLXCDriverPtr  driver,
     if (virSecurityManagerSetSocketLabel(driver->securityManager, vm->def) < 0)
         goto cleanup;
 
-    monitor = virNetClientNewUNIX(sockpath, false, NULL);
+    monitor = virLXCMonitorNew(vm, sockpath, &monitorCallbacks);
 
     if (virSecurityManagerClearSocketLabel(driver->securityManager, vm->def) < 0) {
-        virNetClientFree(monitor);
+        virLXCMonitorClose(monitor);
+        virLXCMonitorUnref(monitor);
         monitor = NULL;
         goto cleanup;
     }
 
-    if (!monitor)
-        goto cleanup;
-
-    virNetClientSetEOFNotify(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
-
 cleanup:
     VIR_FREE(sockpath);
     return monitor;
@@ -1040,8 +1055,8 @@ cleanup:
         VIR_FREE(veths[i]);
     }
     if (rc != 0) {
-        virNetClientClose(priv->monitor);
-        virNetClientFree(priv->monitor);
+        virLXCMonitorClose(priv->monitor);
+        virLXCMonitorUnref(priv->monitor);
         priv->monitor = NULL;
         virDomainConfVMNWFilterTeardown(vm);
 
-- 
1.7.10.4




More information about the libvir-list mailing list