]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Allow qemuDomainAdjustMaxMemLock() to restore previous value
authorAndrea Bolognani <abologna@redhat.com>
Thu, 10 Dec 2015 18:13:58 +0000 (19:13 +0100)
committerAndrea Bolognani <abologna@redhat.com>
Thu, 17 Dec 2015 09:12:47 +0000 (10:12 +0100)
When the function changes the memory lock limit for the first time,
it will retrieve the current value and store it inside the
virDomainObj for the domain.

When the function is called again, if memory locking is no longer
needed, it will be able to restore the memory locking limit to its
original value.

src/conf/domain_conf.h
src/qemu/qemu_domain.c

index cec681a788be6d85d74dfa7a7054b96e6026de1e..952d3ccbf75b5341e9d74b58caf993541cd18211 100644 (file)
@@ -2420,6 +2420,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 bool (*virDomainObjListACLFilter)(virConnectPtr conn,
index 4b796ab60eadc46f5fd747ede7d7d20db57d833a..1e1e57f7fc66749b9e8fd8703723cbd0f5acb399 100644 (file)
@@ -4125,7 +4125,10 @@ qemuDomainRequiresMlock(virDomainDefPtr def)
  * 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 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
  */
@@ -4135,8 +4138,22 @@ qemuDomainAdjustMaxMemLock(virDomainObjPtr vm)
     unsigned long long bytes = 0;
     int ret = -1;
 
-    if (qemuDomainRequiresMlock(vm->def))
+    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. Failing to obtain the current limit is not a critical
+         * failure, it just means we'll be unable to lower it later */
+        if (!vm->original_memlock) {
+            if (virProcessGetMaxMemLock(vm->pid, &(vm->original_memlock)) < 0)
+                vm->original_memlock = 0;
+        }
         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;
+    }
 
     /* Trying to set the memory locking limit to zero is a no-op */
     if (virProcessSetMaxMemLock(vm->pid, bytes) < 0)