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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list