[systemd-commits] 7 commits - Makefile.am man/systemd.exec.xml src/cgroup.c src/cgroup.h src/dbus-execute.h src/execute.c src/execute.h src/load-fragment.c src/logind-session.c src/manager.c src/pam-module.c src/unit.c units/.gitignore units/user at .service.in

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jun 29 17:41:12 PDT 2011


 Makefile.am            |    7 +++++--
 man/systemd.exec.xml   |   12 ++++++++++++
 src/cgroup.c           |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/cgroup.h           |    6 ++++++
 src/dbus-execute.h     |    6 ++++--
 src/execute.c          |   31 ++++++++++++++++++++-----------
 src/execute.h          |    2 ++
 src/load-fragment.c    |   20 +++++++++++++++++---
 src/logind-session.c   |    4 ++++
 src/manager.c          |    5 +++++
 src/pam-module.c       |    8 +++++++-
 src/unit.c             |   17 +++++++++++++----
 units/.gitignore       |    1 +
 units/user at .service.in |   18 ++++++++++++++++++
 14 files changed, 158 insertions(+), 23 deletions(-)

New commits:
commit e025b4c306d4b0895786839ebbb934188edc6e61
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:41:01 2011 +0200

    unit: consider all cgroups in the name=systemd hierarchy, even when the user has specified an explicit path in it

