
On Thu, Dec 02, 2021 at 16:56:49 +0100, Jiri Denemark wrote:
Userfaultfd is by default allowed only for privileged processes. Since libvirt runs QEMU unprivileged, we need to enable unprivileged access to userfaultfd before starting post-copy migration.
Rather than providing a static sysctl configuration file, we set the sysctl knob in runtime once post-copy migration is requested. This way unprivileged_userfaultfd is only enabled once actually used.
https://bugzilla.redhat.com/show_bug.cgi?id=1945420
Signed-off-by: Jiri Denemark <jdenemar@redhat.com> --- src/qemu/qemu_migration_params.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c index dbc3219826..a9449ed1ff 100644 --- a/src/qemu/qemu_migration_params.c +++ b/src/qemu/qemu_migration_params.c @@ -804,6 +804,24 @@ qemuMigrationCapsToJSON(virBitmap *caps, }
+static void +qemuMigrationParamsEnableUserfaultfd(virDomainObj *vm)
passing 'vm'
+{ + const char *sysctl = "/proc/sys/vm/unprivileged_userfaultfd"; + + if (!virFileExists(sysctl)) + return; + + VIR_DEBUG("Enabling unprivileged userfaultfd for post-copy migration of " + "domain %s", vm->def->name);
Just to debug-log the VM name is a bit pointless. If debug logs are enabled you'll be able to figure out the migrated VM by other log entries.
+ + if (virFileWriteStr(sysctl, "1", 0) < 0) { + virReportSystemError(errno, "%s", + _("failed to enable unprivileged userfaultfd"));
Reporting an error and not actually failing is also something we rarely do. Firstly it can set the error object and report a spurious error in cases when we'd forget to set an error, and additionally it can flood system logs with 'error' level messages which is also getting frequently reported.
+ } +} + + /** * qemuMigrationParamsApply * @driver: qemu driver @@ -839,6 +857,13 @@ qemuMigrationParamsApply(virQEMUDriver *driver, goto cleanup; } } else { + /* userfaultfd may only be enabled for privileged processes by default, + * we need to make sure QEMU can use it before enabling post-copy + * migration */ + if (virBitmapIsBitSet(priv->migrationCaps, QEMU_MIGRATION_CAP_POSTCOPY) && + virBitmapIsBitSet(migParams->caps, QEMU_MIGRATION_CAP_POSTCOPY)) + qemuMigrationParamsEnableUserfaultfd(vm); + if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps))) goto cleanup;
-- 2.34.1