From 68faf98ca09314b61314ad2ac0cc133c400a83f9 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 12 Apr 2012 03:38:52 +0200 Subject: execute: when we can't get the requested rlimit, get the next closest --- src/core/execute.c | 2 +- src/shared/util.c | 24 ++++++++++++++++++++++++ src/shared/util.h | 3 +++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/core/execute.c b/src/core/execute.c index 8ae3923c5d..271c57f562 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1367,7 +1367,7 @@ int exec_spawn(ExecCommand *command, if (!context->rlimit[i]) continue; - if (setrlimit(i, context->rlimit[i]) < 0) { + if (setrlimit_closest(i, context->rlimit[i]) < 0) { err = -errno; r = EXIT_LIMITS; goto fail_child; diff --git a/src/shared/util.c b/src/shared/util.c index a3873a9318..0b4d4d6746 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -6120,3 +6120,27 @@ int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *pa execv(path, l); _exit(EXIT_FAILURE); } + +int setrlimit_closest(int resource, const struct rlimit *rlim) { + struct rlimit highest, fixed; + + assert(rlim); + + if (setrlimit(resource, rlim) >= 0) + return 0; + + if (errno != EPERM) + return -errno; + + /* So we failed to set the desired setrlimit, then let's try + * to get as close as we can */ + assert_se(getrlimit(resource, &highest) == 0); + + fixed.rlim_cur = MIN(rlim->rlim_cur, highest.rlim_max); + fixed.rlim_max = MIN(rlim->rlim_max, highest.rlim_max); + + if (setrlimit(resource, &fixed) < 0) + return -errno; + + return 0; +} diff --git a/src/shared/util.h b/src/shared/util.h index 3f4e49e6bc..c487b702bf 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -34,6 +34,7 @@ #include #include #include +#include #include "macro.h" @@ -531,4 +532,6 @@ int fd_inc_rcvbuf(int fd, size_t n); int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...); +int setrlimit_closest(int resource, const struct rlimit *rlim); + #endif -- cgit v1.2.3-54-g00ecf