[systemd-commits] 13 commits - TODO src/core src/login src/machine src/shared src/systemctl src/test

Lennart Poettering lennart at kemper.freedesktop.org
Wed Jul 10 14:42:23 PDT 2013


 TODO                                  |   12 +++
 src/core/cgroup.c                     |    2 
 src/core/dbus-manager.c               |   19 +---
 src/core/dbus-unit.c                  |  124 ++++++++++++++++++++++++++-----
 src/core/dbus.c                       |  136 +++++++++++++++++++++++++++-------
 src/core/dbus.h                       |    6 +
 src/core/load-fragment-gperf.gperf.m4 |    2 
 src/core/main.c                       |    9 +-
 src/core/manager.c                    |   29 ++++++-
 src/core/manager.h                    |    4 -
 src/core/scope.c                      |    2 
 src/core/unit.c                       |   11 ++
 src/login/logind-dbus.c               |   88 +++++++++++++++++-----
 src/login/logind-session.c            |    3 
 src/login/logind.c                    |   13 +++
 src/login/logind.h                    |    2 
 src/login/user-sessions.c             |  111 ---------------------------
 src/machine/machine.c                 |    1 
 src/machine/machined-dbus.c           |   51 +++++++++++-
 src/machine/machined.c                |   12 +++
 src/shared/dbus-common.c              |    2 
 src/shared/set.c                      |    5 +
 src/systemctl/systemctl.c             |   17 ++--
 src/test/test-engine.c                |    2 
 src/test/test-sched-prio.c            |    2 
 src/test/test-unit-name.c             |    2 
 26 files changed, 445 insertions(+), 222 deletions(-)

New commits:
commit 7fb3ee51c1b37738fd0ea2c81dfd6c336144698a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 23:39:46 2013 +0200

    user-sessions: rely on PID 1 to kill sessions
    
    As we want to centralized cgroup access we should stop killing the user
    sessions directly from the systemd-user-sessions service. Instead, rely
    on PID 1 doing this by adding the right ordering dependencies to the
    session scope units.

diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index e07a28e..57fac00 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -844,6 +844,63 @@ static int bus_unit_set_transient_property(
                         unit_write_drop_in(u, mode, "Slice", contents);
                 }
                 return 1;
