
On 11.06.2012 18:54, Eric Blake wrote:
On 06/11/2012 08:29 AM, Michal Privoznik wrote:
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(-)
Double-negative logic. But I guess we're stuck with it, as the default of 'flags==0' must imply the relabel.
@@ -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))
Took me a couple reads to convince myself that I couldn't come up with any nicer wording of this condition without breaking defaults.
ACK.
Yeah, it is quite confusing, therefore I am squashing in some comments before pushing: diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0309bfb..5f3aa99 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3281,7 +3281,7 @@ int qemuProcessStart(virConnectPtr conn, int i; char *nodeset = NULL; char *nodemask = NULL; - unsigned int stop_flags = VIR_QEMU_PROCESS_STOP_NO_RELABEL; + unsigned int stop_flags; /* Okay, these are just internal flags, * but doesn't hurt to check */ @@ -3289,6 +3289,12 @@ int qemuProcessStart(virConnectPtr conn, VIR_QEMU_PROCESS_START_PAUSED | VIR_QEMU_PROCESS_START_AUTODESROY, -1); + /* From now on until domain security labeling is done: + * if any operation fails and we goto cleanup, we must not + * restore any security label as we would overwrite labels + * we did not set. */ + stop_flags = VIR_QEMU_PROCESS_STOP_NO_RELABEL; + hookData.conn = conn; hookData.vm = vm; hookData.driver = driver; @@ -3632,6 +3638,10 @@ int qemuProcessStart(virConnectPtr conn, vm->def, stdin_path) < 0) goto cleanup; + /* Security manager labeled all devices, therefore + * if any operation from now on fails and we goto cleanup, + * where virSecurityManagerRestoreAllLabel() is called + * (hidden under qemuProcessStop) we need to restore labels. */ stop_flags &= ~VIR_QEMU_PROCESS_STOP_NO_RELABEL; if (stdin_fd != -1) { @@ -3986,7 +3996,7 @@ void qemuProcessStop(struct qemud_driver *driver, VIR_FREE(xml); } - /* Reset Security Labels */ + /* Reset Security Labels unless caller don't want us to */ if (!(flags & VIR_QEMU_PROCESS_STOP_NO_RELABEL)) virSecurityManagerRestoreAllLabel(driver->securityManager, vm->def, --- And pushed now. Thanks for review! Michal