From: "Daniel P. Berrange" <berrange(a)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(a)redhat.com>
---
po/POTFILES.in | 1 +
src/Makefile.am | 1 +
src/lxc/lxc_domain.h | 4 +-
src/lxc/lxc_monitor.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++++
src/lxc/lxc_monitor.h | 54 ++++++++++++++++
src/lxc/lxc_process.c | 73 +++++++++++++---------
6 files changed, 267 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 0f32918..2b0bae5 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 13641ce..7018979 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -392,6 +392,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..d334c10
--- /dev/null
+++ b/src/lxc/lxc_monitor.c
@@ -0,0 +1,165 @@
+/*
+ * 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, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#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 refs */
+
+ 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) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ mon->refs = 1;
+
+ 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:
+ 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);
+ 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..d3b6387
--- /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, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#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 1a6a209..67465b5 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -178,9 +178,13 @@ 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);
+ virLXCMonitorLock(priv->monitor);
+ if (virLXCMonitorUnref(priv->monitor) > 0)
+ virLXCMonitorUnlock(priv->monitor);
+ priv->monitor = NULL;
+ }
virPidFileDelete(driver->stateDir, vm->def->name);
virDomainDeleteConfig(driver->stateDir, NULL, vm);
@@ -471,13 +475,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 +520,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) {
+ virLXCMonitorLock(monitor);
+ virLXCMonitorUnref(monitor);
+ monitor = NULL;
+ }
goto cleanup;
}
- if (!monitor)
- goto cleanup;
-
- virNetClientSetCloseCallback(monitor, virLXCProcessMonitorEOFNotify, vm, NULL);
-
cleanup:
- VIR_FREE(sockpath);
return monitor;
}
@@ -1041,9 +1053,12 @@ cleanup:
VIR_FREE(veths[i]);
}
if (rc != 0) {
- virNetClientClose(priv->monitor);
- virNetClientFree(priv->monitor);
- priv->monitor = NULL;
+ if (priv->monitor) {
+ virLXCMonitorLock(priv->monitor);
+ if (virLXCMonitorUnref(priv->monitor) > 0)
+ virLXCMonitorUnlock(priv->monitor);
+ priv->monitor = NULL;
+ }
virDomainConfVMNWFilterTeardown(vm);
virSecurityManagerRestoreAllLabel(driver->securityManager,
--
1.7.10.4