[PATCH 2/2] allow system wide limits for services
Frederic Crozat
fcrozat at suse.com
Wed Mar 21 10:03:40 PDT 2012
---
src/core/main.c | 28 ++++++++++++++++++++++++++++
src/core/manager.c | 7 +++++++
src/core/manager.h | 2 ++
src/core/service.c | 8 ++++++++
4 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/src/core/main.c b/src/core/main.c
index 8c25819..5e37b47 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -85,6 +85,7 @@ static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
static usec_t arg_runtime_watchdog = 0;
static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
+static struct rlimit *default_rlimit[RLIMIT_NLIMITS] = {};
static FILE* serialization = NULL;
@@ -665,6 +666,22 @@ static int parse_config_file(void) {
{ "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
{ "Manager", "RuntimeWatchdogSec", config_parse_usec, 0, &arg_runtime_watchdog },
{ "Manager", "ShutdownWatchdogSec", config_parse_usec, 0, &arg_shutdown_watchdog },
+ { "Manager", "LimitCPU", config_parse_limit, 0, &default_rlimit[RLIMIT_CPU]},
+ { "Manager", "LimitFSIZE", config_parse_limit, 0, &default_rlimit[RLIMIT_FSIZE]},
+ { "Manager", "LimitDATA", config_parse_limit, 0, &default_rlimit[RLIMIT_DATA]},
+ { "Manager", "LimitSTACK", config_parse_limit, 0, &default_rlimit[RLIMIT_STACK]},
+ { "Manager", "LimitCORE", config_parse_limit, 0, &default_rlimit[RLIMIT_CORE]},
+ { "Manager", "LimitRSS", config_parse_limit, 0, &default_rlimit[RLIMIT_RSS]},
+ { "Manager", "LimitNOFILE", config_parse_limit, 0, &default_rlimit[RLIMIT_NOFILE]},
+ { "Manager", "LimitAS", config_parse_limit, 0, &default_rlimit[RLIMIT_AS]},
+ { "Manager", "LimitNPROC", config_parse_limit, 0, &default_rlimit[RLIMIT_NPROC]},
+ { "Manager", "LimitMEMLOCK", config_parse_limit, 0, &default_rlimit[RLIMIT_MEMLOCK]},
+ { "Manager", "LimitLOCKS", config_parse_limit, 0, &default_rlimit[RLIMIT_LOCKS]},
+ { "Manager", "LimitSIGPENDING", config_parse_limit, 0, &default_rlimit[RLIMIT_SIGPENDING]},
+ { "Manager", "LimitMSGQUEUE", config_parse_limit, 0, &default_rlimit[RLIMIT_MSGQUEUE]},
+ { "Manager", "LimitNICE", config_parse_limit, 0, &default_rlimit[RLIMIT_NICE]},
+ { "Manager", "LimitRTPRIO", config_parse_limit, 0, &default_rlimit[RLIMIT_RTPRIO]},
+ { "Manager", "LimitRTTIME", config_parse_limit, 0, &default_rlimit[RLIMIT_RTTIME]},
{ NULL, NULL, NULL, 0, NULL }
};
@@ -1471,6 +1488,14 @@ int main(int argc, char *argv[]) {
m->default_std_error = arg_default_std_error;
m->runtime_watchdog = arg_runtime_watchdog;
m->shutdown_watchdog = arg_shutdown_watchdog;
+ for (j = 0; j < RLIMIT_NLIMITS; j++) {
+ if (default_rlimit[j]) {
+ m->rlimit[j] = newdup(struct rlimit, default_rlimit[j], 1);
+
+ if (!m->rlimit[j])
+ goto finish;
+ }
+ }
if (dual_timestamp_is_set(&initrd_timestamp))
m->initrd_timestamp = initrd_timestamp;
@@ -1631,6 +1656,9 @@ finish:
if (m)
manager_free(m);
+ for (j = 0; j < RLIMIT_NLIMITS; j++)
+ free (default_rlimit[j]);
+
free(arg_default_unit);
strv_free(arg_default_controllers);
free_join_controllers();
diff --git a/src/core/manager.c b/src/core/manager.c
index f8fb8a2..65b34f3 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -476,6 +476,7 @@ static void manager_clear_jobs_and_units(Manager *m) {
void manager_free(Manager *m) {
UnitType c;
+ int i;
assert(m);
@@ -524,6 +525,12 @@ void manager_free(Manager *m) {
free(m->switch_root);
free(m->switch_root_init);
+ for (i = 0; i < RLIMIT_NLIMITS; i++) {
+ if (m->rlimit[i]) {
+ free (m->rlimit[i]);
+ m->rlimit[i] = NULL;
+ }
+ }
free(m);
}
diff --git a/src/core/manager.h b/src/core/manager.h
index 046540d..6aefc8b 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -226,6 +226,8 @@ struct Manager {
ExecOutput default_std_output, default_std_error;
+ struct rlimit *rlimit[RLIMIT_NLIMITS];
+
/* non-zero if we are reloading or reexecuting, */
int n_reloading;
diff --git a/src/core/service.c b/src/core/service.c
index 28049a3..fa3a54b 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -110,6 +110,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
static void service_init(Unit *u) {
Service *s = SERVICE(u);
+ int i;
assert(u);
assert(u->load_state == UNIT_STUB);
@@ -129,6 +130,13 @@ static void service_init(Unit *u) {
s->guess_main_pid = true;
exec_context_init(&s->exec_context);
+ for (i = 0; i < RLIMIT_NLIMITS; i++) {
+ if (UNIT(s)->manager->rlimit[i]) {
+ s->exec_context.rlimit[i] = newdup(struct rlimit, UNIT(s)->manager->rlimit[i], 1);
+ if (!s->exec_context.rlimit[i])
+ return;
+ }
+ }
RATELIMIT_INIT(s->start_limit, 10*USEC_PER_SEC, 5);
--
1.7.7
--=-u2Y66SLysGDaWSR/g7cg--
More information about the systemd-devel
mailing list