On Wed, Jul 24, 2024 at 05:34:32PM GMT, Peter Krempa wrote:
+static void
+qemuMigrationDstPrepareDiskSeclabels(virDomainObj *vm,
+ size_t nmigrate_disks,
+ const char **migrate_disks,
+ unsigned int flags)
+{
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver);
+ size_t i;
+
+ /* In case when storage is exported from this host, security label
+ * remembering would behave differently compared to the host which mounts
+ * the exported filesystem. Specifically for incoming migration remembering
+ * a seclabel would remember a seclabel already allowing access to the image,
+ * which is not desired. Thus we skip remembering of seclabels for images
+ * which are local to this host but accessed in a shared way from another
+ * host.
+ */
+ if (!cfg->sharedFilesystems ||
+ cfg->sharedFilesystems[0] == NULL)
+ return;
+
+ for (i = 0; i < vm->def->ndisks; i++) {
+ virDomainDiskDef *disk = vm->def->disks[i];
This only iterates over disks, so it's probably not surprising that
it fails when other types of storage are involved.
For example, if the domain uses UEFI, local -> remote migration works
but when attempting to migrate back I get
error: Requested operation is not valid: Setting different SELinux
label on /var/lib/libvirt/qemu/nvram/cirros-efi_VARS.fd which is
already in use
If I add TPM into the mix, local -> remote migration fails with
error: unable to lock
/var/lib/libvirt/swtpm/50601047-47f7-4f45-9b41-9112dfaa3539/tpm2/.lock
for metadata change: Resource temporarily unavailable
Setting remember_owner=0 in qemu.conf makes all these errors go away,
but of course that's a very big hammer and the idea here is to use a
much smaller, more targeted one.
I think it might be enough to extend this logic beyond disks so that
it covers UEFI and TPM too, but I'm not entirely sure those use a
virStorageSource behind the scenes. Hopefully that's the case and the
changes needed on top are minimal, but I figure you're in a better
position than me to look into it.
+ /* We care only about existing local storage */
+ if (virStorageSourceIsEmpty(disk->src) ||
+ !virStorageSourceIsLocalStorage(disk->src))
+ continue;
+
+ /* Only paths which are on local filesystem but shared elsewhere are
+ * relevant */
+ if (!virFileIsSharedFSOverride(disk->src->path,
cfg->sharedFilesystems))
+ continue;
+
+ /* Any storage that was migrated via NBD is technically fully local so
+ * we want seclabels remembered */
+ if (flags & (VIR_MIGRATE_NON_SHARED_DISK | VIR_MIGRATE_NON_SHARED_INC)) {
+ if (qemuMigrationAnyCopyDisk(disk, nmigrate_disks, migrate_disks))
+ continue;
+ }
+
+ disk->src->seclabelSkipRemeber = true;
You misspelled "remember" here.
@@ -3154,6 +3201,8 @@ qemuMigrationDstPrepareActive(virQEMUDriver
*driver,
dataFD[0])))
goto error;
+ qemuMigrationDstPrepareDiskSeclabels(vm, nmigrate_disks, migrate_disks, flags);
+
if (qemuProcessPrepareDomain(driver, vm, startFlags) < 0)
goto error;
One thing that concerns me is that the changes appear to only be on
the destination side of the migration. So only the remote -> local
path is affected. But what about the local -> remote path?
If we assume remember_owner=1, then obviously the various XATTRs
related to remembering will be set on domain startup. What will take
care of collecting that garbage once local -> remote migration has
been performed? I think things might be fine based on the fact that
the XATTRs seems to be dropped for disks even in the current state,
but I thought I'd mention this specifically just in case.
Thanks a lot for looking into this!
--
Andrea Bolognani / Red Hat / Virtualization