+
+        } else if (streq(name, "Requires") ||
+                   streq(name, "RequiresOverridable") ||
+                   streq(name, "Requisite") ||
+                   streq(name, "RequisiteOverridable") ||
+                   streq(name, "Wants") ||
+                   streq(name, "BindsTo") ||
+                   streq(name, "Conflicts") ||
+                   streq(name, "Before") ||
+                   streq(name, "After") ||
+                   streq(name, "OnFailure") ||
+                   streq(name, "PropagatesReloadTo") ||
+                   streq(name, "ReloadPropagatedFrom") ||
+                   streq(name, "PartOf")) {
+
+                UnitDependency d;
+                DBusMessageIter sub;
+
+                d = unit_dependency_from_string(name);
+                if (d < 0)
+                        return -EINVAL;
+
+                if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_ARRAY ||
+                    dbus_message_iter_get_element_type(i) != DBUS_TYPE_STRING)
+                        return -EINVAL;
+
+                dbus_message_iter_recurse(i, &sub);
+                while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRING) {
+                        const char *other;
+
+                        dbus_message_iter_get_basic(&sub, &other);
+
+                        if (!unit_name_is_valid(other, false))
+                                return -EINVAL;
+
+                        if (mode != UNIT_CHECK) {
+                                _cleanup_free_ char *label = NULL, *contents = NULL;
+
+                                r = unit_add_dependency_by_name(u, d, other, NULL, true);
+                                if (r < 0)
+                                        return r;
+
+                                label = strjoin(name, "-", other, NULL);
+                                if (!label)
+                                        return -ENOMEM;
+
+                                contents = strjoin("[Unit]\n", name, "=", other, "\n", NULL);
+                                if (!contents)
+                                        return -ENOMEM;
+
+                                unit_write_drop_in(u, mode, label, contents);
+                        }
+
+                        dbus_message_iter_next(&sub);
+                }
+
+                return 1;
         }
 
         return 0;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index ec46fdc..39af637 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2518,6 +2518,7 @@ int manager_start_scope(
                 pid_t pid,
                 const char *slice,
                 const char *description,
+                const char *after,
                 DBusError *error,
                 char **job) {
 
@@ -2575,6 +2576,20 @@ int manager_start_scope(
                         return log_oom();
         }
 
+        if (!isempty(after)) {
+                const char *after_property = "After";
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &after_property) ||
+                    !dbus_message_iter_open_container(&sub2, DBUS_TYPE_VARIANT, "as", &sub3) ||
+                    !dbus_message_iter_open_container(&sub3, DBUS_TYPE_ARRAY, "s", &sub4) ||
+                    !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_STRING, &after) ||
+                    !dbus_message_iter_close_container(&sub3, &sub4) ||
+                    !dbus_message_iter_close_container(&sub2, &sub3) ||
+                    !dbus_message_iter_close_container(&sub, &sub2))
+                        return log_oom();
+        }
+
         /* cgroup empty notification is not available in containers
          * currently. To make this less problematic, let's shorten the
          * stop timeout for sessions, so that we don't wait
diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 3c67f86..db22150 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -474,7 +474,7 @@ static int session_start_scope(Session *s) {
 
                 description = strjoin("Session ", s->id, " of user ", s->user->name, NULL);
 
-                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, &error, &job);
+                r = manager_start_scope(s->manager, scope, s->leader, s->user->slice, description, "systemd-user-sessions.service", &error, &job);
                 if (r < 0) {
                         log_error("Failed to start session scope: %s %s", bus_error(&error, r), error.name);
                         dbus_error_free(&error);
diff --git a/src/login/logind.h b/src/login/logind.h
index f7457c0..9c41cdf 100644
--- a/src/login/logind.h
+++ b/src/login/logind.h
@@ -178,7 +178,7 @@ int manager_send_changed(Manager *manager, const char *properties);
 
 int manager_dispatch_delayed(Manager *manager);
 
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job);
+int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, const char *after, DBusError *error, char **job);
 int manager_start_unit(Manager *manager, const char *unit, DBusError *error, char **job);
 int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job);
 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error);
diff --git a/src/login/user-sessions.c b/src/login/user-sessions.c
index 18066cc..45fb427 100644
--- a/src/login/user-sessions.c
+++ b/src/login/user-sessions.c
@@ -25,109 +25,8 @@
 
 #include "log.h"
 #include "util.h"
-#include "cgroup-util.h"
 #include "fileio.h"
 
-static int kill_all_users(void) {
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-        int r = 0;
-
-        d = opendir("/run/systemd/users");
-        if (!d) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_error("Failed to open /run/systemd/users: %m");
-                return -errno;
-        }
-
-        FOREACH_DIRENT(de, d, return -errno) {
-                _cleanup_free_ char *cgroup = NULL;
-                char *a;
-                int k;
-
-                if (!dirent_is_file(de))
-                        continue;
-
-                a = strappenda("/run/systemd/users/", de->d_name);
-
-                k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL);
-                if (k < 0) {
-                        if (k != -ENOENT) {
-                                log_error("Failed to read user data: %s", strerror(-k));
-                                r = k;
-                        }
-
-                        continue;
-                }
-
-                if (!cgroup) {
-                        log_error("User data did not contain cgroup field.");
-                        r = -ENOENT;
-                        continue;
-                }
-
-                k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true);
-                if (k < 0) {
-                        log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k));
-                        r = k;
-                }
-        }
-
-        return r;
-}
-
-static int kill_all_sessions(void) {
-        _cleanup_closedir_ DIR *d = NULL;
-        struct dirent *de;
-        int r = 0;
-
-        d = opendir("/run/systemd/sessions");
-        if (!d) {
-                if (errno == ENOENT)
-                        return 0;
-
-                log_error("Failed to open /run/systemd/sessions: %m");
-                return -errno;
-        }
-
-        FOREACH_DIRENT(de, d, return -errno) {
-                _cleanup_free_ char *cgroup = NULL;
-                char *a;
-                int k;
-
-                if (!dirent_is_file(de))
-                        continue;
-
-                a = strappenda("/run/systemd/sessions/", de->d_name);
-
-                k = parse_env_file(a, NEWLINE, "CGROUP", &cgroup, NULL);
-                if (k < 0) {
-                        if (k != -ENOENT) {
-                                log_error("Failed to read session data: %s", strerror(-k));
-                                r = k;
-                        }
-
-                        continue;
-                }
-
-                if (!cgroup) {
-                        log_error("Session data did not contain cgroup field.");
-                        r = -ENOENT;
-                        continue;
-                }
-
-                k = cg_kill_recursive_and_wait(SYSTEMD_CGROUP_CONTROLLER, cgroup, true);
-                if (k < 0) {
-                        log_error("Failed to kill cgroup %s: %s", cgroup, strerror(-k));
-                        r = k;
-                }
-        }
-
-        return r;
-}
-
 int main(int argc, char*argv[]) {
         int ret = EXIT_FAILURE;
 
@@ -167,20 +66,12 @@ int main(int argc, char*argv[]) {
                         goto finish;
 
         } else if (streq(argv[1], "stop")) {
-                int r, q;
+                int r;
 
                 r = write_string_file_atomic("/run/nologin", "System is going down.");
                 if (r < 0)
                         log_error("Failed to create /run/nologin: %s", strerror(-r));
 
-                q = kill_all_users();
-                if (q < 0 && r >= 0)
-                        r = q;
-
-                q = kill_all_sessions();
-                if (q < 0 && r >= 0)
-                        r = q;
-
         } else {
                 log_error("Unknown verb %s.", argv[1]);
                 goto finish;

commit f2d4f98d5873e0649b79b04b967fc9625ab3a350
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 23:33:17 2013 +0200

    logind: when creating the scope job fails, return this immediately to the client that wants to register the session
    
    Otherwise we'll hanging for the job to finish without any job existing.
    
    Similar, for machined.

diff --git a/src/login/logind-session.c b/src/login/logind-session.c
index 2892c38..3c67f86 100644
--- a/src/login/logind-session.c
+++ b/src/login/logind-session.c
@@ -480,6 +480,7 @@ static int session_start_scope(Session *s) {
                         dbus_error_free(&error);
 
                         free(scope);
+                        return r;
                 } else {
                         s->scope = scope;
 
diff --git a/src/machine/machine.c b/src/machine/machine.c
index d75c338..591a656 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -247,6 +247,7 @@ static int machine_start_scope(Machine *m) {
                         dbus_error_free(&error);
 
                         free(scope);
+                        return r;
                 } else {
                         m->scope = scope;
 

commit 6797c324a653f119a3d7133122648aaa4878ddd6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 23:31:40 2013 +0200

    logind: don't misunderstand UnitRemoved signals during reloading
    
    When PID 1 reloads the units logind/machined will see UnitRemoved
    signals for all units. Instead of trusting these immediately, let's
    check the actual unit state before considering a unit gone, so that
    reloading PID 1 is not mistaken as the end of all sessions.

diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 29a1963..ec46fdc 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2427,28 +2427,32 @@ DBusHandlerResult bus_message_filter(
                 }
 
                 session = hashmap_get(m->session_units, unit);
-                if (session) {
-                        hashmap_remove(m->session_units, session->scope);
-                        free(session->scope);
-                        session->scope = NULL;
+                if (session)
+                         session_add_to_gc_queue(session);
 
-                        session_add_to_gc_queue(session);
+                user = hashmap_get(m->user_units, unit);
+                if (user)
+                        user_add_to_gc_queue(user);
+
+        } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "Reloading")) {
+                dbus_bool_t b;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_BOOLEAN, &b,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse Reloading message: %s", bus_error_message(&error));
+                        goto finish;
                 }
 
-                user = hashmap_get(m->user_units, unit);
-                if (user) {
-
-                        if (streq_ptr(unit, user->service)) {
-                                hashmap_remove(m->user_units, user->service);
-                                free(user->service);
-                                user->service = NULL;
-                        } else if (streq_ptr(unit, user->slice)) {
-                                hashmap_remove(m->user_units, user->slice);
-                                free(user->slice);
-                                user->slice = NULL;
-                        }
+                /* systemd finished reloading, let's recheck all our sessions */
+                if (!b) {
+                        Session *session;
+                        Iterator i;
 
-                        user_add_to_gc_queue(user);
+                        log_debug("System manager has been reloaded, rechecking sessions...");
+
+                        HASHMAP_FOREACH(session, m->sessions, i)
+                                session_add_to_gc_queue(session);
                 }
         }
 