diff --git a/src/unit.c b/src/unit.c
index 87b7edf..e3687d4 100644
--- a/src/unit.c
+++ b/src/unit.c
@@ -1741,10 +1741,13 @@ int unit_add_cgroup(Unit *u, CGroupBonding *b) {
 
         assert(b->path);
 
-        if (!b->controller)
+        if (!b->controller) {
                 if (!(b->controller = strdup(SYSTEMD_CGROUP_CONTROLLER)))
                         return -ENOMEM;
 
+                b->ours = true;
+        }
+
         /* Ensure this hasn't been added yet */
         assert(!b->unit);
 
@@ -1789,6 +1792,7 @@ static char *default_cgroup_path(Unit *u) {
 int unit_add_cgroup_from_text(Unit *u, const char *name) {
         char *controller = NULL, *path = NULL;
         CGroupBonding *b = NULL;
+        bool ours = false;
         int r;
 
         assert(u);
@@ -1797,11 +1801,15 @@ int unit_add_cgroup_from_text(Unit *u, const char *name) {
         if ((r = cg_split_spec(name, &controller, &path)) < 0)
                 return r;
 
-        if (!path)
+        if (!path) {
                 path = default_cgroup_path(u);
+                ours = true;
+        }
 
-        if (!controller)
+        if (!controller) {
                 controller = strdup(SYSTEMD_CGROUP_CONTROLLER);
+                ours = true;
+        }
 
         if (!path || !controller) {
                 free(path);
@@ -1822,7 +1830,8 @@ int unit_add_cgroup_from_text(Unit *u, const char *name) {
 
         b->controller = controller;
         b->path = path;
-        b->ours = false;
+        b->ours = ours;
+        b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
 
         if ((r = unit_add_cgroup(u, b)) < 0)
                 goto fail;

commit f284f69a7b0ed1eb4aa812251902e055b0e530b1
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:39:29 2011 +0200

    execute: when parsing ConrolGroup= replace wildcards

diff --git a/src/load-fragment.c b/src/load-fragment.c
index 0c2ef91..3146186 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1071,10 +1071,23 @@ static int config_parse_cgroup(
         char *state;
 
         FOREACH_WORD_QUOTED(w, l, rvalue, state) {
-                char *t;
+                char *t, *k;
                 int r;
 
-                if (!(t = cunescape_length(w, l)))
+                t = strndup(w, l);
+                if (!t)
+                        return -ENOMEM;
+
+                k = unit_full_printf(u, t);
+                free(t);
+
+                if (!k)
+                        return -ENOMEM;
+
+                t = cunescape(k);
+                free(k);
+
+                if (!t)
                         return -ENOMEM;
 
                 r = unit_add_cgroup_from_text(u, t);

commit d42d27ead91e470cb12986d928441e56c0f543ca
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:18:01 2011 +0200

    logind: add service for per-user shared systemd daemon

diff --git a/Makefile.am b/Makefile.am
index 2a027c3..9a67505 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -353,7 +353,8 @@ nodist_systemunit_DATA = \
 	units/fsck at .service \
 	units/fsck-root.service \
 	units/quotacheck.service \
-	units/rescue.service
+	units/rescue.service \
+        units/user at .service
 
 if ENABLE_BINFMT
 nodist_systemunit_DATA += \
@@ -404,6 +405,7 @@ EXTRA_DIST = \
 	units/fsck at .service.in \
 	units/fsck-root.service.in \
 	units/quotacheck.service.in \
+        units/user at .service.in \
 	systemd.pc.in \
 	introspect.awk \
 	src/org.freedesktop.systemd1.policy.in \
diff --git a/src/pam-module.c b/src/pam-module.c
index a15b4ca..178c469 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -361,6 +361,13 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         if (sd_booted() <= 0)
                 return PAM_SUCCESS;
 
+        /* Make sure we don't enter a loop by talking to
+         * systemd-logind when it is actually waiting for the
+         * background to finish start-up, */
+        pam_get_item(handle, PAM_SERVICE, (const void**) &service);
+        if (streq_ptr(service, "systemd-shared"))
+                return PAM_SUCCESS;
+
         if (parse_argv(handle,
                        argc, argv,
                        &controllers, &reset_controllers,
@@ -401,7 +408,6 @@ _public_ PAM_EXTERN int pam_sm_open_session(
         uid = pw->pw_uid;
         pid = getpid();
 
-        pam_get_item(handle, PAM_SERVICE, (const void**) &service);
         pam_get_item(handle, PAM_XDISPLAY, (const void**) &display);
         pam_get_item(handle, PAM_TTY, (const void**) &tty);
         pam_get_item(handle, PAM_RUSER, (const void**) &remote_user);
diff --git a/units/.gitignore b/units/.gitignore
index 8da3804..ac700e8 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -1,3 +1,4 @@
+user at .service
 systemd-logind.service
 systemd-localed.service
 systemd-timedated.service
diff --git a/units/user at .service.in b/units/user at .service.in
new file mode 100644
index 0000000..d692c8e
--- /dev/null
+++ b/units/user at .service.in
@@ -0,0 +1,18 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=User Manager for %I
+After=systemd-user-sessions.service
+
+[Service]
+User=%I
+PAMName=systemd-shared
+ControlGroup=/user/%I/shared
+ControlGroupModify=yes
+Type=notify
+ExecStart=- at rootbindir@/systemd --user

commit e6061ab2afecfaaa0d0797b88f9a4f53720b31ee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:16:07 2011 +0200

    logind: make sure to create/run/systemd/sessions before we try to place a fifo in it

diff --git a/src/logind-session.c b/src/logind-session.c
index bc1b9b7..cadf932 100644
--- a/src/logind-session.c
+++ b/src/logind-session.c
@@ -787,6 +787,10 @@ int session_create_fifo(Session *s) {
 
         /* Create FIFO */
         if (!s->fifo_path) {
+                r = safe_mkdir("/run/systemd/sessions", 0755, 0, 0);
+                if (r < 0)
+                        return r;
+
                 if (asprintf(&s->fifo_path, "/run/systemd/sessions/%s.ref", s->id) < 0)
                         return -ENOMEM;
 

commit 530345e78299951c3a151c93d77e5adbe421bc68
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:15:41 2011 +0200

    manager: use sd_notify() to notify parent systemd that we have finished startup

diff --git a/Makefile.am b/Makefile.am
index 8da2e1b..2a027c3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -546,7 +546,8 @@ libsystemd_core_la_SOURCES = \
 	src/tcpwrap.c \
 	src/cgroup-util.c \
 	src/condition.c \
-        src/dbus-common.c
+        src/dbus-common.c \
+        src/sd-daemon.c
 
 libsystemd_core_la_CFLAGS = \
 	$(AM_CFLAGS) \
diff --git a/src/manager.c b/src/manager.c
index 0830e80..92a6dff 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -58,6 +58,7 @@
 #include "special.h"
 #include "bus-errors.h"
 #include "exit-status.h"
+#include "sd-daemon.h"
 
 /* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
 #define GC_QUEUE_ENTRIES_MAX 16
@@ -2944,6 +2945,10 @@ void manager_check_finished(Manager *m) {
         }
 
         bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
+
+        sd_notifyf(false,
+                   "READY=1\nSTATUS=Startup finished in %s.",
+                   format_timespan(sum, sizeof(sum), total_usec));
 }
 
 void manager_run_generators(Manager *m) {

commit 3b8bdddeffbbb9569ae68018bf2942cf73befc85
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 02:15:01 2011 +0200

    execute: do initgroups() first, pam initialization second so that it can still modify the groups list

diff --git a/src/execute.c b/src/execute.c
index 6f0f5d0..cb55843 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -886,7 +886,7 @@ static int setup_pam(
          * cleanups, so forget about the handle here. */
         handle = NULL;
 
-        /* Unblock SIGSUR1 again in the parent */
+        /* Unblock SIGTERM again in the parent */
         if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
                 goto fail;
 
@@ -1255,6 +1255,14 @@ int exec_spawn(ExecCommand *command,
                                 }
                 }
 
+                if (apply_permissions)
+                        if (enforce_groups(context, username, uid) < 0) {
+                                r = EXIT_GROUP;
+                                goto fail_child;
+                        }
+
+                umask(context->umask);
+
 #ifdef HAVE_PAM
                 if (context->pam_name && username) {
                         if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) < 0) {
@@ -1264,14 +1272,6 @@ int exec_spawn(ExecCommand *command,
                 }
 #endif
 
-                if (apply_permissions)
-                        if (enforce_groups(context, username, uid) < 0) {
-                                r = EXIT_GROUP;
-                                goto fail_child;
-                        }
-
-                umask(context->umask);
-
                 if (strv_length(context->read_write_dirs) > 0 ||
                     strv_length(context->read_only_dirs) > 0 ||
                     strv_length(context->inaccessible_dirs) > 0 ||

commit 64747e2d4b6feb61e9f9e70d36ffcf5a972e168a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jun 30 00:11:25 2011 +0200

    exec: add ControlGroupModify= switch to allow changing access mode to cgroups fs

diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index ffc2573..b9a37da 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -630,6 +630,18 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>ControlGroupModify=</varname></term>
+                                <listitem><para>Takes a boolean
+                                argument. If true, the control groups
+                                created for this unit will be owned by
+                                ther user specified with
+                                <varname>User=</varname> (and the
+                                configured group), and he can create
+                                subgroups as well as add processes to
+                                the group.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>CapabilityBoundingSet=</varname></term>
 
                                 <listitem><para>Controls which
diff --git a/src/cgroup.c b/src/cgroup.c
index 0c6f20d..a349158 100644
--- a/src/cgroup.c
+++ b/src/cgroup.c
@@ -140,6 +140,50 @@ int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid) {
         return 0;
 }
 
+int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
+        assert(b);
+
+        if (!b->realized)
+                return -EINVAL;
+
+        return cg_set_group_access(b->controller, b->path, mode, uid, gid);
+}
+
+int cgroup_bonding_set_group_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_set_group_access(b, mode, uid, gid);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
+int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid) {
+        assert(b);
+
+        if (!b->realized)
+                return -EINVAL;
+
+        return cg_set_task_access(b->controller, b->path, mode, uid, gid);
+}
+
+int cgroup_bonding_set_task_access_list(CGroupBonding *first, mode_t mode, uid_t uid, gid_t gid) {
+        CGroupBonding *b;
+        int r;
+
+        LIST_FOREACH(by_unit, b, first) {
+                r = cgroup_bonding_set_task_access(b, mode, uid, gid);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s) {
         assert(b);
         assert(sig >= 0);
diff --git a/src/cgroup.h b/src/cgroup.h
index c6dff43..f33d844 100644
--- a/src/cgroup.h
+++ b/src/cgroup.h
@@ -59,6 +59,12 @@ void cgroup_bonding_free_list(CGroupBonding *first, bool remove_or_trim);
 int cgroup_bonding_install(CGroupBonding *b, pid_t pid);
 int cgroup_bonding_install_list(CGroupBonding *first, pid_t pid);
 
+int cgroup_bonding_set_group_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+int cgroup_bonding_set_group_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+
+int cgroup_bonding_set_task_access(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+int cgroup_bonding_set_task_access_list(CGroupBonding *b, mode_t mode, uid_t uid, gid_t gid);
+
 int cgroup_bonding_kill(CGroupBonding *b, int sig, bool sigcont, Set *s);
 int cgroup_bonding_kill_list(CGroupBonding *first, int sig, bool sigcont, Set *s);
 
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 56c5bcd..49ad6cb 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -91,7 +91,8 @@
         "  <property name=\"SameProcessGroup\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"KillMode\" type=\"s\" access=\"read\"/>\n"  \
         "  <property name=\"KillSignal\" type=\"i\" access=\"read\"/>\n" \
-        "  <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n"
+        "  <property name=\"UtmpIdentifier\" type=\"s\" access=\"read\"/>\n" \
+        "  <property name=\"ControlGroupModify\" type=\"b\" access=\"read\"/>\n"
 
 #define BUS_EXEC_COMMAND_INTERFACE(name)                             \
         "  <property name=\"" name "\" type=\"a(sasbttuii)\" access=\"read\"/>\n"
@@ -153,7 +154,8 @@
         { interface, "SameProcessGroup",              bus_property_append_bool,   "b",     &(context).same_pgrp                    }, \
         { interface, "KillMode",                      bus_execute_append_kill_mode, "s",   &(context).kill_mode                    }, \
         { interface, "KillSignal",                    bus_property_append_int,    "i",     &(context).kill_signal                  }, \
-        { interface, "UtmpIdentifier",                bus_property_append_string, "s",     (context).utmp_id                       }
+        { interface, "UtmpIdentifier",                bus_property_append_string, "s",     (context).utmp_id                       }, \
+        { interface, "ControlGroupModify",            bus_property_append_bool,   "b",     &(context).control_group_modify         }
 
 #define BUS_EXEC_STATUS_PROPERTIES(interface, estatus, prefix)           \
         { interface, prefix "StartTimestamp",         bus_property_append_usec,   "t",     &(estatus).start_timestamp.realtime     }, \
diff --git a/src/execute.c b/src/execute.c
index b00ccde..6f0f5d0 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1246,6 +1246,13 @@ int exec_spawn(ExecCommand *command,
                                         r = EXIT_STDIN;
                                         goto fail_child;
                                 }
+
+                        if (cgroup_bondings && context->control_group_modify)
+                                if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 ||
+                                    cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) {
+                                        r = EXIT_CGROUP;
+                                        goto fail_child;
+                                }
                 }
 
 #ifdef HAVE_PAM
@@ -1649,12 +1656,14 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
                 "%sWorkingDirectory: %s\n"
                 "%sRootDirectory: %s\n"
                 "%sNonBlocking: %s\n"
-                "%sPrivateTmp: %s\n",
+                "%sPrivateTmp: %s\n"
+                "%sControlGroupModify: %s\n",
                 prefix, c->umask,
                 prefix, c->working_directory ? c->working_directory : "/",
                 prefix, c->root_directory ? c->root_directory : "/",
                 prefix, yes_no(c->non_blocking),
-                prefix, yes_no(c->private_tmp));
+                prefix, yes_no(c->private_tmp),
+                prefix, yes_no(c->control_group_modify));
 
         STRV_FOREACH(e, c->environment)
                 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
diff --git a/src/execute.h b/src/execute.h
index 55bae24..a2d9072 100644
--- a/src/execute.h
+++ b/src/execute.h
@@ -160,6 +160,8 @@ struct ExecContext {
         bool non_blocking;
         bool private_tmp;
 
+        bool control_group_modify;
+
         /* This is not exposed to the user but available
          * internally. We need it to make sure that whenever we spawn
          * /bin/mount it is run in the same process group as us so
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 352db6b..0c2ef91 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1911,7 +1911,8 @@ static int load_from_path(Unit *u, const char *path) {
                 { "KillMode",               config_parse_kill_mode,       0, &(context).kill_mode,                            section   }, \
                 { "KillSignal",             config_parse_kill_signal,     0, &(context).kill_signal,                          section   }, \
                 { "SendSIGKILL",            config_parse_bool,            0, &(context).send_sigkill,                         section   }, \
-                { "UtmpIdentifier",         config_parse_string_printf,   0, &(context).utmp_id,                              section   }
+                { "UtmpIdentifier",         config_parse_string_printf,   0, &(context).utmp_id,                              section   }, \
+                { "ControlGroupModify",     config_parse_bool,            0, &(context).control_group_modify,                 section   }
 
         const ConfigItem items[] = {
                 { "Names",                  config_parse_names,           0, u,                                               "Unit"    },



More information about the systemd-commits mailing list