From bbefc9cc2e4111d183e0e68bc21c07094901158f Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Fri, 20 Nov 2015 17:06:41 +0100 Subject: [PATCH] process: Add virProcessGetMaxMemLock() This function can be used to retrieve the current locked memory limit for a process, so that the setting can be later restored. Add a configure check for getrlimit(), which we now use. --- configure.ac | 2 +- src/libvirt_private.syms | 1 + src/util/virprocess.c | 45 ++++++++++++++++++++++++++++++++++++++++ src/util/virprocess.h | 2 ++ 4 files changed, 49 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 67c10ddaed..928fcb4cb2 100644 --- a/configure.ac +++ b/configure.ac @@ -283,7 +283,7 @@ AC_CHECK_SIZEOF([long]) dnl Availability of various common functions (non-fatal if missing), dnl and various less common threadsafe functions AC_CHECK_FUNCS_ONCE([cfmakeraw fallocate geteuid getgid getgrnam_r \ - getmntent_r getpwuid_r getuid kill mmap newlocale posix_fallocate \ + getmntent_r getpwuid_r getrlimit getuid kill mmap newlocale posix_fallocate \ posix_memalign prlimit regexec sched_getaffinity setgroups setns \ setrlimit symlink sysctlbyname getifaddrs sched_setscheduler]) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 55822aef99..0b5ddc16b5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2040,6 +2040,7 @@ virPortAllocatorSetUsed; virProcessAbort; virProcessExitWithStatus; virProcessGetAffinity; +virProcessGetMaxMemLock; virProcessGetNamespaces; virProcessGetPids; virProcessGetStartTime; diff --git a/src/util/virprocess.c b/src/util/virprocess.c index 9b388342d8..277b3bc34e 100644 --- a/src/util/virprocess.c +++ b/src/util/virprocess.c @@ -788,6 +788,51 @@ virProcessSetMaxMemLock(pid_t pid ATTRIBUTE_UNUSED, unsigned long long bytes) } #endif /* ! (HAVE_SETRLIMIT && defined(RLIMIT_MEMLOCK)) */ +#if HAVE_GETRLIMIT && defined(RLIMIT_MEMLOCK) +int +virProcessGetMaxMemLock(pid_t pid, + unsigned long long *bytes) +{ + struct rlimit rlim; + + if (!bytes) + return 0; + + if (pid == 0) { + if (getrlimit(RLIMIT_MEMLOCK, &rlim) < 0) { + virReportSystemError(errno, + "%s", + _("cannot get locked memory limit")); + return -1; + } + } else { + if (virProcessPrLimit(pid, RLIMIT_MEMLOCK, NULL, &rlim) < 0) { + virReportSystemError(errno, + _("cannot get locked memory limit " + "of process %lld"), + (long long int) pid); + return -1; + } + } + + /* virProcessSetMaxMemLock() sets both rlim_cur and rlim_max to the + * same value, so we can retrieve just rlim_max here */ + *bytes = rlim.rlim_max; + + return 0; +} +#else /* ! (HAVE_GETRLIMIT && defined(RLIMIT_MEMLOCK)) */ +int +virProcessGetMaxMemLock(pid_t pid ATTRIBUTE_UNUSED, + unsigned long long *bytes) +{ + if (!bytes) + return 0; + + virReportSystemError(ENOSYS, "%s", _("Not supported on this platform")); + return -1; +} +#endif /* ! (HAVE_GETRLIMIT && defined(RLIMIT_MEMLOCK)) */ #if HAVE_SETRLIMIT && defined(RLIMIT_NPROC) int diff --git a/src/util/virprocess.h b/src/util/virprocess.h index 1768009d37..a7a1fe9200 100644 --- a/src/util/virprocess.h +++ b/src/util/virprocess.h @@ -76,6 +76,8 @@ int virProcessSetMaxMemLock(pid_t pid, unsigned long long bytes); int virProcessSetMaxProcesses(pid_t pid, unsigned int procs); int virProcessSetMaxFiles(pid_t pid, unsigned int files); +int virProcessGetMaxMemLock(pid_t pid, unsigned long long *bytes); + /* Callback to run code within the mount namespace tied to the given * pid. This function must use only async-signal-safe functions, as * it gets run after a fork of a multi-threaded process. The return -- GitLab