@@ -2682,6 +2686,16 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char
                         DBUS_TYPE_STRING, &fail,
                         DBUS_TYPE_INVALID);
         if (r < 0) {
+                if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
+                    dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
+
+                        if (job)
+                                *job = NULL;
+
+                        dbus_error_free(error);
+                        return 0;
+                }
+
                 log_error("Failed to stop unit %s: %s", unit, bus_error(error, r));
                 return r;
         }
@@ -2704,7 +2718,7 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char
                 *job = copy;
         }
 
-        return 0;
+        return 1;
 }
 
 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) {
@@ -2769,8 +2783,26 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
                         DBUS_TYPE_STRING, &interface,
                         DBUS_TYPE_STRING, &property,
                         DBUS_TYPE_INVALID);
-
         if (r < 0) {
+                if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY) ||
+                    dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED)) {
+                        /* systemd might have droppped off
+                         * momentarily, let's not make this an
+                         * error */
+
+                        dbus_error_free(&error);
+                        return true;
+                }
+
+                if (dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
+                    dbus_error_has_name(&error, BUS_ERROR_LOAD_FAILED)) {
+                        /* If the unit is already unloaded then it's
+                         * not active */
+
+                        dbus_error_free(&error);
+                        return false;
+                }
+
                 log_error("Failed to query ActiveState: %s", bus_error(&error, r));
                 dbus_error_free(&error);
                 return r;
diff --git a/src/login/logind.c b/src/login/logind.c
index fcb3ccf..a79ba33 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -1038,12 +1038,23 @@ static int manager_connect_bus(Manager *m) {
                            "interface='org.freedesktop.DBus.Properties',"
                            "member='PropertiesChanged'",
                            &error);
-
         if (dbus_error_is_set(&error)) {
                 log_error("Failed to add match for PropertiesChanged: %s", bus_error_message(&error));
                 dbus_error_free(&error);
         }
 
+        dbus_bus_add_match(m->bus,
+                           "type='signal',"
+                           "sender='org.freedesktop.systemd1',"
+                           "interface='org.freedesktop.systemd1.Manager',"
+                           "member='Reloading',"
+                           "path='/org/freedesktop/systemd1'",
+                           &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
+                dbus_error_free(&error);
+        }
+
         r = bus_method_call_with_reply(
                         m->bus,
                         "org.freedesktop.systemd1",
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 1b1eb3a..4664c73 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -583,12 +583,28 @@ DBusHandlerResult bus_message_filter(
                 }
 
                 mm = hashmap_get(m->machine_units, unit);
-                if (mm) {
-                        hashmap_remove(m->machine_units, mm->scope);
-                        free(mm->scope);
-                        mm->scope = NULL;
-
+                if (mm)
                         machine_add_to_gc_queue(mm);
+
+        } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "Reloading")) {
+                dbus_bool_t b;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_BOOLEAN, &b,
+                                           DBUS_TYPE_INVALID)) {
+                        log_error("Failed to parse Reloading message: %s", bus_error_message(&error));
+                        goto finish;
+                }
+
+                /* systemd finished reloading, let's recheck all our machines */
+                if (!b) {
+                        Machine *mm;
+                        Iterator i;
+
+                        log_debug("System manager has been reloaded, rechecking machines...");
+
+                        HASHMAP_FOREACH(mm, m->machines, i)
+                                machine_add_to_gc_queue(mm);
                 }
         }
 
@@ -727,6 +743,16 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char
                         DBUS_TYPE_STRING, &fail,
                         DBUS_TYPE_INVALID);
         if (r < 0) {
+                if (dbus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT) ||
+                    dbus_error_has_name(error, BUS_ERROR_LOAD_FAILED)) {
+
+                        if (job)
+                                *job = NULL;
+
+                        dbus_error_free(error);
+                        return 0;
+                }
+
                 log_error("Failed to stop unit %s: %s", unit, bus_error(error, r));
                 return r;
         }
@@ -749,7 +775,7 @@ int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char
                 *job = copy;
         }
 
-        return 0;
+        return 1;
 }
 
 int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) {
@@ -814,8 +840,19 @@ int manager_unit_is_active(Manager *manager, const char *unit) {
                         DBUS_TYPE_STRING, &interface,
                         DBUS_TYPE_STRING, &property,
                         DBUS_TYPE_INVALID);
-
         if (r < 0) {
+                if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY) ||
+                    dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED)) {
+                        dbus_error_free(&error);
+                        return true;
+                }
+
+                if (dbus_error_has_name(&error, BUS_ERROR_NO_SUCH_UNIT) ||
+                    dbus_error_has_name(&error, BUS_ERROR_LOAD_FAILED)) {
+                        dbus_error_free(&error);
+                        return false;
+                }
+
                 log_error("Failed to query ActiveState: %s", bus_error(&error, r));
                 dbus_error_free(&error);
                 return r;
diff --git a/src/machine/machined.c b/src/machine/machined.c
index f2803a1..c7c4ecc 100644
--- a/src/machine/machined.c
+++ b/src/machine/machined.c
@@ -233,6 +233,18 @@ static int manager_connect_bus(Manager *m) {
                 dbus_error_free(&error);
         }
 
