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>
This commit is contained in:
Daniel P. Berrange 2012-07-17 12:14:35 +01:00
parent 357866c379
commit de4b32e4bf
6 changed files with 285 additions and 31 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
};

176
src/lxc/lxc_monitor.c Normal file
View File

@ -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);
}

54
src/lxc/lxc_monitor.h Normal file
View File

@ -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__ */

View File

@ -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,