aboutsummaryrefslogtreecommitdiff
path: root/src/lxc
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2012-07-17 12:14:35 +0100
committerDaniel P. Berrange <berrange@redhat.com>2012-07-30 12:50:22 +0100
commitde4b32e4bf7394bc697e87133d0461db87f4a392 (patch)
tree942948e4d2be670f14d403632d82ac989d144aed /src/lxc
parentConvert the LXC driver to use virNetClient (diff)
downloadlibvirt-de4b32e4bf7394bc697e87133d0461db87f4a392.tar.gz
libvirt-de4b32e4bf7394bc697e87133d0461db87f4a392.tar.bz2
libvirt-de4b32e4bf7394bc697e87133d0461db87f4a392.zip
Move LXC monitor code out into separate file
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@redhat.com>
Diffstat (limited to 'src/lxc')
-rw-r--r--src/lxc/lxc_domain.h4
-rw-r--r--src/lxc/lxc_monitor.c176
-rw-r--r--src/lxc/lxc_monitor.h54
-rw-r--r--src/lxc/lxc_process.c80
4 files changed, 283 insertions, 31 deletions
diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h
index 190202e7f..318c78eb6 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;
bool doneStopEvent;
};
diff --git a/src/lxc/lxc_monitor.c b/src/lxc/lxc_monitor.c
new file mode 100644
index 000000000..da170ae6a
--- /dev/null
+++ b/src/lxc/lxc_monitor.c
@@ -0,0 +1,176 @@
+/*
+ * 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);
+}
+
+
+static void virLXCMonitorCloseFreeCallback(void *opaque)
+{
+ virLXCMonitorPtr mon = opaque;
+ virLXCMonitorLock(mon);
+ if (virLXCMonitorUnref(mon) > 0)
+ virLXCMonitorUnlock(mon);
+}
+
+
+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;
+
+ virLXCMonitorRef(mon);
+ virNetClientSetCloseCallback(mon->client, virLXCMonitorEOFNotify, mon,
+ virLXCMonitorCloseFreeCallback);
+
+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 000000000..d3b6387b1
--- /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 c93468f22..89c2b214b 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -181,9 +181,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);
@@ -474,13 +478,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;
virLXCDomainObjPrivatePtr priv;
@@ -513,36 +529,39 @@ 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);
+ /* Hold an extra reference because we can't allow 'vm' to be
+ * deleted while the monitor is active */
+ virDomainObjRef(vm);
+
+ monitor = virLXCMonitorNew(vm, driver->stateDir, &monitorCallbacks);
+
+ if (monitor == NULL)
+ ignore_value(virDomainObjUnref(vm));
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;
}
@@ -1051,9 +1070,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,