From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> 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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list