richardphibel / rpms / systemd

Forked from rpms/systemd 2 years ago
Clone
923a60
From ff5349960f1cf7af5404b0f765c57eb386c91216 Mon Sep 17 00:00:00 2001
923a60
From: Lennart Poettering <lennart@poettering.net>
923a60
Date: Fri, 13 Nov 2015 18:25:02 +0100
923a60
Subject: [PATCH] logind: add a new UserTasksMax= setting to logind.conf
923a60
923a60
This new setting configures the TasksMax= field for the slice objects we
923a60
create for each user.
923a60
923a60
This alters logind to create the slice unit as transient unit explicitly
923a60
instead of relying on implicit generation of slice units by simply
923a60
starting them. This also enables us to set a friendly description for
923a60
slice units that way.
923a60
923a60
Cherry-picked from: 90558f315844ec35e3fd4f1a19ac38c8721c9354
923a60
Conflicts:
923a60
	src/login/logind-dbus.c
923a60
	src/login/logind-user.c
923a60
	src/login/logind.conf
923a60
	src/login/logind.h
923a60
923a60
Resolves: #1337244
923a60
---
923a60
 man/logind.conf.xml          | 15 +++++-
923a60
 src/login/logind-dbus.c      | 94 +++++++++++++++++++++++++++++++++++-
923a60
 src/login/logind-gperf.gperf |  1 +
923a60
 src/login/logind-session.c   | 25 ++++++----
923a60
 src/login/logind-session.h   |  3 +-
923a60
 src/login/logind-user.c      | 41 +++++++++++-----
923a60
 src/login/logind.c           |  1 +
923a60
 src/login/logind.conf        |  1 +
923a60
 src/login/logind.h           |  4 +-
923a60
 9 files changed, 160 insertions(+), 25 deletions(-)
923a60
923a60
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
923a60
index 54651f07d2..bcc8ee9753 100644
923a60
--- a/man/logind.conf.xml
923a60
+++ b/man/logind.conf.xml
923a60
@@ -1,4 +1,4 @@
923a60
- 
923a60
+ 
923a60
 
923a60
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
923a60
 
923a60
@@ -262,7 +262,18 @@
923a60
         limit relative to the amount of physical RAM. Defaults to 10%.
923a60
         Note that this size is a safety limit only. As each runtime
923a60
         directory is a tmpfs file system, it will only consume as much
923a60
-        memory as is needed. </para></listitem>
923a60
+        memory as is needed.</para></listitem>
923a60
+      </varlistentry>
923a60
+
923a60
+      <varlistentry>
923a60
+        <term><varname>UserTasksMax=</varname></term>
923a60
+
923a60
+        <listitem><para>Sets the maximum number of OS tasks each user
923a60
+        may run concurrently. This controls the
923a60
+        <varname>TasksMax=</varname> setting of the per-user slice
923a60
+        unit, see
923a60
+        <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
923a60
+        for details.</para></listitem>
923a60
       </varlistentry>
923a60
 
923a60
       <varlistentry>
923a60
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
923a60
index fb84e92e5d..63b9a0df36 100644
923a60
--- a/src/login/logind-dbus.c
923a60
+++ b/src/login/logind-dbus.c
923a60
@@ -2325,13 +2325,101 @@ int manager_dispatch_delayed(Manager *manager) {
923a60
         return 1;
923a60
 }
923a60
 
