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 | 3 +++
src/qemu/qemu_domain.c | 21 +++++++++++++++++++--
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cec681a..952d3cc 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -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,
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4b796ab..1e1e57f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -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)
--
2.5.0