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(a)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