923a60
+int manager_start_slice(
923a60
+                Manager *manager,
923a60
+                const char *slice,
923a60
+                const char *description,
923a60
+                const char *after,
923a60
+                const char *after2,
923a60
+                uint64_t tasks_max,
923a60
+                sd_bus_error *error,
923a60
+                char **job) {
923a60
+
923a60
+        _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
923a60
+        int r;
923a60
+
923a60
+        assert(manager);
923a60
+        assert(slice);
923a60
+
923a60
+        r = sd_bus_message_new_method_call(
923a60
+                        manager->bus,
923a60
+                        &m,
923a60
+                        "org.freedesktop.systemd1",
923a60
+                        "/org/freedesktop/systemd1",
923a60
+                        "org.freedesktop.systemd1.Manager",
923a60
+                        "StartTransientUnit");
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_bus_message_append(m, "ss", strempty(slice), "fail");
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_bus_message_open_container(m, 'a', "(sv)");
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        if (!isempty(description)) {
923a60
+                r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
923a60
+                if (r < 0)
923a60
+                        return r;
923a60
+        }
923a60
+
923a60
+        if (!isempty(after)) {
923a60
+                r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after);
923a60
+                if (r < 0)
923a60
+                        return r;
923a60
+        }
923a60
+
923a60
+        if (!isempty(after2)) {
923a60
+                r = sd_bus_message_append(m, "(sv)", "After", "as", 1, after2);
923a60
+                if (r < 0)
923a60
+                        return r;
923a60
+        }
923a60
+
923a60
+        r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_bus_message_close_container(m);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_bus_message_append(m, "a(sa(sv))", 0);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        r = sd_bus_call(manager->bus, m, 0, error, &reply);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
+        if (job) {
923a60
+                const char *j;
923a60
+                char *copy;
923a60
+
923a60
+                r = sd_bus_message_read(reply, "o", &j);
923a60
+                if (r < 0)
923a60
+                        return r;
923a60
+
923a60
+                copy = strdup(j);
923a60
+                if (!copy)
923a60
+                        return -ENOMEM;
923a60
+
923a60
+                *job = copy;
923a60
+        }
923a60
+
923a60
+        return 1;
923a60
+}
923a60
+
923a60
 int manager_start_scope(
923a60
                 Manager *manager,
923a60
                 const char *scope,
923a60
                 pid_t pid,
923a60
                 const char *slice,
923a60
                 const char *description,
923a60
-                const char *after, const char *after2,
923a60
+                const char *after,
923a60
+                const char *after2,
923a60
+                uint64_t tasks_max,
923a60
                 sd_bus_error *error,
923a60
                 char **job) {
923a60
 
923a60
@@ -2399,6 +2487,10 @@ int manager_start_scope(
923a60
         if (r < 0)
923a60
                 return r;
923a60
 
923a60
+        r = sd_bus_message_append(m, "(sv)", "TasksMax", "t", tasks_max);
923a60
+        if (r < 0)
923a60
+                return r;
923a60
+
923a60
         r = sd_bus_message_close_container(m);
923a60
         if (r < 0)
923a60
                 return r;
923a60
diff --git a/src/login/logind-gperf.gperf b/src/login/logind-gperf.gperf
923a60
index 62460673b9..8a064e2a96 100644
923a60
--- a/src/login/logind-gperf.gperf
923a60
+++ b/src/login/logind-gperf.gperf
923a60
@@ -33,3 +33,4 @@ Login.IdleAction,                  config_parse_handle_action, 0, offsetof(Manag
923a60
 Login.IdleActionSec,               config_parse_sec,           0, offsetof(Manager, idle_action_usec)
923a60
 Login.RuntimeDirectorySize,        config_parse_tmpfs_size,    0, offsetof(Manager, runtime_dir_size)
923a60
 Login.RemoveIPC,                   config_parse_bool,          0, offsetof(Manager, remove_ipc)
923a60
+Login.UserTasksMax,                config_parse_uint64,        0, offsetof(Manager, user_tasks_max)
923a60
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
923a60
index 746e50aa51..4575a029fe 100644
923a60
--- a/src/login/logind-session.c
923a60
+++ b/src/login/logind-session.c
923a60
@@ -510,21 +510,28 @@ static int session_start_scope(Session *s) {
923a60
 
923a60
         if (!s->scope) {
923a60
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
923a60
-                _cleanup_free_ char *description = NULL;
923a60
                 char *scope, *job = NULL;
923a60
-
923a60
-                description = strjoin("Session ", s->id, " of user ", s->user->name, NULL);
923a60
-                if (!description)
923a60
-                        return log_oom();
923a60
+                const char *description;
923a60
 
923a60
                 scope = strjoin("session-", s->id, ".scope", NULL);
923a60
                 if (!scope)
923a60
                         return log_oom();
923a60
 
923a60
-                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job;;
923a60
+                description = strjoina("Session ", s->id, " of user ", s->user->name, NULL);
923a60
+
923a60
+                r = manager_start_scope(
923a60
+                                s->manager,
923a60
+                                scope,
923a60
+                                s->leader,
923a60
+                                s->user->slice,
923a60
+                                description,
923a60
+                                "systemd-logind.service",
923a60
+                                "systemd-user-sessions.service",
923a60
+                                (uint64_t) -1, /* disable TasksMax= for the scope, rely on the slice setting for it */
923a60
+                                &error,
923a60
+                                &job;;
923a60
                 if (r < 0) {
923a60
-                        log_error("Failed to start session scope %s: %s %s",
923a60
-                                  scope, bus_error_message(&error, r), error.name);
923a60
+                        log_error_errno(r, "Failed to start session scope %s: %s", scope, bus_error_message(&error, r));
923a60
                         free(scope);
923a60
                         return r;
923a60
                 } else {
923a60
@@ -536,7 +543,7 @@ static int session_start_scope(Session *s) {
923a60
         }
923a60
 
923a60
         if (s->scope)
923a60
-                hashmap_put(s->manager->session_units, s->scope, s);
923a60
+                (void) hashmap_put(s->manager->session_units, s->scope, s);
923a60
 
923a60
         return 0;
923a60
 }
923a60
diff --git a/src/login/logind-session.h b/src/login/logind-session.h
923a60
index 5002b68689..d662082d85 100644
923a60
--- a/src/login/logind-session.h
923a60
+++ b/src/login/logind-session.h
923a60
@@ -115,7 +115,8 @@ struct Session {
923a60
 
923a60
         bool in_gc_queue:1;
923a60
         bool started:1;
923a60
-        bool stopping:1;
923a60
+
923a60
+        bool stopping;
923a60
 
923a60
         sd_bus_message *create_message;
923a60
 
923a60
diff --git a/src/login/logind-user.c b/src/login/logind-user.c
923a60
index 97eb4feca9..4298704cea 100644
923a60
--- a/src/login/logind-user.c
923a60
+++ b/src/login/logind-user.c
923a60
@@ -33,6 +33,7 @@
923a60
 #include "special.h"
923a60
 #include "unit-name.h"
923a60
 #include "bus-util.h"
923a60
+#include "bus-common-errors.h"
923a60
 #include "bus-error.h"
923a60
 #include "conf-parser.h"
923a60
 #include "clean-ipc.h"
923a60
@@ -367,34 +368,52 @@ fail:
923a60
 }
923a60
 
923a60
 static int user_start_slice(User *u) {
923a60
-        char *job;
923a60
         int r;
923a60
 
923a60
         assert(u);
923a60
 
923a60
         if (!u->slice) {
923a60
                 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
923a60
-                char lu[DECIMAL_STR_MAX(uid_t) + 1], *slice;
923a60
-                sprintf(lu, UID_FMT, u->uid);
923a60
+                char lu[DECIMAL_STR_MAX(uid_t) + 1], *slice, *job;
923a60
+                const char *description;
923a60
+
923a60
+                free(u->slice_job);
923a60
+                u->slice_job = NULL;
923a60
 
923a60
+                xsprintf(lu, UID_FMT, u->uid);
923a60
                 r = build_subslice(SPECIAL_USER_SLICE, lu, &slice);
923a60
                 if (r < 0)
923a60
-                        return r;
923a60
-
923a60
-                r = manager_start_unit(u->manager, slice, &error, &job;;
923a60
+                        return log_error_errno(r, "Failed to build slice name: %m");
923a60
+
923a60
+                description = strjoina("User Slice of ", u->name);
923a60
+
923a60
+                r = manager_start_slice(
923a60
+                                u->manager,
923a60
+                                slice,
923a60
+                                description,
923a60
+                                "systemd-logind.service",
923a60
+                                "systemd-user-sessions.service",
923a60
+                                u->manager->user_tasks_max,
923a60
+                                &error,
923a60
+                                &job;;
923a60
                 if (r < 0) {
923a60
-                        log_error("Failed to start user slice: %s", bus_error_message(&error, r));
923a60
-                        free(slice);
923a60
+
923a60
+                        if (sd_bus_error_has_name(&error, BUS_ERROR_UNIT_EXISTS))
923a60
+                                /* The slice already exists? If so, that's fine, let's just reuse it */
923a60
+                                u->slice = slice;
923a60
+                        else {
923a60
+                                log_error_errno(r, "Failed to start user slice %s, ignoring: %s (%s)", slice, bus_error_message(&error, r), error.name);
923a60
+                                free(slice);
923a60
+                                /* we don't fail due to this, let's try to continue */
923a60
+                        }
923a60
                 } else {
923a60
                         u->slice = slice;
923a60
-
923a60
-                        free(u->slice_job);
923a60
                         u->slice_job = job;
923a60
                 }
923a60
         }
923a60
 
923a60
         if (u->slice)
923a60
-                hashmap_put(u->manager->user_units, u->slice, u);
923a60
+                (void) hashmap_put(u->manager->user_units, u->slice, u);
923a60
 
923a60
         return 0;
923a60
 }
923a60
diff --git a/src/login/logind.c b/src/login/logind.c
923a60
index e8d0669bbf..16c931c3e0 100644
923a60
--- a/src/login/logind.c
923a60
+++ b/src/login/logind.c
923a60
@@ -63,6 +63,7 @@ Manager *manager_new(void) {
923a60
         m->idle_action_not_before_usec = now(CLOCK_MONOTONIC);
923a60
 
923a60
         m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */
923a60
+        m->user_tasks_max = (uint64_t) -1;
923a60
 
923a60
         m->devices = hashmap_new(&string_hash_ops);
923a60
         m->seats = hashmap_new(&string_hash_ops);
923a60
diff --git a/src/login/logind.conf b/src/login/logind.conf
923a60
index be8d7dff29..d33e0b34d2 100644
923a60
--- a/src/login/logind.conf
923a60
+++ b/src/login/logind.conf
923a60
@@ -31,3 +31,4 @@
923a60
 #IdleActionSec=30min
923a60
 #RuntimeDirectorySize=10%
923a60
 #RemoveIPC=no
923a60
+#UserTasksMax=
923a60
diff --git a/src/login/logind.h b/src/login/logind.h
923a60
index e0cb7d0238..8503eb24dd 100644
923a60
--- a/src/login/logind.h
923a60
+++ b/src/login/logind.h
923a60
@@ -128,6 +128,7 @@ struct Manager {
923a60
         sd_event_source *lid_switch_ignore_event_source;
923a60
 
923a60
         size_t runtime_dir_size;
923a60
+        uint64_t user_tasks_max;
923a60
 };
923a60
 
923a60
 Manager *manager_new(void);
923a60
@@ -176,7 +177,8 @@ int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_
923a60
 
923a60
 int manager_dispatch_delayed(Manager *manager);
923a60
 
923a60
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *after2, sd_bus_error *error, char **job);
923a60
+int manager_start_slice(Manager *manager, const char *slice, const char *description, const char *after, const char *after2, uint64_t tasks_max, sd_bus_error *error, char **job);
923a60
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, const char *after2, uint64_t tasks_max, sd_bus_error *error, char **job);
923a60
 int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
923a60
 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
923a60
 int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);