|
|
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);
|