Skip to content

Instantly share code, notes, and snippets.

@yshui
Created April 30, 2014 22:11
Show Gist options
  • Save yshui/f12d873a7a5ffc0b62c5 to your computer and use it in GitHub Desktop.
Save yshui/f12d873a7a5ffc0b62c5 to your computer and use it in GitHub Desktop.
systemd --user
From cae2e1a925c52449fd13c2dce7dacbf9d7b9725a Mon Sep 17 00:00:00 2001
From: Yuxuan Shui <yshuiv7@gmail.com>
Date: Sun, 30 Mar 2014 03:58:12 +0800
Subject: [PATCH 1/2] core: Add a User= to scopes.
Conflicts:
src/core/scope.c
---
src/core/dbus-scope.c | 13 +++++++++++++
src/core/load-fragment-gperf.gperf.m4 | 1 +
src/core/scope.c | 26 ++++++++++++++++++++++++++
src/core/scope.h | 2 ++
4 files changed, 42 insertions(+)
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
index b9e3be4..7e7bd09 100644
--- a/src/core/dbus-scope.c
+++ b/src/core/dbus-scope.c
@@ -146,6 +146,19 @@ static int bus_scope_set_transient_property(
}
return 1;
+
+ } else if (streq(name, "User")) {
+ const char *d;
+ r = sd_bus_message_read(message, "s", &d);
+ if (r < 0)
+ return r;
+ if (mode != UNIT_CHECK) {
+ s->user = strdup(d);
+
+ unit_write_drop_in_format(UNIT(s), mode, name, "[Scope]\nUser=%s\n", s->user);
+ }
+
+ return 1;
}
return 0;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 21bccbb..3034d87 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -305,6 +305,7 @@ m4_dnl
CGROUP_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl
KILL_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl
Scope.TimeoutStopSec, config_parse_sec, 0, offsetof(Scope, timeout_stop_usec)
+Scope.User, config_parse_unit_string_printf, 0, offsetof(Scope, user)
m4_dnl The [Install] section is ignored here.
Install.Alias, NULL, 0, 0
Install.WantedBy, NULL, 0, 0
diff --git a/src/core/scope.c b/src/core/scope.c
index e8f9e8d..941e11c 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -51,6 +51,7 @@ static void scope_init(Unit *u) {
s->timeout_stop_usec = u->manager->default_timeout_stop_usec;
+ s->user = NULL;
UNIT(s)->ignore_on_isolate = true;
UNIT(s)->ignore_on_snapshot = true;
}
@@ -62,6 +63,9 @@ static void scope_done(Unit *u) {
free(s->controller);
+ free(s->user);
+ s->user = NULL;
+
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
}
@@ -298,6 +302,28 @@ static int scope_start(Unit *u) {
if (r < 0)
return r;
+ if(s->user){
+ uid_t uid;
+ gid_t gid;
+ const char *username = s->user;
+
+ r = get_user_creds(&username, &uid, &gid, NULL, NULL);
+ if (r < 0)
+ return r;
+
+ r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0644, uid, gid);
+ if (r < 0) {
+ log_error("Failed to set cgroup permission: %s", strerror(-r));
+ return r;
+ }
+
+ r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, 0755, uid, gid);
+ if (r < 0) {
+ log_error("Failed to set cgroup permission: %s", strerror(-r));
+ return r;
+ }
+ }
+
s->result = SCOPE_SUCCESS;
scope_set_state(s, SCOPE_RUNNING);
diff --git a/src/core/scope.h b/src/core/scope.h
index 6c59126..809e69c 100644
--- a/src/core/scope.h
+++ b/src/core/scope.h
@@ -51,6 +51,8 @@ struct Scope {
CGroupContext cgroup_context;
KillContext kill_context;
+ char *user;
+
ScopeState state, deserialized_state;
ScopeResult result;
--
1.9.2
From c6b2f26e9abaca7f66cce5c96cfdb2237ee28d65 Mon Sep 17 00:00:00 2001
From: Yuxuan Shui <yshuiv7@gmail.com>
Date: Sun, 30 Mar 2014 04:00:54 +0800
Subject: [PATCH 2/3] logind: make the user owner of the session scope.
Conflicts:
src/login/logind-session.c
---
src/login/logind-dbus.c | 11 ++++++++++-
src/login/logind-session.c | 2 +-
src/login/logind.h | 2 +-
3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 0af6714..6e5fbfd 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2242,7 +2242,7 @@ int manager_start_scope(
Manager *manager,
const char *scope,
pid_t pid,
- const char *slice,
+ User *user,
const char *description,
const char *after, const char *after2,
sd_bus_error *error,
@@ -2250,6 +2250,9 @@ int manager_start_scope(
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
int r;
+ char *uid;
+
+ const char *slice = user->slice;
assert(manager);
assert(scope);
@@ -2302,6 +2305,12 @@ int manager_start_scope(
* stop timeout for sessions, so that we don't wait
* forever. */
+ asprintf(&uid, "%lu", (long unsigned int) user->uid);
+ r = sd_bus_message_append(m, "(sv)", "User", "s", uid);
+ if (r < 0)
+ return r;
+ free(uid);
+
/* Make sure that the session shells are terminated with
* SIGHUP since bash and friends tend to ignore SIGTERM */
r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", true);
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 8e6f95e..85f7fca 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -489,7 +489,7 @@ static int session_start_scope(Session *s) {
if (!scope)
return log_oom();
- r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job);
+ r = manager_start_scope(s->manager, scope, s->leader, s->user, description, "systemd-logind.service", "systemd-user-sessions.service", &error, &job);
if (r < 0) {
log_error("Failed to start session scope %s: %s %s",
scope, bus_error_message(&error, r), error.name);
diff --git a/src/login/logind.h b/src/login/logind.h
index 31353ef..43320cc 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -174,7 +174,7 @@ int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_
int manager_dispatch_delayed(Manager *manager);
-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);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, User *user, const char *description, const char *after, const char *after2, sd_bus_error *error, char **job);
int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error);
--
1.9.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment