On Fri, Jul 26, 2024 at 07:47:57 -0700, Andrea Bolognani wrote: > 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. Hmm, yeah. > 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 So I've kind of forgot about this one. That's mainly as sharing this path is not actually needed for migration to work, as the contents are shared inside the migration stream automatically. Given though that users might want to share this one, so that they can start the VM withouth migration on a different host and also we allow setting the path to a more reasonable directory for sharing (users should not share /var/lib/libvirt/qemu/nvram/, or anything belonging to libvirt in the first place) we should treat this one the same as disk sources. Good thing that the nvram path is now a virStorage source. Now this also shows that we've forgotten to give it the same treatment that disk images get inside qemuProcessStop() (see below for explanation. > 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 This makes it look like the file is still locked, that might be indication of a different problem as libvirt will not keep the lock after updating the XATTRs. > 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. Yup, as I've stated we must never suggest that users disable this feature. > 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 At least the R/W pflash device is handled by virStorageSource so that should be easy. > 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. Eh ... and copied it all over place :D > > > @@ -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? On the source side, at least for disks we simply nuke the metadata(xattrs). In fact we do that in most cases when stopping the VM, not only for migration. See qemuProcessStop(), in the loop which calls qemuBlockRemoveImageMetadata(). That call removes the metadata from all disk top level sources. While the original intention might have been different (block jobs) it also ensures that this behaves correctly in this corner case. Now it seems that at least the varstore pflash virStorageSource requires the same treatment there. > 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. So apart from the code I've mentioned above which explicitly drops the xattrs, they are also not shared via NFS. Thus the remote side itself would not get them. If we'd leak them though it would mean that a re-start or incoming migration on the source of the migration would no longer work, so we need the same treatment for the other resources as well. I'll post another version adding the missing treatment for uefi, but I don't think I care enough about TPMs to go digging how that stuff is plumbed in or why it complains about locks being held which don't seem to be held by libvirt.