[libvirt PATCH v2] qemu: Enable unprivileged userfaultfd for post-copy migration

Jiri Denemark jdenemar at redhat.com
Tue Dec 7 09:19:42 UTC 2021


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 at redhat.com>
---

Notes:
    Version 2:
    - setting unprivileged_userfaultfd only when it is not already enabled
    - virReportSystemError replaced with VIR_WARN

 src/qemu/qemu_migration_params.c | 42 ++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/src/qemu/qemu_migration_params.c b/src/qemu/qemu_migration_params.c
index dbc3219826..9ba4811242 100644
--- a/src/qemu/qemu_migration_params.c
+++ b/src/qemu/qemu_migration_params.c
@@ -804,6 +804,41 @@ qemuMigrationCapsToJSON(virBitmap *caps,
 }
 
 
+/**
+ * qemuMigrationParamsEnableUserfaultfd
+ *
+ * Try to enable unprivileged userfaultfd unless it's missing or already
+ * enabled. Only a warning is logged when we cannot enable it, QEMU will
+ * report an error when enabling post-copy migration capability.
+ */
+static void
+qemuMigrationParamsEnableUserfaultfd(void)
+{
+    const char *sysctl = "/proc/sys/vm/unprivileged_userfaultfd";
+    g_autofree char *buf = NULL;
+
+    if (!virFileExists(sysctl))
+        return;
+
+    if (virFileReadAll(sysctl, 10, &buf) < 0) {
+        VIR_WARN("Cannot read unprivileged userfaultfd state");
+        return;
+    }
+
+    if (STREQ(buf, "1\n")) {
+        VIR_DEBUG("Unprivileged userfaultfd already enabled");
+        return;
+    }
+
+    VIR_DEBUG("Enabling unprivileged userfaultfd for post-copy migration");
+
+    if (virFileWriteStr(sysctl, "1", 0) < 0) {
+        VIR_WARN("Failed to enable unprivileged userfaultfd: %s",
+                 g_strerror(errno));
+    }
+}
+
+
 /**
  * qemuMigrationParamsApply
  * @driver: qemu driver
@@ -839,6 +874,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();
+
         if (!(caps = qemuMigrationCapsToJSON(priv->migrationCaps, migParams->caps)))
             goto cleanup;
 
-- 
2.34.1




More information about the libvir-list mailing list