mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 21:34:54 +03:00
Add support for autodestroy of guests to the LXC and UML drivers
We recently added support for VIR_DOMAIN_START_AUTODESTROY and an impl to the QEMU driver. It is very desirable to support in other drivers, so this adds it to LXC and UML * src/lxc/lxc_conf.h, src/lxc/lxc_driver.c, src/uml/uml_conf.h, src/uml/uml_driver.c: Wire up autodestroy functions
This commit is contained in:
parent
07862822f3
commit
02e92dc470
@ -56,6 +56,11 @@ struct __lxc_driver {
|
||||
int have_netns;
|
||||
|
||||
virDomainEventStatePtr domainEventState;
|
||||
|
||||
/* Mapping of 'char *uuidstr' -> virConnectPtr
|
||||
* of guests which will be automatically killed
|
||||
* when the virConnectPtr is closed*/
|
||||
virHashTablePtr autodestroy;
|
||||
};
|
||||
|
||||
int lxcLoadDriverConfig(lxc_driver_t *driver);
|
||||
|
@ -110,6 +110,19 @@ static void lxcDomainEventFlush(int timer, void *opaque);
|
||||
static void lxcDomainEventQueue(lxc_driver_t *driver,
|
||||
virDomainEventPtr event);
|
||||
|
||||
static int lxcVmTerminate(lxc_driver_t *driver,
|
||||
virDomainObjPtr vm,
|
||||
virDomainShutoffReason reason);
|
||||
static int lxcProcessAutoDestroyInit(lxc_driver_t *driver);
|
||||
static void lxcProcessAutoDestroyRun(lxc_driver_t *driver,
|
||||
virConnectPtr conn);
|
||||
static void lxcProcessAutoDestroyShutdown(lxc_driver_t *driver);
|
||||
static int lxcProcessAutoDestroyAdd(lxc_driver_t *driver,
|
||||
virDomainObjPtr vm,
|
||||
virConnectPtr conn);
|
||||
static int lxcProcessAutoDestroyRemove(lxc_driver_t *driver,
|
||||
virDomainObjPtr vm);
|
||||
|
||||
|
||||
static virDrvOpenStatus lxcOpen(virConnectPtr conn,
|
||||
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
|
||||
@ -165,6 +178,7 @@ static int lxcClose(virConnectPtr conn)
|
||||
lxcDriverLock(driver);
|
||||
virDomainEventCallbackListRemoveConn(conn,
|
||||
driver->domainEventState->callbacks);
|
||||
lxcProcessAutoDestroyRun(driver, conn);
|
||||
lxcDriverUnlock(driver);
|
||||
|
||||
conn->privateData = NULL;
|
||||
@ -1001,6 +1015,104 @@ cleanup:
|
||||
}
|
||||
|
||||
|
||||
static int lxcProcessAutoDestroyInit(lxc_driver_t *driver)
|
||||
{
|
||||
if (!(driver->autodestroy = virHashCreate(5, NULL)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lxcProcessAutoDestroyData {
|
||||
lxc_driver_t *driver;
|
||||
virConnectPtr conn;
|
||||
};
|
||||
|
||||
static void lxcProcessAutoDestroyDom(void *payload,
|
||||
const void *name,
|
||||
void *opaque)
|
||||
{
|
||||
struct lxcProcessAutoDestroyData *data = opaque;
|
||||
virConnectPtr conn = payload;
|
||||
const char *uuidstr = name;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
virDomainObjPtr dom;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
|
||||
|
||||
if (data->conn != conn)
|
||||
return;
|
||||
|
||||
if (virUUIDParse(uuidstr, uuid) < 0) {
|
||||
VIR_WARN("Failed to parse %s", uuidstr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(dom = virDomainFindByUUID(&data->driver->domains,
|
||||
uuid))) {
|
||||
VIR_DEBUG("No domain object to kill");
|
||||
return;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Killing domain");
|
||||
lxcVmTerminate(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||
virDomainAuditStop(dom, "destroyed");
|
||||
event = virDomainEventNewFromObj(dom,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
||||
|
||||
if (dom && !dom->persistent)
|
||||
virDomainRemoveInactive(&data->driver->domains, dom);
|
||||
|
||||
if (dom)
|
||||
virDomainObjUnlock(dom);
|
||||
if (event)
|
||||
lxcDomainEventQueue(data->driver, event);
|
||||
virHashRemoveEntry(data->driver->autodestroy, uuidstr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Precondition: driver is locked
|
||||
*/
|
||||
static void lxcProcessAutoDestroyRun(lxc_driver_t *driver, virConnectPtr conn)
|
||||
{
|
||||
struct lxcProcessAutoDestroyData data = {
|
||||
driver, conn
|
||||
};
|
||||
VIR_DEBUG("conn=%p", conn);
|
||||
virHashForEach(driver->autodestroy, lxcProcessAutoDestroyDom, &data);
|
||||
}
|
||||
|
||||
static void lxcProcessAutoDestroyShutdown(lxc_driver_t *driver)
|
||||
{
|
||||
virHashFree(driver->autodestroy);
|
||||
}
|
||||
|
||||
static int lxcProcessAutoDestroyAdd(lxc_driver_t *driver,
|
||||
virDomainObjPtr vm,
|
||||
virConnectPtr conn)
|
||||
{
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||
VIR_DEBUG("vm=%s uuid=%s conn=%p", vm->def->name, uuidstr, conn);
|
||||
if (virHashAddEntry(driver->autodestroy, uuidstr, conn) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lxcProcessAutoDestroyRemove(lxc_driver_t *driver,
|
||||
virDomainObjPtr vm)
|
||||
{
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||
VIR_DEBUG("vm=%s uuid=%s", vm->def->name, uuidstr);
|
||||
if (virHashRemoveEntry(driver->autodestroy, uuidstr) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* lxcVmCleanup:
|
||||
* @driver: pointer to driver structure
|
||||
@ -1028,6 +1140,9 @@ static void lxcVmCleanup(lxc_driver_t *driver,
|
||||
VIR_FREE(xml);
|
||||
}
|
||||
|
||||
/* Stop autodestroy in case guest is restarted */
|
||||
lxcProcessAutoDestroyRemove(driver, vm);
|
||||
|
||||
virEventRemoveHandle(priv->monitorWatch);
|
||||
VIR_FORCE_CLOSE(priv->monitor);
|
||||
|
||||
@ -1496,6 +1611,7 @@ cleanup:
|
||||
* @conn: pointer to connection
|
||||
* @driver: pointer to driver structure
|
||||
* @vm: pointer to virtual machine structure
|
||||
* @autoDestroy: mark the domain for auto destruction
|
||||
* @reason: reason for switching vm to running state
|
||||
*
|
||||
* Starts a vm
|
||||
@ -1505,6 +1621,7 @@ cleanup:
|
||||
static int lxcVmStart(virConnectPtr conn,
|
||||
lxc_driver_t * driver,
|
||||
virDomainObjPtr vm,
|
||||
bool autoDestroy,
|
||||
virDomainRunningReason reason)
|
||||
{
|
||||
int rc = -1, r;
|
||||
@ -1665,6 +1782,10 @@ static int lxcVmStart(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (autoDestroy &&
|
||||
lxcProcessAutoDestroyAdd(driver, vm, conn) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/*
|
||||
* Again, need to save the live configuration, because the function
|
||||
* requires vm->def->id != -1 to save tty info surely.
|
||||
@ -1719,7 +1840,7 @@ static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
|
||||
virDomainEventPtr event = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
|
||||
|
||||
lxcDriverLock(driver);
|
||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||
@ -1743,7 +1864,9 @@ static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = lxcVmStart(dom->conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
|
||||
ret = lxcVmStart(dom->conn, driver, vm,
|
||||
(flags & VIR_DOMAIN_START_AUTODESTROY),
|
||||
VIR_DOMAIN_RUNNING_BOOTED);
|
||||
|
||||
if (ret == 0) {
|
||||
event = virDomainEventNewFromObj(vm,
|
||||
@ -1796,7 +1919,7 @@ lxcDomainCreateAndStart(virConnectPtr conn,
|
||||
virDomainPtr dom = NULL;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
|
||||
|
||||
lxcDriverLock(driver);
|
||||
if (!(def = virDomainDefParseString(driver->caps, xml,
|
||||
@ -1819,7 +1942,9 @@ lxcDomainCreateAndStart(virConnectPtr conn,
|
||||
goto cleanup;
|
||||
def = NULL;
|
||||
|
||||
if (lxcVmStart(conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
|
||||
if (lxcVmStart(conn, driver, vm,
|
||||
(flags & VIR_DOMAIN_START_AUTODESTROY),
|
||||
VIR_DOMAIN_RUNNING_BOOTED) < 0) {
|
||||
virDomainAuditStart(vm, "booted", false);
|
||||
virDomainRemoveInactive(&driver->domains, vm);
|
||||
vm = NULL;
|
||||
@ -2054,7 +2179,7 @@ lxcAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
|
||||
virDomainObjLock(vm);
|
||||
if (vm->autostart &&
|
||||
!virDomainObjIsActive(vm)) {
|
||||
int ret = lxcVmStart(data->conn, data->driver, vm,
|
||||
int ret = lxcVmStart(data->conn, data->driver, vm, false,
|
||||
VIR_DOMAIN_RUNNING_BOOTED);
|
||||
virDomainAuditStart(vm, "booted", ret >= 0);
|
||||
if (ret < 0) {
|
||||
@ -2205,6 +2330,9 @@ static int lxcStartup(int privileged)
|
||||
lxc_driver->caps->privateDataAllocFunc = lxcDomainObjPrivateAlloc;
|
||||
lxc_driver->caps->privateDataFreeFunc = lxcDomainObjPrivateFree;
|
||||
|
||||
if (lxcProcessAutoDestroyInit(lxc_driver) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* Get all the running persistent or transient configs first */
|
||||
if (virDomainLoadAllConfigs(lxc_driver->caps,
|
||||
&lxc_driver->domains,
|
||||
@ -2285,6 +2413,8 @@ static int lxcShutdown(void)
|
||||
virDomainObjListDeinit(&lxc_driver->domains);
|
||||
virDomainEventStateFree(lxc_driver->domainEventState);
|
||||
|
||||
lxcProcessAutoDestroyShutdown(lxc_driver);
|
||||
|
||||
virCapabilitiesFree(lxc_driver->caps);
|
||||
VIR_FREE(lxc_driver->configDir);
|
||||
VIR_FREE(lxc_driver->autostartDir);
|
||||
|
@ -33,6 +33,7 @@
|
||||
# include "virterror_internal.h"
|
||||
# include "threads.h"
|
||||
# include "command.h"
|
||||
# include "hash.h"
|
||||
|
||||
# define umlDebug(fmt, ...) do {} while(0)
|
||||
|
||||
@ -64,6 +65,11 @@ struct uml_driver {
|
||||
|
||||
/* Event handling */
|
||||
virDomainEventStatePtr domainEventState;
|
||||
|
||||
/* Mapping of 'char *uuidstr' -> virConnectPtr
|
||||
* of guests which will be automatically killed
|
||||
* when the virConnectPtr is closed*/
|
||||
virHashTablePtr autodestroy;
|
||||
};
|
||||
|
||||
|
||||
|
@ -75,6 +75,16 @@ struct _umlDomainObjPrivate {
|
||||
int monitorWatch;
|
||||
};
|
||||
|
||||
static int umlProcessAutoDestroyInit(struct uml_driver *driver);
|
||||
static void umlProcessAutoDestroyRun(struct uml_driver *driver,
|
||||
virConnectPtr conn);
|
||||
static void umlProcessAutoDestroyShutdown(struct uml_driver *driver);
|
||||
static int umlProcessAutoDestroyAdd(struct uml_driver *driver,
|
||||
virDomainObjPtr vm,
|
||||
virConnectPtr conn);
|
||||
static int umlProcessAutoDestroyRemove(struct uml_driver *driver,
|
||||
virDomainObjPtr vm);
|
||||
|
||||
|
||||
static int umlShutdown(void);
|
||||
|
||||
@ -119,10 +129,10 @@ static void umlDomainEventQueue(struct uml_driver *driver,
|
||||
|
||||
static int umlStartVMDaemon(virConnectPtr conn,
|
||||
struct uml_driver *driver,
|
||||
virDomainObjPtr vm);
|
||||
virDomainObjPtr vm,
|
||||
bool autoDestroy);
|
||||
|
||||
static void umlShutdownVMDaemon(virConnectPtr conn,
|
||||
struct uml_driver *driver,
|
||||
static void umlShutdownVMDaemon(struct uml_driver *driver,
|
||||
virDomainObjPtr vm,
|
||||
virDomainShutoffReason reason);
|
||||
|
||||
@ -150,7 +160,7 @@ umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
|
||||
!virDomainObjIsActive(vm)) {
|
||||
int ret;
|
||||
virResetLastError();
|
||||
ret = umlStartVMDaemon(data->conn, data->driver, vm);
|
||||
ret = umlStartVMDaemon(data->conn, data->driver, vm, false);
|
||||
virDomainAuditStart(vm, "booted", ret >= 0);
|
||||
if (ret < 0) {
|
||||
virErrorPtr err = virGetLastError();
|
||||
@ -309,7 +319,7 @@ reread:
|
||||
continue;
|
||||
}
|
||||
|
||||
umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||
umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||
virDomainAuditStop(dom, "shutdown");
|
||||
event = virDomainEventNewFromObj(dom,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
@ -337,7 +347,7 @@ reread:
|
||||
|
||||
if (umlOpenMonitor(driver, dom) < 0) {
|
||||
VIR_WARN("Could not open monitor for new domain");
|
||||
umlShutdownVMDaemon(NULL, driver, dom,
|
||||
umlShutdownVMDaemon(driver, dom,
|
||||
VIR_DOMAIN_SHUTOFF_FAILED);
|
||||
virDomainAuditStop(dom, "failed");
|
||||
event = virDomainEventNewFromObj(dom,
|
||||
@ -350,7 +360,7 @@ reread:
|
||||
}
|
||||
} else if (umlIdentifyChrPTY(driver, dom) < 0) {
|
||||
VIR_WARN("Could not identify character devices for new domain");
|
||||
umlShutdownVMDaemon(NULL, driver, dom,
|
||||
umlShutdownVMDaemon(driver, dom,
|
||||
VIR_DOMAIN_SHUTOFF_FAILED);
|
||||
virDomainAuditStop(dom, "failed");
|
||||
event = virDomainEventNewFromObj(dom,
|
||||
@ -480,6 +490,9 @@ umlStartup(int privileged)
|
||||
umlInotifyEvent, uml_driver, NULL)) < 0)
|
||||
goto error;
|
||||
|
||||
if (umlProcessAutoDestroyInit(uml_driver) < 0)
|
||||
goto error;
|
||||
|
||||
if (virDomainLoadAllConfigs(uml_driver->caps,
|
||||
¨_driver->domains,
|
||||
uml_driver->configDir,
|
||||
@ -577,7 +590,7 @@ umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
|
||||
|
||||
virDomainObjLock(dom);
|
||||
if (virDomainObjIsActive(dom)) {
|
||||
umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||
umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||
virDomainAuditStop(dom, "shutdown");
|
||||
}
|
||||
virDomainObjUnlock(dom);
|
||||
@ -612,6 +625,8 @@ umlShutdown(void) {
|
||||
VIR_FREE(uml_driver->autostartDir);
|
||||
VIR_FREE(uml_driver->monitorDir);
|
||||
|
||||
umlProcessAutoDestroyShutdown(uml_driver);
|
||||
|
||||
if (uml_driver->brctl)
|
||||
brShutdown(uml_driver->brctl);
|
||||
|
||||
@ -623,6 +638,104 @@ umlShutdown(void) {
|
||||
}
|
||||
|
||||
|
||||
static int umlProcessAutoDestroyInit(struct uml_driver *driver)
|
||||
{
|
||||
if (!(driver->autodestroy = virHashCreate(5, NULL)))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct umlProcessAutoDestroyData {
|
||||
struct uml_driver *driver;
|
||||
virConnectPtr conn;
|
||||
};
|
||||
|
||||
static void umlProcessAutoDestroyDom(void *payload,
|
||||
const void *name,
|
||||
void *opaque)
|
||||
{
|
||||
struct umlProcessAutoDestroyData *data = opaque;
|
||||
virConnectPtr conn = payload;
|
||||
const char *uuidstr = name;
|
||||
unsigned char uuid[VIR_UUID_BUFLEN];
|
||||
virDomainObjPtr dom;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
|
||||
|
||||
if (data->conn != conn)
|
||||
return;
|
||||
|
||||
if (virUUIDParse(uuidstr, uuid) < 0) {
|
||||
VIR_WARN("Failed to parse %s", uuidstr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(dom = virDomainFindByUUID(&data->driver->domains,
|
||||
uuid))) {
|
||||
VIR_DEBUG("No domain object to kill");
|
||||
return;
|
||||
}
|
||||
|
||||
VIR_DEBUG("Killing domain");
|
||||
umlShutdownVMDaemon(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||
virDomainAuditStop(dom, "destroyed");
|
||||
event = virDomainEventNewFromObj(dom,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
|
||||
|
||||
if (dom && !dom->persistent)
|
||||
virDomainRemoveInactive(&data->driver->domains, dom);
|
||||
|
||||
if (dom)
|
||||
virDomainObjUnlock(dom);
|
||||
if (event)
|
||||
umlDomainEventQueue(data->driver, event);
|
||||
virHashRemoveEntry(data->driver->autodestroy, uuidstr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Precondition: driver is locked
|
||||
*/
|
||||
static void umlProcessAutoDestroyRun(struct uml_driver *driver, virConnectPtr conn)
|
||||
{
|
||||
struct umlProcessAutoDestroyData data = {
|
||||
driver, conn
|
||||
};
|
||||
VIR_DEBUG("conn=%p", conn);
|
||||
virHashForEach(driver->autodestroy, umlProcessAutoDestroyDom, &data);
|
||||
}
|
||||
|
||||
static void umlProcessAutoDestroyShutdown(struct uml_driver *driver)
|
||||
{
|
||||
virHashFree(driver->autodestroy);
|
||||
}
|
||||
|
||||
static int umlProcessAutoDestroyAdd(struct uml_driver *driver,
|
||||
virDomainObjPtr vm,
|
||||
virConnectPtr conn)
|
||||
{
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||
VIR_DEBUG("vm=%s uuid=%s conn=%p", vm->def->name, uuidstr, conn);
|
||||
if (virHashAddEntry(driver->autodestroy, uuidstr, conn) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int umlProcessAutoDestroyRemove(struct uml_driver *driver,
|
||||
virDomainObjPtr vm)
|
||||
{
|
||||
char uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
virUUIDFormat(vm->def->uuid, uuidstr);
|
||||
VIR_DEBUG("vm=%s uuid=%s", vm->def->name, uuidstr);
|
||||
if (virHashRemoveEntry(driver->autodestroy, uuidstr) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int umlReadPidFile(struct uml_driver *driver,
|
||||
virDomainObjPtr vm)
|
||||
{
|
||||
@ -842,8 +955,7 @@ error:
|
||||
}
|
||||
|
||||
|
||||
static int umlCleanupTapDevices(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr vm) {
|
||||
static int umlCleanupTapDevices(virDomainObjPtr vm) {
|
||||
int i;
|
||||
int err;
|
||||
int ret = 0;
|
||||
@ -873,7 +985,8 @@ static int umlCleanupTapDevices(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
|
||||
static int umlStartVMDaemon(virConnectPtr conn,
|
||||
struct uml_driver *driver,
|
||||
virDomainObjPtr vm) {
|
||||
virDomainObjPtr vm,
|
||||
bool autoDestroy) {
|
||||
int ret;
|
||||
char *logfile;
|
||||
int logfd = -1;
|
||||
@ -935,7 +1048,7 @@ static int umlStartVMDaemon(virConnectPtr conn,
|
||||
if (!(cmd = umlBuildCommandLine(conn, driver, vm))) {
|
||||
VIR_FORCE_CLOSE(logfd);
|
||||
virDomainConfVMNWFilterTeardown(vm);
|
||||
umlCleanupTapDevices(conn, vm);
|
||||
umlCleanupTapDevices(vm);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -953,13 +1066,17 @@ static int umlStartVMDaemon(virConnectPtr conn,
|
||||
if (ret < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (autoDestroy &&
|
||||
umlProcessAutoDestroyAdd(driver, vm, conn) < 0)
|
||||
goto cleanup;
|
||||
|
||||
ret = virDomainObjSetDefTransient(driver->caps, vm, false);
|
||||
cleanup:
|
||||
virCommandFree(cmd);
|
||||
|
||||
if (ret < 0) {
|
||||
virDomainConfVMNWFilterTeardown(vm);
|
||||
umlCleanupTapDevices(conn, vm);
|
||||
umlCleanupTapDevices(vm);
|
||||
}
|
||||
|
||||
/* NB we don't mark it running here - we do that async
|
||||
@ -972,8 +1089,7 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
struct uml_driver *driver ATTRIBUTE_UNUSED,
|
||||
static void umlShutdownVMDaemon(struct uml_driver *driver,
|
||||
virDomainObjPtr vm,
|
||||
virDomainShutoffReason reason)
|
||||
{
|
||||
@ -997,7 +1113,10 @@ static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
|
||||
|
||||
virDomainConfVMNWFilterTeardown(vm);
|
||||
umlCleanupTapDevices(conn, vm);
|
||||
umlCleanupTapDevices(vm);
|
||||
|
||||
/* Stop autodestroy in case guest is restarted */
|
||||
umlProcessAutoDestroyRemove(driver, vm);
|
||||
|
||||
if (vm->newDef) {
|
||||
virDomainDefFree(vm->def);
|
||||
@ -1072,6 +1191,7 @@ static int umlClose(virConnectPtr conn) {
|
||||
umlDriverLock(driver);
|
||||
virDomainEventCallbackListRemoveConn(conn,
|
||||
driver->domainEventState->callbacks);
|
||||
umlProcessAutoDestroyRun(driver, conn);
|
||||
umlDriverUnlock(driver);
|
||||
|
||||
conn->privateData = NULL;
|
||||
@ -1342,7 +1462,7 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
|
||||
virDomainPtr dom = NULL;
|
||||
virDomainEventPtr event = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
|
||||
|
||||
umlDriverLock(driver);
|
||||
if (!(def = virDomainDefParseString(driver->caps, xml,
|
||||
@ -1359,7 +1479,8 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
|
||||
goto cleanup;
|
||||
def = NULL;
|
||||
|
||||
if (umlStartVMDaemon(conn, driver, vm) < 0) {
|
||||
if (umlStartVMDaemon(conn, driver, vm,
|
||||
(flags & VIR_DOMAIN_START_AUTODESTROY)) < 0) {
|
||||
virDomainAuditStart(vm, "booted", false);
|
||||
virDomainRemoveInactive(&driver->domains,
|
||||
vm);
|
||||
@ -1436,7 +1557,7 @@ umlDomainDestroyFlags(virDomainPtr dom,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||
umlShutdownVMDaemon(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||
virDomainAuditStop(vm, "destroyed");
|
||||
event = virDomainEventNewFromObj(vm,
|
||||
VIR_DOMAIN_EVENT_STOPPED,
|
||||
@ -1717,7 +1838,7 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
|
||||
virDomainEventPtr event = NULL;
|
||||
int ret = -1;
|
||||
|
||||
virCheckFlags(0, -1);
|
||||
virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
|
||||
|
||||
umlDriverLock(driver);
|
||||
vm = virDomainFindByUUID(&driver->domains, dom->uuid);
|
||||
@ -1728,7 +1849,8 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = umlStartVMDaemon(dom->conn, driver, vm);
|
||||
ret = umlStartVMDaemon(dom->conn, driver, vm,
|
||||
(flags & VIR_DOMAIN_START_AUTODESTROY));
|
||||
virDomainAuditStart(vm, "booted", ret >= 0);
|
||||
if (ret == 0)
|
||||
event = virDomainEventNewFromObj(vm,
|
||||
|
Loading…
Reference in New Issue
Block a user