[libvirt] [PATCH 3/6] qemu: Add qemuDomainAdjustMaxMemLock()

Andrea Bolognani abologna at redhat.com
Tue Nov 24 13:56:35 UTC 2015


This function detects whether a domain needs RLIMIT_MEMLOCK
to be set, and if so, uses an appropriate value.

It also stores the original value inside the virDomainObj for
the domain so that it can be later restored.
---
 src/conf/domain_conf.h |  3 +++
 src/qemu/qemu_domain.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |  1 +
 3 files changed, 54 insertions(+)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8d43ee6..9e28ac9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2386,6 +2386,9 @@ struct _virDomainObj {
     void (*privateDataFreeFunc)(void *);
 
     int taint;
+
+    unsigned long long original_memlock; /* Original RLIMIT_MEMLOCK, zero if no
+                                          * restore will be required later */
 };
 
 typedef struct _virDomainObjList virDomainObjList;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 18513f9..51a1770 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -40,6 +40,7 @@
 #include "virstoragefile.h"
 #include "virstring.h"
 #include "virthreadjob.h"
+#include "virprocess.h"
 
 #include "storage/storage_driver.h"
 
@@ -3954,3 +3955,52 @@ qemuDomainRequiresMlock(virDomainDefPtr def)
 
     return false;
 }
+
+/**
+ * qemuDomainAdjustMaxMemLock:
+ *
+ * @vm: domain
+ *
+ * Adjust the memory locking limit for the QEMU process associated to @vm, in
+ * order to comply with VFIO or architecture requirements.
+ *
+ * The limit will not be changed unless doing so is needed; the first time
+ * the limit is changed, the original (default) limit is stored in @vm and
+ * that value will be restored if qemuDomainAdjustMaxMemLock() is called once
+ * memory locking is no longer required.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+int
+qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
+{
+    unsigned long long bytes = 0;
+    int ret = -1;
+
+    if (qemuDomainRequiresMlock(vm->def)) {
+        /* If this is the first time adjusting the limit, save the current
+         * value so that we can restore it once memory locking is no longer
+         * required */
+        if (!vm->original_memlock) {
+            if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0)
+                goto out;
+        }
+        bytes = qemuDomainGetMlockLimitBytes(vm->def);
+    } else {
+        /* Once memory locking is no longer required, we can restore the
+         * original, usually very low, limit */
+        bytes = vm->original_memlock;
+        vm->original_memlock = 0;
+    }
+
+    /* Don't do anything unless we're actually setting a limit */
+    if (bytes) {
+        if (virProcessSetMaxMemLock(vm->pid, bytes) < 0)
+            goto out;
+    }
+
+    ret = 0;
+
+ out:
+     return ret;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 271dce9..cc64df3 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -486,6 +486,7 @@ int qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
 
 unsigned long long qemuDomainGetMlockLimitBytes(virDomainDefPtr def);
 bool qemuDomainRequiresMlock(virDomainDefPtr def);
+int qemuDomainAdjustMaxMemLock(virDomainObjPtr vm);
 
 int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def,
                                        virQEMUCapsPtr qemuCaps,
-- 
2.5.0




More information about the libvir-list mailing list