From 8fa0374c5b8e834fcbdeae674cc6cc9e6bf9019f Mon Sep 17 00:00:00 2001 From: Michal Privoznik Date: Mon, 18 Nov 2019 17:40:01 +0100 Subject: [PATCH] qemuProcessStop: Remove image metadata for running mirror jobs If user starts a blockcommit or a blockcopy then we modify access for qemu on both images and leave it like that until the job terminates. So far so good. Problem is, if user instead of terminating the job (where we would modify the access again so that the state before the job is restored) calls destroy on the domain or if qemu dies whilst executing the block job. In this case we don't ever clear the access we granted at the beginning. To fix this, maybe a bit harsh approach is used, but it works: after all labels were restored (that is after qemuSecurityRestoreAllLabel() was called), we iterate over each disk in the domain and remove XATTRs from the whole backing chain and also from any file the disk is being mirrored to. This would have been done at the time of pivot, but it isn't because user decided to kill the domain instead. If we don't do this and leave some XATTRs behind the domain might be unable to start. Also, secdriver can't do this because it doesn't know if there is any job running. It's outside of its scope - the hypervisor driver is responsible for calling secdriver's APIs. Moreover, this is safe to call because we don't remember labels for any member of a backing chain except of the top layer. But that one was restored in qemuSecurityRestoreAllLabel() call done earlier. Therefore, not only we don't remember labels (and thus this is basically a NOP for other images in the backing chain) it is also safe to call this when no blockjob was started in the first place, or if some parts of the backing chain are shared with some other domains - this is NOP, unless a block job is active at the time of domain destroy. https://bugzilla.redhat.com/show_bug.cgi?id=1741456#c19 Signed-off-by: Michal Privoznik Reviewed-by: Peter Krempa --- src/qemu/qemu_process.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 59fd0c11ba..161b3910e5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7611,6 +7611,18 @@ void qemuProcessStop(virQEMUDriverPtr driver, for (i = 0; i < vm->def->niothreadids; i++) vm->def->iothreadids[i]->thread_id = 0; + /* Do this explicitly after vm->pid is reset so that security drivers don't + * try to enter the domain's namespace which is non-existent by now as qemu + * is no longer running. */ + for (i = 0; i < def->ndisks; i++) { + virDomainDiskDefPtr disk = def->disks[i]; + + if (disk->mirror) + qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->mirror); + + qemuBlockRemoveImageMetadata(driver, vm, disk->dst, disk->src); + } + /* clear all private data entries which are no longer needed */ qemuDomainObjPrivateDataClear(priv);