Currently, if qemuProcessStart fail at some point, e.g. because
domain being started wants a PCI/USB device already assigned to
a different domain, we jump to cleanup label where qemuProcessStop
is performed. This unconditionally calls virSecurityManagerRestoreAllLabel
which is wrong because the other domain is still using those devices.
However, once we successfully label all devices/paths in
qemuProcessStart() from that point on, we have to perform a rollback
on failure - that is - we have to virSecurityManagerRestoreAllLabel.
---
src/qemu/qemu_process.c | 12 ++++++++----
src/qemu/qemu_process.h | 3 ++-
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 4cb0a83..0309bfb 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3281,6 +3281,7 @@ int qemuProcessStart(virConnectPtr conn,
int i;
char *nodeset = NULL;
char *nodemask = NULL;
+ unsigned int stop_flags = VIR_QEMU_PROCESS_STOP_NO_RELABEL;
/* Okay, these are just internal flags,
* but doesn't hurt to check */
@@ -3631,6 +3632,8 @@ int qemuProcessStart(virConnectPtr conn,
vm->def, stdin_path) < 0)
goto cleanup;
+ stop_flags &= ~VIR_QEMU_PROCESS_STOP_NO_RELABEL;
+
if (stdin_fd != -1) {
/* if there's an fd to migrate from, and it's a pipe, put the
* proper security label on it
@@ -3770,7 +3773,7 @@ cleanup:
VIR_FREE(nodemask);
virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile);
- qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, 0);
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
return -1;
}
@@ -3984,9 +3987,10 @@ void qemuProcessStop(struct qemud_driver *driver,
}
/* Reset Security Labels */
- virSecurityManagerRestoreAllLabel(driver->securityManager,
- vm->def,
- flags & VIR_QEMU_PROCESS_STOP_MIGRATED);
+ if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL))
+ virSecurityManagerRestoreAllLabel(driver->securityManager,
+ vm->def,
+ flags & VIR_QEMU_PROCESS_STOP_MIGRATED);
virSecurityManagerReleaseLabel(driver->securityManager, vm->def);
/* Clear out dynamically assigned labels */
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index ce59215..d13778d 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -61,7 +61,8 @@ int qemuProcessStart(virConnectPtr conn,
unsigned int flags);
typedef enum {
- VIR_QEMU_PROCESS_STOP_MIGRATED = 1 << 0,
+ VIR_QEMU_PROCESS_STOP_MIGRATED = 1 << 0,
+ VIR_QEMU_PROCESS_STOP_NO_RELABEL = 1 << 1,
} qemuProcessStopFlags;
void qemuProcessStop(struct qemud_driver *driver,
--
1.7.8.5