+        dbus_bus_add_match(m->bus,
+                           "type='signal',"
+                           "sender='org.freedesktop.systemd1',"
+                           "interface='org.freedesktop.systemd1.Manager',"
+                           "member='Reloading',"
+                           "path='/org/freedesktop/systemd1'",
+                           &error);
+        if (dbus_error_is_set(&error)) {
+                log_error("Failed to add match for Reloading: %s", bus_error_message(&error));
+                dbus_error_free(&error);
+        }
+
         r = bus_method_call_with_reply(
                         m->bus,
                         "org.freedesktop.systemd1",

commit 72673e866a83e6aafdbb599eb3eff2617b7dc79d
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 21:17:37 2013 +0200

    unit: when deserializing cgroup path add it back into cgroup hashmap
    
    Also, properly remove cgroup path from hashmap when freeing unit.

diff --git a/src/core/unit.c b/src/core/unit.c
index 70cdd3d..5bc57e2 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -433,7 +433,11 @@ void unit_free(Unit *u) {
         if (u->in_cgroup_queue)
                 LIST_REMOVE(Unit, cgroup_queue, u->manager->cgroup_queue, u);
 
-        free(u->cgroup_path);
+        if (u->cgroup_path) {
+                hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
+                free(u->cgroup_path);
+        }
+
         free(u->description);
         strv_free(u->documentation);
         free(u->fragment_path);
@@ -2308,6 +2312,8 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
 
                         free(u->cgroup_path);
                         u->cgroup_path = s;
+
+                        hashmap_put(u->manager->cgroup_unit, s, u);
                         continue;
                 }
 

commit b9316fb0f39fff3df792e4e72eb491ec4265b91f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 21:13:56 2013 +0200

    unit: save description/slice of transient units to /run
    
    This is necessary so that these properties survive a daemon reload.

diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 4605b2f..e07a28e 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -794,6 +794,7 @@ static int bus_unit_set_transient_property(
                         return -EINVAL;
 
                 if (mode != UNIT_CHECK) {
+                        _cleanup_free_ char *contents = NULL;
                         const char *description;
 
                         dbus_message_iter_get_basic(i, &description);
@@ -801,6 +802,12 @@ static int bus_unit_set_transient_property(
                         r = unit_set_description(u, description);
                         if (r < 0)
                                 return r;
+
+                        contents = strjoin("[Unit]\nDescription=", description, "\n", NULL);
+                        if (!contents)
+                                return -ENOMEM;
+
+                        unit_write_drop_in(u, mode, "Description", contents);
                 }
 
                 return 1;
@@ -818,6 +825,8 @@ static int bus_unit_set_transient_property(
                         if (mode != UNIT_CHECK)
                                 unit_ref_unset(&u->slice);
                 } else {
+                        _cleanup_free_ char *contents = NULL;
+
                         r = manager_load_unit(u->manager, s, NULL, error, &slice);
                         if (r < 0)
                                 return r;
@@ -827,6 +836,12 @@ static int bus_unit_set_transient_property(
 
                         if (mode != UNIT_CHECK)
                                 unit_ref_set(&u->slice, slice);
+
+                        contents = strjoin("[", UNIT_VTABLE(u)->private_section, "]\nSlice=", s, NULL);
+                        if (!contents)
+                                return -ENOMEM;
+
+                        unit_write_drop_in(u, mode, "Slice", contents);
                 }
                 return 1;
         }
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 2325d6a..76fc9c4 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -259,6 +259,8 @@ Path.MakeDirectory,              config_parse_bool,                  0,
 Path.DirectoryMode,              config_parse_mode,                  0,                             offsetof(Path, directory_mode)
 m4_dnl
 CGROUP_CONTEXT_CONFIG_ITEMS(Slice)m4_dnl
+m4_dnl
+CGROUP_CONTEXT_CONFIG_ITEMS(Scope)m4_dnl
 m4_dnl The [Install] section is ignored here.
 Install.Alias,                   NULL,                               0,                             0
 Install.WantedBy,                NULL,                               0,                             0

commit 71445ae75b0e9954d141e5f0ee97803b406ea332
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 21:10:53 2013 +0200

    core: send out "Reloading" signal before and after doing a full reload/reexec of PID 1
    
    Since we'll unload all units/job during a reload, and then readd them it
    is really useful for clients to be aware of this phase hence sent a
    signal out before and after. This signal is called "Reloading" (despite
    the fact that it is also sent out during reexecution, which we consider
    a special case in this context) and has one boolean parameter which is
    true for the signal sent before the reload, and false for the signal
    after the reload. The UnitRemoved/JobRremoved and UnitNew/JobNew due to
    the reloading are guranteed to be between the pair of Reloading
    messages.

diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 742f6bb..d7604b1 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -276,7 +276,10 @@
         "   <arg name=\"userspace\" type=\"t\"/>\n"                     \
         "   <arg name=\"total\" type=\"t\"/>\n"                         \
         "  </signal>"                                                   \
-        "  <signal name=\"UnitFilesChanged\"/>\n"
+        "  <signal name=\"UnitFilesChanged\"/>\n"                       \
+        "  <signal name=\"Reloading\">\n"                               \
+        "   <arg name=\"active\" type=\"b\"/>\n"                        \
+        "  </signal>"
 
 #define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
         "  <property name=\"Version\" type=\"s\" access=\"read\"/>\n"   \
diff --git a/src/core/dbus.c b/src/core/dbus.c
index c1bf25c..aa3d93b 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1451,7 +1451,7 @@ void bus_broadcast_finished(
                 usec_t userspace_usec,
                 usec_t total_usec) {
 
-        DBusMessage *message;
+        _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
 
         assert(m);
 
@@ -1471,18 +1471,42 @@ void bus_broadcast_finished(
                                       DBUS_TYPE_UINT64, &total_usec,
                                       DBUS_TYPE_INVALID)) {
                 log_oom();
-                goto finish;
+                return;
         }
 
 
         if (bus_broadcast(m, message) < 0) {
                 log_oom();
-                goto finish;
+                return;
         }
+}
 
-finish:
-        if (message)
-                dbus_message_unref(message);
+void bus_broadcast_reloading(Manager *m, bool active) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
+        dbus_bool_t b = active;
+
+        assert(m);
+
+        message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
+        if (!message) {
+                log_oom();
+                return;
+        }
+
+        assert_cc(sizeof(usec_t) == sizeof(uint64_t));
+        if (!dbus_message_append_args(message,
+                                      DBUS_TYPE_BOOLEAN, &b,
+                                      DBUS_TYPE_INVALID)) {
+                log_oom();
+                return;
+        }
+
+
+        if (bus_broadcast(m, message) < 0) {
+                log_oom();
+                return;
+        }
 }
 
 Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) {
diff --git a/src/core/dbus.h b/src/core/dbus.h
index b5c28c6..6500cd7 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -43,6 +43,7 @@ bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
 int bus_fdset_add_all(Manager *m, FDSet *fds);
 
 void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
+void bus_broadcast_reloading(Manager *m, bool active);
 
 Set *bus_acquire_subscribed(Manager *m, DBusConnection *c);
 
diff --git a/src/core/main.c b/src/core/main.c
index 1d188e0..efc5791 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1055,15 +1055,16 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
         assert(_f);
         assert(_fds);
 
-        /* Make sure nothing is really destructed when we shut down */
-        m->n_reloading ++;
-
         r = manager_open_serialization(m, &f);
         if (r < 0) {
                 log_error("Failed to create serialization file: %s", strerror(-r));
                 goto fail;
         }
 
+        /* Make sure nothing is really destructed when we shut down */
+        m->n_reloading ++;
+        bus_broadcast_reloading(m, true);
+
         fds = fdset_new();
         if (!fds) {
                 r = -ENOMEM;
diff --git a/src/core/manager.c b/src/core/manager.c
index 51f03de..2e98181 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -864,6 +864,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         if (serialization) {
                 assert(m->n_reloading > 0);
                 m->n_reloading --;
+
+                /* Let's wait for the UnitNew/JobNew messages being
+                 * sent, before we notify that the reload is
+                 * finished */
+                m->send_reloading_done = true;
         }
 
         return r;
@@ -1163,6 +1168,13 @@ unsigned manager_dispatch_dbus_queue(Manager *m) {
         }
 
         m->dispatching_dbus_queue = false;
+
+        if (m->send_reloading_done) {
+                m->send_reloading_done = false;
+
+                bus_broadcast_reloading(m, false);
+        }
+
         return n;
 }
 
@@ -2238,6 +2250,7 @@ int manager_reload(Manager *m) {
                 return r;
 
         m->n_reloading ++;
+        bus_broadcast_reloading(m, true);
 
         fds = fdset_new();
         if (!fds) {
@@ -2297,6 +2310,8 @@ int manager_reload(Manager *m) {
         assert(m->n_reloading > 0);
         m->n_reloading--;
 
+        m->send_reloading_done = true;
+
 finish:
         if (f)
                 fclose(f);
diff --git a/src/core/manager.h b/src/core/manager.h
index 31da04e..6d52414 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -195,6 +195,8 @@ struct Manager {
         int32_t conn_data_slot;
         int32_t subscribed_data_slot;
 
+        bool send_reloading_done;
+
         uint32_t current_job_id;
         uint32_t default_unit_job_id;
 

commit d0ede8f1c555500dceebd3cc8a8e877ed1d89de6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 20:44:21 2013 +0200

    systemctl: suppress error message when doing "systemctl daemon-reexec"
    
    When we issue a reexecution request via the private socket we need to
    expect a "Disconnected" in addition to "NoReply" when the connection is
    terminated.

diff --git a/src/shared/dbus-common.c b/src/shared/dbus-common.c
index f579567..c727cae 100644
--- a/src/shared/dbus-common.c
+++ b/src/shared/dbus-common.c
@@ -1383,6 +1383,8 @@ int bus_method_call_with_reply(
                         r = -EACCES;
                 else if (dbus_error_has_name(&error, DBUS_ERROR_NO_REPLY))
                         r = -ETIMEDOUT;
+                else if (dbus_error_has_name(&error, DBUS_ERROR_DISCONNECTED))
+                        r = -ECONNRESET;
                 else
                         r = -EIO;
                 goto finish;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index e3818cd..d25b7d6 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3938,9 +3938,9 @@ static int daemon_reload(DBusConnection *bus, char **args) {
                 /* There's always a fallback possible for
                  * legacy actions. */
                 r = -EADDRNOTAVAIL;
-        else if (r == -ETIMEDOUT && streq(method, "Reexecute"))
-                /* On reexecution, we expect a disconnect, not
-                 * a reply */
+        else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
+                /* On reexecution, we expect a disconnect, not a
+                 * reply */
                 r = 0;
         else if (r < 0)
                 log_error("Failed to issue method call: %s", bus_error_message(&error));

commit 94c01aeb1049a87435e046245b8e5d975b778c60
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 20:37:19 2013 +0200

    systemctl: suppress error messages when checking whether a unit needs to be reloaded

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 04464de..e3818cd 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1454,8 +1454,9 @@ static int cancel_job(DBusConnection *bus, char **args) {
         return 0;
 }
 
-static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
+static int need_daemon_reload(DBusConnection *bus, const char *unit) {
         _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
+        _cleanup_dbus_error_free_ DBusError error;
         dbus_bool_t b = FALSE;
         DBusMessageIter iter, sub;
         const char
@@ -1465,6 +1466,8 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
         _cleanup_free_ char *n = NULL;
         int r;
 
+        dbus_error_init(&error);
+
         /* We ignore all errors here, since this is used to show a warning only */
 
         n = unit_name_mangle(unit);
@@ -1478,7 +1481,7 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
                         "org.freedesktop.systemd1.Manager",
                         "GetUnit",
                         &reply,
-                        NULL,
+                        &error,
                         DBUS_TYPE_STRING, &n,
                         DBUS_TYPE_INVALID);
         if (r < 0)
@@ -1499,7 +1502,7 @@ static bool need_daemon_reload(DBusConnection *bus, const char *unit) {
                         "org.freedesktop.DBus.Properties",
                         "Get",
                         &reply,
-                        NULL,
+                        &error,
                         DBUS_TYPE_STRING, &interface,
                         DBUS_TYPE_STRING, &property,
                         DBUS_TYPE_INVALID);
@@ -1919,7 +1922,7 @@ static int start_unit_one(
                 return -EIO;
         }
 
-        if (need_daemon_reload(bus, n))
+        if (need_daemon_reload(bus, n) > 0)
                 log_warning("Warning: Unit file of %s changed on disk, 'systemctl %sdaemon-reload' recommended.",
                             n, arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
 

commit 0c5778a26b14093c79bfc9e8b34e2aeeb1d79b87
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 20:35:57 2013 +0200

    scope: don't require an initialized PIDs set when deserializing
    
    When a scope unit is created due to deserialization rather than client
    request don't enforce that the PIDs set must be non-empty, since the
    cgroup is already populated.

diff --git a/src/core/scope.c b/src/core/scope.c
index e0de951..20a969d 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -112,7 +112,7 @@ static int scope_verify(Scope *s) {
         if (UNIT(s)->load_state != UNIT_LOADED)
                 return 0;
 
-        if (set_size(s->pids) <= 0) {
+        if (set_size(s->pids) <= 0 && UNIT(s)->manager->n_reloading <= 0) {
                 log_error_unit(UNIT(s)->id, "Scope %s has no PIDs. Refusing.", UNIT(s)->id);
                 return -EINVAL;
         }

commit b170dd803d334234ad7edd0dc7bb34860832bc07
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 20:33:11 2013 +0200

    core: while we are reloading don't suppress bus signals
    
    While we are reloading we shouldn't suppress adding units to the bus
    queue when there are no subscribers, simply because we might not have
    deserialized the subscribers list yet. Hence, during reloading always
    assume we have subscribers.

diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 5831046..4605b2f 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -568,8 +568,9 @@ const DBusObjectPathVTable bus_unit_vtable = {
 };
 
 void bus_unit_send_change_signal(Unit *u) {
-        _cleanup_free_ char *p = NULL;
         _cleanup_dbus_message_unref_ DBusMessage *m = NULL;
+        _cleanup_free_ char *p = NULL;
+        int r;
 
         assert(u);
 
@@ -587,8 +588,10 @@ void bus_unit_send_change_signal(Unit *u) {
         }
 
         p = unit_dbus_path(u);
-        if (!p)
-                goto oom;
+        if (!p) {
+                log_oom();
+                return;
+        }
 
         if (u->sent_dbus_new_signal) {
                 /* Send a properties changed signal. First for the
@@ -601,19 +604,26 @@ void bus_unit_send_change_signal(Unit *u) {
                         m = bus_properties_changed_new(p,
                                                        UNIT_VTABLE(u)->bus_interface,
                                                        UNIT_VTABLE(u)->bus_invalidating_properties);
-                        if (!m)
-                                goto oom;
+                        if (!m) {
+                                log_oom();
+                                return;
+                        }
 
-                        if (bus_broadcast(u->manager, m) < 0)
-                                goto oom;
+                        r = bus_broadcast(u->manager, m);
+                        if (r < 0) {
+                                log_error("Failed to broadcast change message: %s", strerror(-r));
+                                return;
+                        }
 
                         dbus_message_unref(m);
                 }
 
                 m = bus_properties_changed_new(p, "org.freedesktop.systemd1.Unit",
                                                INVALIDATING_PROPERTIES);
-                if (!m)
-                        goto oom;
+                if (!m) {
+                        log_oom();
+                        return;
+                }
 
         } else {
                 /* Send a new signal */
@@ -621,25 +631,27 @@ void bus_unit_send_change_signal(Unit *u) {
                 m = dbus_message_new_signal("/org/freedesktop/systemd1",
                                             "org.freedesktop.systemd1.Manager",
                                             "UnitNew");
-                if (!m)
-                        goto oom;
+                if (!m) {
+                        log_oom();
+                        return;
+                }
 
                 if (!dbus_message_append_args(m,
                                               DBUS_TYPE_STRING, &u->id,
                                               DBUS_TYPE_OBJECT_PATH, &p,
-                                              DBUS_TYPE_INVALID))
-                        goto oom;
+                                              DBUS_TYPE_INVALID)) {
+                        log_oom();
+                        return;
+                }
         }
 
-        if (bus_broadcast(u->manager, m) < 0)
-                goto oom;
+        r = bus_broadcast(u->manager, m);
+        if (r < 0) {
+                log_error("Failed to broadcast UnitNew/PropertiesChanged message.");
+                return;
+        }
 
         u->sent_dbus_new_signal = true;
-
-        return;
-
-oom:
-        log_oom();
 }
 
 void bus_unit_send_removed_signal(Unit *u) {
diff --git a/src/core/dbus.c b/src/core/dbus.c
index 5180d89..c1bf25c 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1379,6 +1379,12 @@ bool bus_has_subscriber(Manager *m) {
 
         assert(m);
 
+        /* If we are reloading then we might not have deserialized the
+           subscribers yet, hence let's assume that there are some */
+
+        if (m->n_reloading > 0)
+                return true;
+
         SET_FOREACH(c, m->bus_connections_for_dispatch, i)
                 if (bus_connection_has_subscriber(m, c))
                         return true;

commit 6fa4853328e3d78d092172fa54effb7e785d0a85
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 19:24:03 2013 +0200

    core: serialize/deserialize bus subscribers

diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index fe2f749..742f6bb 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1057,17 +1057,9 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
 
                 SELINUX_ACCESS_CHECK(connection, message, "status");
 
-                s = BUS_CONNECTION_SUBSCRIBED(m, connection);
-                if (!s) {
-                        s = set_new(string_hash_func, string_compare_func);
-                        if (!s)
-                                goto oom;
-
-                        if (!dbus_connection_set_data(connection, m->subscribed_data_slot, s, NULL)) {
-                                set_free(s);
-                                goto oom;
-                        }
-                }
+                s = bus_acquire_subscribed(m, connection);
+                if (!s)
+                        goto oom;
 
                 client = strdup(bus_message_get_sender_with_fallback(message));
                 if (!client)
diff --git a/src/core/dbus.c b/src/core/dbus.c
index c2097a4..5180d89 100644
--- a/src/core/dbus.c
+++ b/src/core/dbus.c
@@ -1135,19 +1135,19 @@ int bus_init(Manager *m, bool try_bus_connect) {
 
         if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
             set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
-                goto oom;
+                return log_oom();
 
         if (m->name_data_slot < 0)
                 if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
-                        goto oom;
+                        return log_oom();
 
         if (m->conn_data_slot < 0)
                 if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
-                        goto oom;
+                        return log_oom();
 
         if (m->subscribed_data_slot < 0)
                 if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
-                        goto oom;
+                        return log_oom();
 
         if (try_bus_connect) {
                 if ((r = bus_init_system(m)) < 0 ||
@@ -1155,16 +1155,14 @@ int bus_init(Manager *m, bool try_bus_connect) {
                         return r;
         }
 
-        if ((r = bus_init_private(m)) < 0)
+        r = bus_init_private(m);
+        if (r < 0)
                 return r;
 
         return 0;
-oom:
-        return log_oom();
 }
 
 static void shutdown_connection(Manager *m, DBusConnection *c) {
-        Set *s;
         Job *j;
         Iterator i;
 
@@ -1180,15 +1178,7 @@ static void shutdown_connection(Manager *m, DBusConnection *c) {
 
         set_remove(m->bus_connections, c);
         set_remove(m->bus_connections_for_dispatch, c);
-
-        if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) {
-                char *t;
-
-                while ((t = set_steal_first(s)))
-                        free(t);
-
-                set_free(s);
-        }
+        set_free_free(BUS_CONNECTION_SUBSCRIBED(m, c));
 
         if (m->queued_message_connection == c) {
                 m->queued_message_connection = NULL;
@@ -1259,10 +1249,10 @@ void bus_done(Manager *m) {
         set_free(m->bus_connections_for_dispatch);
 
         if (m->name_data_slot >= 0)
-               dbus_pending_call_free_data_slot(&m->name_data_slot);
+                dbus_pending_call_free_data_slot(&m->name_data_slot);
 
         if (m->conn_data_slot >= 0)
-               dbus_pending_call_free_data_slot(&m->conn_data_slot);
+                dbus_pending_call_free_data_slot(&m->conn_data_slot);
 
         if (m->subscribed_data_slot >= 0)
                 dbus_connection_free_data_slot(&m->subscribed_data_slot);
@@ -1488,3 +1478,69 @@ finish:
         if (message)
                 dbus_message_unref(message);
 }
+
+Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) {
+        Set *s;
+
+        assert(m);
+        assert(c);
+
+        s = BUS_CONNECTION_SUBSCRIBED(m, c);
+        if (s)
+                return s;
+
+        s = set_new(string_hash_func, string_compare_func);
+        if (!s)
+                return NULL;
+
+        if (!dbus_connection_set_data(c, m->subscribed_data_slot, s, NULL)) {
+                set_free(s);
+                return NULL;
+        }
+
+        return s;
+}
+
+void bus_serialize(Manager *m, FILE *f) {
+        char *client;
+        Iterator i;
+        Set *s;
+
+        assert(m);
+        assert(f);
+
+        if (!m->api_bus)
+                return;
+
+        s = BUS_CONNECTION_SUBSCRIBED(m, m->api_bus);
+        SET_FOREACH(client, s, i)
+                fprintf(f, "subscribed=%s\n", client);
+}
+
+int bus_deserialize_item(Manager *m, const char *line) {
+        const char *e;
+        char *b;
+        Set *s;
+
+        assert(m);
+        assert(line);
+
+        if (!m->api_bus)
+                return 0;
+
+        e = startswith(line, "subscribed=");
+        if (!e)
+                return 0;
+
+        s = bus_acquire_subscribed(m, m->api_bus);
+        if (!s)
+                return -ENOMEM;
+
+        b = strdup(e);
+        if (!b)
+                return -ENOMEM;
+
+        set_consume(s, b);
+
+        return 1;
+}
diff --git a/src/core/dbus.h b/src/core/dbus.h
index c7a058e..b5c28c6 100644
--- a/src/core/dbus.h
+++ b/src/core/dbus.h
@@ -44,6 +44,11 @@ int bus_fdset_add_all(Manager *m, FDSet *fds);
 
 void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
 
+Set *bus_acquire_subscribed(Manager *m, DBusConnection *c);
+
+void bus_serialize(Manager *m, FILE *f);
+int bus_deserialize_item(Manager *m, const char *line);
+
 #define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
 #define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
 
diff --git a/src/core/main.c b/src/core/main.c
index 243855f..1d188e0 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1613,7 +1613,7 @@ int main(int argc, char *argv[]) {
         if (arg_running_as == SYSTEMD_SYSTEM)
                 bump_rlimit_nofile(&saved_rlimit_nofile);
 
-        r = manager_new(arg_running_as, &m);
+        r = manager_new(arg_running_as, !!serialization, &m);
         if (r < 0) {
                 log_error("Failed to allocate manager object: %s", strerror(-r));
                 goto finish;
diff --git a/src/core/manager.c b/src/core/manager.c
index 6128194..51f03de 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -424,7 +424,7 @@ static void manager_strip_environment(Manager *m) {
         strv_env_clean(m->environment);
 }
 
-int manager_new(SystemdRunningAs running_as, Manager **_m) {
+int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
         Manager *m;
         int r = -ENOMEM;
 
@@ -476,7 +476,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
         if (!m->cgroup_unit)
                 goto fail;
 
-        if (!(m->watch_bus = hashmap_new(string_hash_func, string_compare_func)))
+        m->watch_bus = hashmap_new(string_hash_func, string_compare_func);
+        if (!m->watch_bus)
                 goto fail;
 
         m->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
@@ -502,7 +503,7 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
         /* Try to connect to the busses, if possible. */
         if ((running_as == SYSTEMD_USER && getenv("DBUS_SESSION_BUS_ADDRESS")) ||
             running_as == SYSTEMD_SYSTEM) {
-                r = bus_init(m, running_as != SYSTEMD_SYSTEM);
+                r = bus_init(m, reexecuting || running_as != SYSTEMD_SYSTEM);
                 if (r < 0)
                         goto fail;
         } else
@@ -2041,6 +2042,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
                 }
         }
 
+        bus_serialize(m, f);
+
         fputc('\n', f);
 
         HASHMAP_FOREACH_KEY(u, t, m->units, i) {
@@ -2054,7 +2057,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
                 fputs(u->id, f);
                 fputc('\n', f);
 
-                if ((r = unit_serialize(u, f, fds, !switching_root)) < 0) {
+                r = unit_serialize(u, f, fds, !switching_root);
+                if (r < 0) {
                         m->n_reloading --;
                         return r;
                 }
@@ -2159,7 +2163,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
 
                         strv_free(m->environment);
                         m->environment = e;
-                } else
+                } else if (bus_deserialize_item(m, l) == 0)
                         log_debug("Unknown serialization item '%s'", l);
         }
 
diff --git a/src/core/manager.h b/src/core/manager.h
index 57a0a8d..31da04e 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -248,7 +248,7 @@ struct Manager {
         char *switch_root_init;
 };
 
-int manager_new(SystemdRunningAs running_as, Manager **m);
+int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **m);
 void manager_free(Manager *m);
 
 int manager_enumerate(Manager *m);
diff --git a/src/core/unit.c b/src/core/unit.c
index 447f201..70cdd3d 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2128,7 +2128,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
         if (!unit_can_serialize(u))
                 return 0;
 
-        if ((r = UNIT_VTABLE(u)->serialize(u, f, fds)) < 0)
+        r = UNIT_VTABLE(u)->serialize(u, f, fds);
+        if (r < 0)
                 return r;
 
 
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index eeff843..29a1963 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -2411,6 +2411,7 @@ DBusHandlerResult bus_message_filter(
                         if (u)
                                 user_add_to_gc_queue(u);
                 }
+
         } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Manager", "UnitRemoved")) {
 
                 const char *path, *unit;
diff --git a/src/shared/set.c b/src/shared/set.c
index c338dc3..5a4bf11 100644
--- a/src/shared/set.c
+++ b/src/shared/set.c
@@ -50,9 +50,12 @@ int set_put(Set *s, void *value) {
 }
 
 int set_consume(Set *s, void *value) {
-        int r = set_put(s, value);
+        int r;
+
+        r = set_put(s, value);
         if (r < 0)
                 free(value);
+
         return r;
 }
 
diff --git a/src/test/test-engine.c b/src/test/test-engine.c
index 0f38622..20ae103 100644
--- a/src/test/test-engine.c
+++ b/src/test/test-engine.c
@@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
 
         assert_se(set_unit_path("test") >= 0);
 
-        assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0);
+        assert_se(manager_new(SYSTEMD_SYSTEM, false, &m) >= 0);
 
         printf("Load1:\n");
         assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0);
diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c
index ba0aacf..7af7407 100644
--- a/src/test/test-sched-prio.c
+++ b/src/test/test-sched-prio.c
@@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
 
         /* prepare the test */
         assert_se(set_unit_path(TEST_DIR) >= 0);
-        r = manager_new(SYSTEMD_USER, &m);
+        r = manager_new(SYSTEMD_USER, false, &m);
         if (r == -EPERM) {
                 puts("manager_new: Permission denied. Skipping test.");
                 return EXIT_TEST_SKIP;
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
index 86cb2b8..93bf28a 100644
--- a/src/test/test-unit-name.c
+++ b/src/test/test-unit-name.c
@@ -123,7 +123,7 @@ static int test_unit_printf(void) {
         assert_se((root = getpwnam("root")));
         assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0);
 
-        r = manager_new(SYSTEMD_USER, &m);
+        r = manager_new(SYSTEMD_USER, false, &m);
         if (r == -EPERM) {
                 puts("manager_new: Permission denied. Skipping test.");
                 return EXIT_TEST_SKIP;

commit 376dd21dc0757e8a6d3f60d6d21bb802a90f1983
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 02:01:29 2013 +0200

    cgroup: downgrade error message when we cannot remove a cgroup to debug
    
    Some units set KillMode=none to survive the initrd→rootfs transition. We
    cannot remove their cgroups, but that shouldn't really be considered an
    issue, so let's downgrade the error message.

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index c7f1e77..b5d1347 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -533,7 +533,7 @@ void unit_destroy_cgroup(Unit *u) {
 
         r = cg_trim_with_mask(u->cgroup_mask, u->cgroup_path, true);
         if (r < 0)
-                log_error("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r));
+                log_debug("Failed to destroy cgroup %s: %s", u->cgroup_path, strerror(-r));
 
         hashmap_remove(u->manager->cgroup_unit, u->cgroup_path);
 

commit bdeeb6b543a2a2d0a494f17b85f1498859cdfc2f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jul 10 02:01:14 2013 +0200

    update TODO

diff --git a/TODO b/TODO
index 0498809..7d413a8 100644
--- a/TODO
+++ b/TODO
@@ -38,6 +38,18 @@ Features:
 
 * when a kernel driver logs in a tight loop we should ratelimit that too.
 
+* journald: when we drop syslog messages because the syslog socket is
+  full, make sure to write how many messages are lost as first thing
+  to syslog when it works again.
+
+* prohibit Restart= set with Type=oneshot
+
+* man: the documentation of Restart= currently is very misleading and suggests the tools from ExecStartPre= might get restarted.
+
+* load .d/*.conf dropins for device units
+
+* user at .service and session-*.scope should get posession of their own cgroups
+
 * move systemctl set-log-level to systemd-analyze?
 
 * fix killing spree logic in systemd-user-sessions



More information about the systemd-commits mailing list