[systemd/f17] auto-restart fix and other improvements

Michal Schmidt michich at fedoraproject.org
Tue Jun 26 10:53:40 UTC 2012


commit 64dea3ab1f3069f753438f3e916b4128be5a625b
Author: Michal Schmidt <mschmidt at redhat.com>
Date:   Tue Jun 26 12:26:35 2012 +0200

    auto-restart fix and other improvements
    
    - Temporarily revert patch for #732874 until the syslog units are fixed.
    - logind improvements (CanTTY, CanGraphical, 'closing' session state).
    - Fix for auto-restart (#832039).
    - Don't ship systemd-vconsole-setup on S390(x) (workaround for #834118).

 ...rily-revert-systemd-return-error-when-ask.patch |   29 ++
 ...se-CanGraphical-and-CanTTY-properties-on-.patch |  204 ++++++++++++
 ...oduce-a-state-for-session-being-one-of-on.patch |  325 ++++++++++++++++++++
 ...an-document-new-sd_session_get_state-call.patch |   81 +++++
 ...CanTTY-and-CanGraphical-seat-attributes-i.patch |  203 ++++++++++++
 ...t-look-for-preset-files-in-lib-unless-usr.patch |   25 ++
 0437-service-fix-incorrect-argument.patch          |   25 ++
 ...s-via-FAILED-DEAD-before-going-to-AUTO_RE.patch |   58 ++++
 systemd.spec                                       |   25 ++-
 9 files changed, 972 insertions(+), 3 deletions(-)
---
diff --git a/0431-F17-Temporarily-revert-systemd-return-error-when-ask.patch b/0431-F17-Temporarily-revert-systemd-return-error-when-ask.patch
new file mode 100644
index 0000000..ec1ae7c
--- /dev/null
+++ b/0431-F17-Temporarily-revert-systemd-return-error-when-ask.patch
@@ -0,0 +1,29 @@
+From 3b8e5d0e1ecaeb51b1b5f349e2f70acb1d8c4e9c Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 26 Jun 2012 12:08:12 +0200
+Subject: [PATCH] F17: Temporarily revert "systemd: return error when asked to
+ stop unknown unit"
+
+This reverts commit ef5fc8087d3b22bd826167a59305b3e8e15f8d68.
+I will return this later after the necessary rsyslog and syslog-ng
+updates are in stable.
+---
+ src/core/dbus-manager.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
+index a610a6b..aaaeec4 100644
+--- a/src/core/dbus-manager.c
++++ b/src/core/dbus-manager.c
+@@ -1594,11 +1594,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
+                                 job_type = JOB_RELOAD;
+                 }
+ 
+-                if (job_type == JOB_STOP && u->load_state == UNIT_ERROR && unit_active_state(u) == UNIT_INACTIVE) {
+-                        dbus_set_error(&error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
+-                        return bus_send_error_reply(connection, message, &error, -EPERM);
+-                }
+-
+                 if ((job_type == JOB_START && u->refuse_manual_start) ||
+                     (job_type == JOB_STOP && u->refuse_manual_stop) ||
+                     ((job_type == JOB_RESTART || job_type == JOB_TRY_RESTART) &&
diff --git a/0432-logind-expose-CanGraphical-and-CanTTY-properties-on-.patch b/0432-logind-expose-CanGraphical-and-CanTTY-properties-on-.patch
new file mode 100644
index 0000000..dedcf03
--- /dev/null
+++ b/0432-logind-expose-CanGraphical-and-CanTTY-properties-on-.patch
@@ -0,0 +1,204 @@
+From 9a18fda4aeb84be192be8744c793d1b9e627bd9a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 21 Jun 2012 13:48:01 +0200
+Subject: [PATCH] logind: expose CanGraphical and CanTTY properties on seat
+ objects
+
+Since we boot so fast now that gdm might get started before the
+graphics drivers are properly loaded and probed we might end up
+announcing seat0 to gdm before it has graphics capabilities. Which will
+cause gdm/X11 cause to fail later on.
+
+To fix this race, let's expose CanGraphical and CanTTY fields on all
+seats, which clarify whether a seat is suitable for gdm resp, suitable
+for text logins. gdm then needs to watch CanGraphical and spawn X11 on
+it only if it is true.
+
+This way:
+
+USB graphics seats will expose CanGraphical=yes, CanTTY=no
+
+Machines with no graphics drivers at all, but a text console:
+CanGraphical=no, CanTTY=yes
+
+Machines with CONFIG_VT turned off: CanGraphical=yes, CanTTY=no
+
+And the most important case: seat0 where the graphics driver has not
+been probed yet boot up with CanGraphical=no, CanTTY=yes first, which
+then changes to CanGraphical=yes as soon as the probing is complete.
+(cherry picked from commit f1a8e221ecacea23883df57951e291a910463948)
+
+Conflicts:
+	TODO
+---
+ src/login/logind-device.c    |   16 +++++++++++++---
+ src/login/logind-seat-dbus.c |   40 ++++++++++++++++++++++++++++++++++++++--
+ src/login/logind-seat.c      |   20 ++++++++++++++++++--
+ src/login/logind-seat.h      |    3 +++
+ 4 files changed, 72 insertions(+), 7 deletions(-)
+
+diff --git a/src/login/logind-device.c b/src/login/logind-device.c
+index bbd370f..66b5c52 100644
+--- a/src/login/logind-device.c
++++ b/src/login/logind-device.c
+@@ -65,22 +65,32 @@ void device_free(Device *d) {
+ }
+ 
+ void device_detach(Device *d) {
++        Seat *s;
+         assert(d);
+ 
+-        if (d->seat)
+-                LIST_REMOVE(Device, devices, d->seat->devices, d);
++        if (!d->seat)
++                return;
+ 
+-        seat_add_to_gc_queue(d->seat);
++        s = d->seat;
++        LIST_REMOVE(Device, devices, d->seat->devices, d);
+         d->seat = NULL;
++
++        seat_add_to_gc_queue(s);
++        seat_send_changed(s, "CanGraphical\0");
+ }
+ 
+ void device_attach(Device *d, Seat *s) {
+         assert(d);
+         assert(s);
+ 
++        if (d->seat == s)
++                return;
++
+         if (d->seat)
+                 device_detach(d);
+ 
+         d->seat = s;
+         LIST_PREPEND(Device, devices, s->devices, d);
++
++        seat_send_changed(s, "CanGraphical\0");
+ }
+diff --git a/src/login/logind-seat-dbus.c b/src/login/logind-seat-dbus.c
+index 95ef5ff..2d4bce6 100644
+--- a/src/login/logind-seat-dbus.c
++++ b/src/login/logind-seat-dbus.c
+@@ -36,6 +36,8 @@
+         "  <property name=\"Id\" type=\"s\" access=\"read\"/>\n"        \
+         "  <property name=\"ActiveSession\" type=\"so\" access=\"read\"/>\n" \
+         "  <property name=\"CanMultiSession\" type=\"b\" access=\"read\"/>\n" \
++        "  <property name=\"CanTTY\" type=\"b\" access=\"read\"/>\n" \
++        "  <property name=\"CanGraphical\" type=\"b\" access=\"read\"/>\n" \
+         "  <property name=\"Sessions\" type=\"a(so)\" access=\"read\"/>\n" \
+         "  <property name=\"IdleHint\" type=\"b\" access=\"read\"/>\n"  \
+         "  <property name=\"IdleSinceHint\" type=\"t\" access=\"read\"/>\n" \
+@@ -133,7 +135,7 @@ static int bus_seat_append_sessions(DBusMessageIter *i, const char *property, vo
+         return 0;
+ }
+ 
+-static int bus_seat_append_multi_session(DBusMessageIter *i, const char *property, void *data) {
++static int bus_seat_append_can_multi_session(DBusMessageIter *i, const char *property, void *data) {
+         Seat *s = data;
+         dbus_bool_t b;
+ 
+@@ -149,6 +151,38 @@ static int bus_seat_append_multi_session(DBusMessageIter *i, const char *propert
+         return 0;
+ }
+ 
++static int bus_seat_append_can_tty(DBusMessageIter *i, const char *property, void *data) {
++        Seat *s = data;
++        dbus_bool_t b;
++
++        assert(i);
++        assert(property);
++        assert(s);
++
++        b = seat_can_tty(s);
++
++        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
++                return -ENOMEM;
++
++        return 0;
++}
++
++static int bus_seat_append_can_graphical(DBusMessageIter *i, const char *property, void *data) {
++        Seat *s = data;
++        dbus_bool_t b;
++
++        assert(i);
++        assert(property);
++        assert(s);
++
++        b = seat_can_graphical(s);
++
++        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, &b))
++                return -ENOMEM;
++
++        return 0;
++}
++
+ static int bus_seat_append_idle_hint(DBusMessageIter *i, const char *property, void *data) {
+         Seat *s = data;
+         dbus_bool_t b;
+@@ -210,7 +244,9 @@ static int get_seat_for_path(Manager *m, const char *path, Seat **_s) {
+ static const BusProperty bus_login_seat_properties[] = {
+         { "Id",                     bus_property_append_string,      "s", offsetof(Seat, id), true },
+         { "ActiveSession",          bus_seat_append_active,       "(so)", 0 },
+-        { "CanMultiSession",        bus_seat_append_multi_session,   "b", 0 },
++        { "CanMultiSession",        bus_seat_append_can_multi_session, "b", 0 },
++        { "CanTTY",                 bus_seat_append_can_tty,         "b", 0 },
++        { "CanGraphical",           bus_seat_append_can_graphical,   "b", 0 },
+         { "Sessions",               bus_seat_append_sessions,    "a(so)", 0 },
+         { "IdleHint",               bus_seat_append_idle_hint,       "b", 0 },
+         { "IdleSinceHint",          bus_seat_append_idle_hint_since, "t", 0 },
+diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c
+index 2a4786c..402c4e6 100644
+--- a/src/login/logind-seat.c
++++ b/src/login/logind-seat.c
+@@ -104,9 +104,13 @@ int seat_save(Seat *s) {
+         fprintf(f,
+                 "# This is private data. Do not parse.\n"
+                 "IS_VTCONSOLE=%i\n"
+-                "CAN_MULTI_SESSION=%i\n",
++                "CAN_MULTI_SESSION=%i\n"
++                "CAN_TTY=%i\n"
++                "CAN_GRAPHICAL=%i\n",
+                 seat_is_vtconsole(s),
+-                seat_can_multi_session(s));
++                seat_can_multi_session(s),
++                seat_can_tty(s),
++                seat_can_graphical(s));
+ 
+         if (s->active) {
+                 assert(s->active->user);
+@@ -427,6 +431,18 @@ bool seat_can_multi_session(Seat *s) {
+         return s->manager->console_active_fd >= 0;
+ }
+ 
++bool seat_can_tty(Seat *s) {
++        assert(s);
++
++        return seat_is_vtconsole(s);
++}
++
++bool seat_can_graphical(Seat *s) {
++        assert(s);
++
++        return !!s->devices;
++}
++
+ int seat_get_idle_hint(Seat *s, dual_timestamp *t) {
+         Session *session;
+         bool idle_hint = true;
+diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h
+index 3b2c7f0..445d5de 100644
+--- a/src/login/logind-seat.h
++++ b/src/login/logind-seat.h
+@@ -63,6 +63,9 @@ int seat_attach_session(Seat *s, Session *session);
+ 
+ bool seat_is_vtconsole(Seat *s);
+ bool seat_can_multi_session(Seat *s);
++bool seat_can_tty(Seat *s);
++bool seat_can_graphical(Seat *s);
++
+ int seat_get_idle_hint(Seat *s, dual_timestamp *t);
+ 
+ int seat_start(Seat *s);
diff --git a/0433-logind-introduce-a-state-for-session-being-one-of-on.patch b/0433-logind-introduce-a-state-for-session-being-one-of-on.patch
new file mode 100644
index 0000000..a79dbca
--- /dev/null
+++ b/0433-logind-introduce-a-state-for-session-being-one-of-on.patch
@@ -0,0 +1,325 @@
+From 14c8069bcc228db3e92132d6baa5edaf3387d83b Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 21 Jun 2012 16:14:53 +0200
+Subject: [PATCH] logind: introduce a state for session, being one of online,
+ active, closing
+
+online = logged in
+active = logged in and session is in the fg
+closing = nominally logged out but some left-over processes still around
+
+Related to:
+
+https://bugzilla.gnome.org/show_bug.cgi?id=677556
+(cherry picked from commit 0604381b9dbef4cc498b5a77311e1da99c1430b8)
+
+Conflicts:
+	TODO
+---
+ src/login/libsystemd-login.sym  |    5 +++++
+ src/login/loginctl.c            |   10 +++++-----
+ src/login/logind-session-dbus.c |   22 ++++++++++++++++++++--
+ src/login/logind-session.c      |   22 ++++++++++++++++++++++
+ src/login/logind-session.h      |   13 +++++++++++++
+ src/login/logind-user.h         |   10 +++++-----
+ src/login/sd-login.c            |   24 ++++++++++++++++++++++++
+ src/login/test-login.c          |    5 +++++
+ src/systemd/sd-login.h          |    9 +++++++--
+ 9 files changed, 106 insertions(+), 14 deletions(-)
+
+diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
+index a5e6c1e..e43ee17 100644
+--- a/src/login/libsystemd-login.sym
++++ b/src/login/libsystemd-login.sym
+@@ -46,3 +46,8 @@ global:
+         sd_session_get_class;
+         sd_session_get_display;
+ } LIBSYSTEMD_LOGIN_38;
++
++LIBSYSTEMD_LOGIN_186 {
++global:
++        sd_session_get_state;
++} LIBSYSTEMD_LOGIN_43;
+diff --git a/src/login/loginctl.c b/src/login/loginctl.c
+index a494447..9a43685 100644
+--- a/src/login/loginctl.c
++++ b/src/login/loginctl.c
+@@ -364,7 +364,7 @@ typedef struct SessionStatusInfo {
+         pid_t leader;
+         const char *type;
+         const char *class;
+-        bool active;
++        const char *state;
+ } SessionStatusInfo;
+ 
+ typedef struct UserStatusInfo {
+@@ -458,8 +458,8 @@ static void print_session_status_info(SessionStatusInfo *i) {
+         } else if (i->class)
+                 printf("\t   Class: %s\n", i->class);
+ 
+-
+-        printf("\t  Active: %s\n", yes_no(i->active));
++        if (i->state)
++                printf("\t   State: %s\n", i->state);
+ 
+         if (i->default_control_group) {
+                 unsigned c;
+@@ -597,6 +597,8 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
+                                 i->type = s;
+                         else if (streq(name, "Class"))
+                                 i->class = s;
++                        else if (streq(name, "State"))
++                                i->state = s;
+                 }
+                 break;
+         }
+@@ -621,8 +623,6 @@ static int status_property_session(const char *name, DBusMessageIter *iter, Sess
+ 
+                 if (streq(name, "Remote"))
+                         i->remote = b;
+-                else if (streq(name, "Active"))
+-                        i->active = b;
+ 
+                 break;
+         }
+diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c
+index e9fd5a3..c1704d1 100644
+--- a/src/login/logind-session-dbus.c
++++ b/src/login/logind-session-dbus.c
+@@ -53,12 +53,13 @@
+         "  <property name=\"Remote\" type=\"b\" access=\"read\"/>\n"    \
+         "  <property name=\"RemoteHost\" type=\"s\" access=\"read\"/>\n" \
+         "  <property name=\"RemoteUser\" type=\"s\" access=\"read\"/>\n" \
+-        "  <property name=\"Service\" type=\"s\" access=\"read\"/>\n" \
++        "  <property name=\"Service\" type=\"s\" access=\"read\"/>\n"   \
+         "  <property name=\"Leader\" type=\"u\" access=\"read\"/>\n"    \
+         "  <property name=\"Audit\" type=\"u\" access=\"read\"/>\n"     \
+         "  <property name=\"Type\" type=\"s\" access=\"read\"/>\n"      \
+-        "  <property name=\"Class\" type=\"s\" access=\"read\"/>\n"      \
++        "  <property name=\"Class\" type=\"s\" access=\"read\"/>\n"     \
+         "  <property name=\"Active\" type=\"b\" access=\"read\"/>\n"    \
++        "  <property name=\"State\" type=\"s\" access=\"read\"/>\n"     \
+         "  <property name=\"Controllers\" type=\"as\" access=\"read\"/>\n" \
+         "  <property name=\"ResetControllers\" type=\"as\" access=\"read\"/>\n" \
+         "  <property name=\"KillProcesses\" type=\"b\" access=\"read\"/>\n" \
+@@ -219,6 +220,22 @@ static int bus_session_append_default_cgroup(DBusMessageIter *i, const char *pro
+ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_type, session_type, SessionType);
+ static DEFINE_BUS_PROPERTY_APPEND_ENUM(bus_session_append_class, session_class, SessionClass);
+ 
++static int bus_session_append_state(DBusMessageIter *i, const char *property, void *data) {
++        Session *s = data;
++        const char *state;
++
++        assert(i);
++        assert(property);
++        assert(s);
++
++        state = session_state_to_string(session_get_state(s));
++
++        if (!dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, &state))
++                return -ENOMEM;
++
++        return 0;
++}
++
+ static int get_session_for_path(Manager *m, const char *path, Session **_s) {
+         Session *s;
+         char *id;
+@@ -262,6 +279,7 @@ static const BusProperty bus_login_session_properties[] = {
+         { "Type",                   bus_session_append_type,            "s", offsetof(Session, type)                },
+         { "Class",                  bus_session_append_class,           "s", offsetof(Session, class)               },
+         { "Active",                 bus_session_append_active,          "b", 0 },
++        { "State",                  bus_session_append_state,           "s", 0 },
+         { "Controllers",            bus_property_append_strv,          "as", offsetof(Session, controllers),        true },
+         { "ResetControllers",       bus_property_append_strv,          "as", offsetof(Session, reset_controllers),  true },
+         { "KillProcesses",          bus_property_append_bool,           "b", offsetof(Session, kill_processes)      },
+diff --git a/src/login/logind-session.c b/src/login/logind-session.c
+index 49e1e5c..1945041 100644
+--- a/src/login/logind-session.c
++++ b/src/login/logind-session.c
+@@ -133,11 +133,13 @@ int session_save(Session *s) {
+                 "UID=%lu\n"
+                 "USER=%s\n"
+                 "ACTIVE=%i\n"
++                "STATE=%s\n"
+                 "REMOTE=%i\n"
+                 "KILL_PROCESSES=%i\n",
+                 (unsigned long) s->user->uid,
+                 s->user->name,
+                 session_is_active(s),
++                session_state_to_string(session_get_state(s)),
+                 s->remote,
+                 s->kill_processes);
+ 
+@@ -913,6 +915,18 @@ void session_add_to_gc_queue(Session *s) {
+         s->in_gc_queue = true;
+ }
+ 
++SessionState session_get_state(Session *s) {
++        assert(s);
++
++        if (s->fifo_fd < 0)
++                return SESSION_CLOSING;
++
++        if (session_is_active(s))
++                return SESSION_ACTIVE;
++
++        return SESSION_ONLINE;
++}
++
+ int session_kill(Session *s, KillWho who, int signo) {
+         int r = 0;
+         Set *pid_set = NULL;
+@@ -954,6 +968,14 @@ int session_kill(Session *s, KillWho who, int signo) {
+         return r;
+ }
+ 
++static const char* const session_state_table[_SESSION_TYPE_MAX] = {
++        [SESSION_ONLINE] = "online",
++        [SESSION_ACTIVE] = "active",
++        [SESSION_CLOSING] = "closing"
++};
++
++DEFINE_STRING_TABLE_LOOKUP(session_state, SessionState);
++
+ static const char* const session_type_table[_SESSION_TYPE_MAX] = {
+         [SESSION_TTY] = "tty",
+         [SESSION_X11] = "x11",
+diff --git a/src/login/logind-session.h b/src/login/logind-session.h
+index d0b8c87..77a12af 100644
+--- a/src/login/logind-session.h
++++ b/src/login/logind-session.h
+@@ -30,6 +30,14 @@ typedef struct Session Session;
+ #include "logind-seat.h"
+ #include "logind-user.h"
+ 
++typedef enum SessionState {
++        SESSION_ONLINE,   /* Logged in */
++        SESSION_ACTIVE,   /* Logged in and in the fg */
++        SESSION_CLOSING,  /* Logged out, but processes still remain */
++        _SESSION_STATE_MAX,
++        _SESSION_STATE_INVALID = -1
++} SessionState;
++
+ typedef enum SessionType {
+         SESSION_UNSPECIFIED,
+         SESSION_TTY,
+@@ -118,12 +126,17 @@ int session_kill(Session *s, KillWho who, int signo);
+ 
+ char *session_bus_path(Session *s);
+ 
++SessionState session_get_state(Session *u);
++
+ extern const DBusObjectPathVTable bus_session_vtable;
+ 
+ int session_send_signal(Session *s, bool new_session);
+ int session_send_changed(Session *s, const char *properties);
+ int session_send_lock(Session *s, bool lock);
+ 
++const char* session_state_to_string(SessionState t);
++SessionState session_state_from_string(const char *s);
++
+ const char* session_type_to_string(SessionType t);
+ SessionType session_type_from_string(const char *s);
+ 
+diff --git a/src/login/logind-user.h b/src/login/logind-user.h
+index 802f1ed..23e409c 100644
+--- a/src/login/logind-user.h
++++ b/src/login/logind-user.h
+@@ -30,11 +30,11 @@ typedef struct User User;
+ #include "logind-session.h"
+ 
+ typedef enum UserState {
+-        USER_OFFLINE,
+-        USER_LINGERING,
+-        USER_ONLINE,
+-        USER_ACTIVE,
+-        USER_CLOSING,
++        USER_OFFLINE,    /* Not logged in at all */
++        USER_LINGERING,  /* Lingering has been enabled by the admin for this user */
++        USER_ONLINE,     /* User logged in */
++        USER_ACTIVE,     /* User logged in and has a session in the fg */
++        USER_CLOSING,    /* User logged out, but processes still remain and lingering is not enabled */
+         _USER_STATE_MAX,
+         _USER_STATE_INVALID = -1
+ } UserState;
+diff --git a/src/login/sd-login.c b/src/login/sd-login.c
+index a17c1d4..2effe7d 100644
+--- a/src/login/sd-login.c
++++ b/src/login/sd-login.c
+@@ -317,6 +317,30 @@ _public_ int sd_session_is_active(const char *session) {
+         return r;
+ }
+ 
++_public_ int sd_session_get_state(const char *session, char **state) {
++        char *p, *s = NULL;
++        int r;
++
++        if (!state)
++                return -EINVAL;
++
++        r = file_of_session(session, &p);
++        if (r < 0)
++                return r;
++
++        r = parse_env_file(p, NEWLINE, "STATE", &s, NULL);
++        free(p);
++
++        if (r < 0) {
++                free(s);
++                return r;
++        } else if (!s)
++                return -EIO;
++
++        *state = s;
++        return 0;
++}
++
+ _public_ int sd_session_get_uid(const char *session, uid_t *uid) {
+         int r;
+         char *p, *s = NULL;
+diff --git a/src/login/test-login.c b/src/login/test-login.c
+index dd84042..2e0e257 100644
+--- a/src/login/test-login.c
++++ b/src/login/test-login.c
+@@ -71,6 +71,11 @@ int main(int argc, char* argv[]) {
+         assert_se(r >= 0);
+         printf("active = %s\n", yes_no(r));
+ 
++        r = sd_session_get_state(session, &state);
++        assert_se(r >= 0);
++        printf("state = %s\n", state);
++        free(state);
++
+         assert_se(sd_session_get_uid(session, &u) >= 0);
+         printf("uid = %lu\n", (unsigned long) u);
+         assert_se(u == u2);
+diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
+index 315700e..1d5b657 100644
+--- a/src/systemd/sd-login.h
++++ b/src/systemd/sd-login.h
+@@ -63,7 +63,7 @@ int sd_pid_get_owner_uid(pid_t pid, uid_t *uid);
+  * error for non-service processes. */
+ int sd_pid_get_unit(pid_t, char **unit);
+ 
+-/* Get state from uid. Possible states: offline, lingering, online, active */
++/* Get state from uid. Possible states: offline, lingering, online, active, closing */
+ int sd_uid_get_state(uid_t uid, char**state);
+ 
+ /* Return 1 if uid has session on seat. If require_active is true will
+@@ -80,9 +80,14 @@ int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions);
+  * just return number of seats.*/
+ int sd_uid_get_seats(uid_t uid, int require_active, char ***seats);
+ 
+-/* Return 1 if the session is a active */
++/* Return 1 if the session is a active. */
+ int sd_session_is_active(const char *session);
+ 
++/* Get state from session. Possible states: online, active, closing
++ * (This function is a more generic version of
++ * sd_session_is_active().) */
++int sd_session_get_state(const char *sessio, char **state);
++
+ /* Determine user id of session */
+ int sd_session_get_uid(const char *session, uid_t *uid);
+ 
diff --git a/0434-man-document-new-sd_session_get_state-call.patch b/0434-man-document-new-sd_session_get_state-call.patch
new file mode 100644
index 0000000..1f85a69
--- /dev/null
+++ b/0434-man-document-new-sd_session_get_state-call.patch
@@ -0,0 +1,81 @@
+From 3ba2cfc41e04cbb1cfeb2c081b54c874ebaddec4 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 21 Jun 2012 16:31:06 +0200
+Subject: [PATCH] man: document new sd_session_get_state() call (cherry picked
+ from commit 7ea9cb91207f49965bc23bfdac9d5475940bea51)
+
+---
+ man/sd_session_is_active.xml |   26 ++++++++++++++++++++++++++
+ man/sd_uid_get_state.xml     |    8 ++++++--
+ 2 files changed, 32 insertions(+), 2 deletions(-)
+
+diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
+index afdeed5..0665617 100644
+--- a/man/sd_session_is_active.xml
++++ b/man/sd_session_is_active.xml
+@@ -44,6 +44,7 @@
+ 
+         <refnamediv>
+                 <refname>sd_session_is_active</refname>
++                <refname>sd_session_get_state</refname>
+                 <refname>sd_session_get_uid</refname>
+                 <refname>sd_session_get_seat</refname>
+                 <refname>sd_session_get_service</refname>
+@@ -63,6 +64,12 @@
+                         </funcprototype>
+ 
+                         <funcprototype>
++                                <funcdef>int <function>sd_session_get_state</function></funcdef>
++                                <paramdef>const char* <parameter>session</parameter></paramdef>
++                                <paramdef>char** <parameter>state</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
+                                 <funcdef>int <function>sd_session_get_uid</function></funcdef>
+                                 <paramdef>const char* <parameter>session</parameter></paramdef>
+                                 <paramdef>uid_t* <parameter>uid</parameter></paramdef>
+@@ -109,6 +116,25 @@
+                 (i.e. currently in the foreground and available for
+                 user input) or not.</para>
+ 
++                <para><function>sd_session_get_state()</function> may
++                be used to determine the state of the session
++                identified by the specified session identifier. The
++                following states are currently known:
++                <literal>online</literal> (session logged in, but
++                session not active, i.e. not in the foreground),
++                <literal>active</literal> (session logged in and
++                active, i.e. in the foreground),
++                <literal>closing</literal> (session nominally logged
++                out, but some processes belonging to it are still
++                around). In the future additional states might be
++                defined, client code should be written to be robust in
++                regards to additional state strings being
++                returned. This function is a more generic version of
++                <function>sd_session_is_active()</function>. The returned
++                string needs to be freed with the libc
++                <citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
++                call after use.</para>
++
+                 <para><function>sd_session_get_uid()</function> may be
+                 used to determine the user identifier of the Unix user the session
+                 identified by the specified session identifier belongs
+diff --git a/man/sd_uid_get_state.xml b/man/sd_uid_get_state.xml
+index 9249021..0f5643c 100644
+--- a/man/sd_uid_get_state.xml
++++ b/man/sd_uid_get_state.xml
+@@ -93,8 +93,12 @@
+                 at all), <literal>lingering</literal> (user not logged
+                 in, but some user services running),
+                 <literal>online</literal> (user logged in, but not
+-                active), <literal>active</literal> (user logged in on
+-                an active seat). In the future additional states might
++                active, i.e. has no session in the foreground),
++                <literal>active</literal> (user logged in, and has at
++                least one active session, i.e. one session in the
++                foreground), <literal>closing</literal> (user not
++                logged in, and not lingering, but some processes are
++                still around). In the future additional states might
+                 be defined, client code should be written to be robust
+                 in regards to additional state strings being
+                 returned. The returned string needs to be freed with
diff --git a/0435-login-wrap-CanTTY-and-CanGraphical-seat-attributes-i.patch b/0435-login-wrap-CanTTY-and-CanGraphical-seat-attributes-i.patch
new file mode 100644
index 0000000..d3fa8b1
--- /dev/null
+++ b/0435-login-wrap-CanTTY-and-CanGraphical-seat-attributes-i.patch
@@ -0,0 +1,203 @@
+From 85b034c691e7a827488c61bdae5d5da9d52ac72a Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 21 Jun 2012 16:52:54 +0200
+Subject: [PATCH] login: wrap CanTTY and CanGraphical seat attributes in
+ libsystemd-login (cherry picked from commit
+ 20747498c68575646fae88f4dd270fab219a25a6)
+
+---
+ man/sd_seat_get_active.xml     |   31 +++++++++++++++++++++++++++----
+ man/sd_session_is_active.xml   |   16 ++++++++++++----
+ src/login/libsystemd-login.sym |    2 ++
+ src/login/sd-login.c           |   16 ++++++++++++++--
+ src/login/test-login.c         |    8 ++++++++
+ src/systemd/sd-login.h         |    6 ++++++
+ 6 files changed, 69 insertions(+), 10 deletions(-)
+
+diff --git a/man/sd_seat_get_active.xml b/man/sd_seat_get_active.xml
+index acc6ee4..e63cf13 100644
+--- a/man/sd_seat_get_active.xml
++++ b/man/sd_seat_get_active.xml
+@@ -72,6 +72,16 @@
+                                 <funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
+                                 <paramdef>const char* <parameter>seat</parameter></paramdef>
+                         </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_seat_can_tty</function></funcdef>
++                                <paramdef>const char* <parameter>seat</parameter></paramdef>
++                        </funcprototype>
++
++                        <funcprototype>
++                                <funcdef>int <function>sd_seat_can_graphical</function></funcdef>
++                                <paramdef>const char* <parameter>seat</parameter></paramdef>
++                        </funcprototype>
+                 </funcsynopsis>
+         </refsynopsisdiv>
+ 
+@@ -111,6 +121,15 @@
+                 sessions in parallel (whith only one being active at a
+                 time).</para>
+ 
++                <para><function>sd_seat_can_tty()</function> may be
++                used to determine whether a specific seat provides TTY
++                functionality, i.e. is useful as a text console.</para>
++
++                <para><function>sd_seat_can_graphical()</function> may
++                be used to determine whether a specific seat provides
++                graphics functionality, i.e. is useful as a graphics
++                display.</para>
++
+                 <para>If the <literal>seat</literal> parameter of any
+                 of these functions is passed as NULL the operation is
+                 executed for the seat of the session of the calling
+@@ -126,8 +145,10 @@
+                 <function>sd_seat_get_sessions()</function> returns
+                 the number of entries in the session identifier
+                 array. If the test succeeds
+-                <function>sd_seat_can_multi_session</function> returns
+-                a positive integer, if it fails 0. On failure, these
++                <function>sd_seat_can_multi_session</function>,
++                <function>sd_seat_can_tty</function> and
++                <function>sd_seat_can_graphical</function> return a
++                positive integer, if it fails 0. On failure, these
+                 calls return a negative errno-style error code.</para>
+         </refsect1>
+ 
+@@ -135,8 +156,10 @@
+                 <title>Notes</title>
+ 
+                 <para>The <function>sd_seat_get_active()</function>,
+-                <function>sd_seat_get_sessions()</function>, and
+-                <function>sd_seat_can_multi_session()</function> interfaces
++                <function>sd_seat_get_sessions()</function>,
++                <function>sd_seat_can_multi_session()</function>,
++                <function>sd_seat_can_tty()</function> and
++                <function>sd_seat_can_grapical()</function> interfaces
+                 are available as shared library, which can be compiled
+                 and linked to with the
+                 <literal>libsystemd-login</literal>
+diff --git a/man/sd_session_is_active.xml b/man/sd_session_is_active.xml
+index 0665617..b6e0d2b 100644
+--- a/man/sd_session_is_active.xml
++++ b/man/sd_session_is_active.xml
+@@ -198,9 +198,13 @@
+                 <para>If the test succeeds
+                 <function>sd_session_is_active()</function> returns a
+                 positive integer, if it fails 0.  On success
++                <function>sd_session_get_state()</function>,
+                 <function>sd_session_get_uid()</function>,
+-                <function>sd_session_get_service()</function> and
+-                <function>sd_session_get_seat()</function> return 0 or
++                <function>sd_session_get_seat()</function>,
++                <function>sd_session_get_service()</function>,
++                <function>sd_session_get_type()</function>,
++                <function>sd_session_get_class()</function> and
++                <function>sd_session_get_display()</function> return 0 or
+                 a positive integer. On failure, these calls return a
+                 negative errno-style error code.</para>
+         </refsect1>
+@@ -209,9 +213,13 @@
+                 <title>Notes</title>
+ 
+                 <para>The <function>sd_session_is_active()</function>,
++                <function>sd_session_get_state()</function>,
+                 <function>sd_session_get_uid()</function>,
+-                <function>sd_session_get_service()</function> and
+-                <function>sd_session_get_seat()</function> interfaces
++                <function>sd_session_get_seat()</function>,
++                <function>sd_session_get_service()</function>,
++                <function>sd_session_get_type()</function>,
++                <function>sd_session_get_class()</function> and
++                <function>sd_session_get_display()</function> interfaces
+                 are available as shared library, which can be compiled
+                 and linked to with the
+                 <literal>libsystemd-login</literal>
+diff --git a/src/login/libsystemd-login.sym b/src/login/libsystemd-login.sym
+index e43ee17..11bdc00 100644
+--- a/src/login/libsystemd-login.sym
++++ b/src/login/libsystemd-login.sym
+@@ -50,4 +50,6 @@ global:
+ LIBSYSTEMD_LOGIN_186 {
+ global:
+         sd_session_get_state;
++        sd_seat_can_tty;
++        sd_seat_can_graphical;
+ } LIBSYSTEMD_LOGIN_43;
+diff --git a/src/login/sd-login.c b/src/login/sd-login.c
+index 2effe7d..d47a49c 100644
+--- a/src/login/sd-login.c
++++ b/src/login/sd-login.c
+@@ -583,7 +583,7 @@ _public_ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **ui
+         return r;
+ }
+ 
+-_public_ int sd_seat_can_multi_session(const char *seat) {
++static int seat_get_can(const char *seat, const char *variable) {
+         char *p, *s = NULL;
+         int r;
+ 
+@@ -592,7 +592,7 @@ _public_ int sd_seat_can_multi_session(const char *seat) {
+                 return r;
+ 
+         r = parse_env_file(p, NEWLINE,
+-                           "CAN_MULTI_SESSION", &s,
++                           variable, &s,
+                            NULL);
+         free(p);
+ 
+@@ -610,6 +610,18 @@ _public_ int sd_seat_can_multi_session(const char *seat) {
+         return r;
+ }
+ 
++_public_ int sd_seat_can_multi_session(const char *seat) {
++        return seat_get_can(seat, "CAN_MULTI_SESSION");
++}
++
++_public_ int sd_seat_can_tty(const char *seat) {
++        return seat_get_can(seat, "CAN_TTY");
++}
++
++_public_ int sd_seat_can_graphical(const char *seat) {
++        return seat_get_can(seat, "CAN_GRAPHICAL");
++}
++
+ _public_ int sd_get_seats(char ***seats) {
+         return get_files_in_directory("/run/systemd/seats/", seats);
+ }
+diff --git a/src/login/test-login.c b/src/login/test-login.c
+index 2e0e257..5325aeb 100644
+--- a/src/login/test-login.c
++++ b/src/login/test-login.c
+@@ -99,6 +99,14 @@ int main(int argc, char* argv[]) {
+         assert_se(r >= 0);
+         printf("can do multi session = %s\n", yes_no(r));
+ 
++        r = sd_seat_can_tty(seat);
++        assert_se(r >= 0);
++        printf("can do tty = %s\n", yes_no(r));
++
++        r = sd_seat_can_graphical(seat);
++        assert_se(r >= 0);
++        printf("can do graphical = %s\n", yes_no(r));
++
+         assert_se(sd_uid_get_state(u, &state) >= 0);
+         printf("state = %s\n", state);
+ 
+diff --git a/src/systemd/sd-login.h b/src/systemd/sd-login.h
+index 1d5b657..a06f506 100644
+--- a/src/systemd/sd-login.h
++++ b/src/systemd/sd-login.h
+@@ -117,6 +117,12 @@ int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uid, unsign
+ /* Return whether the seat is multi-session capable */
+ int sd_seat_can_multi_session(const char *seat);
+ 
++/* Return whether the seat is TTY capable, i.e. suitable for showing console UIs */
++int sd_seat_can_tty(const char *seat);
++
++/* Return whether the seat is graphics capable, i.e. suitable for showing graphical UIs */
++int sd_seat_can_graphical(const char *seat);
++
+ /* Get all seats, store in *seats. Returns the number of seats. If
+  * seats is NULL only returns number of seats. */
+ int sd_get_seats(char ***seats);
diff --git a/0436-preset-don-t-look-for-preset-files-in-lib-unless-usr.patch b/0436-preset-don-t-look-for-preset-files-in-lib-unless-usr.patch
new file mode 100644
index 0000000..f5b1a11
--- /dev/null
+++ b/0436-preset-don-t-look-for-preset-files-in-lib-unless-usr.patch
@@ -0,0 +1,25 @@
+From 83f9dbb9420b01be546b0255ac19d44785d93b37 Mon Sep 17 00:00:00 2001
+From: Lennart Poettering <lennart at poettering.net>
+Date: Thu, 21 Jun 2012 23:22:53 +0200
+Subject: [PATCH] preset: don't look for preset files in /lib unless /usr is
+ split off (cherry picked from commit
+ b4bdfefac3fcf633aa0700a981d854cc49a9725b)
+
+---
+ src/shared/install.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/src/shared/install.c b/src/shared/install.c
+index 2104c30..f443578 100644
+--- a/src/shared/install.c
++++ b/src/shared/install.c
+@@ -1685,7 +1685,9 @@ int unit_file_query_preset(UnitFileScope scope, const char *name) {
+                                     "/etc/systemd/system.preset",
+                                     "/usr/local/lib/systemd/system.preset",
+                                     "/usr/lib/systemd/system.preset",
++#ifdef HAVE_SPLIT_USR
+                                     "/lib/systemd/system.preset",
++#endif
+                                     NULL);
+         else if (scope == UNIT_FILE_GLOBAL)
+                 r = conf_files_list(&files, ".preset",
diff --git a/0437-service-fix-incorrect-argument.patch b/0437-service-fix-incorrect-argument.patch
new file mode 100644
index 0000000..03ec1b3
--- /dev/null
+++ b/0437-service-fix-incorrect-argument.patch
@@ -0,0 +1,25 @@
+From e716eded2648e024a109511b8fa0bb5fd49ae2b2 Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 26 Jun 2012 11:32:30 +0200
+Subject: [PATCH] service: fix incorrect argument
+
+The last argument to service_enter_dead() is bool allow_restart, not
+a service result.
+(cherry picked from commit e201a0384da94f57f65c951a97d8ddaf990d6240)
+---
+ src/core/service.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index c5a6df6..55a20e0 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -3228,7 +3228,7 @@ static void service_cgroup_notify_event(Unit *u) {
+         case SERVICE_FINAL_SIGTERM:
+         case SERVICE_FINAL_SIGKILL:
+                 if (main_pid_good(s) <= 0 && !control_pid_good(s))
+-                        service_enter_dead(s, SERVICE_SUCCESS, SERVICE_SUCCESS);
++                        service_enter_dead(s, SERVICE_SUCCESS, true);
+ 
+                 break;
+ 
diff --git a/0438-service-pass-via-FAILED-DEAD-before-going-to-AUTO_RE.patch b/0438-service-pass-via-FAILED-DEAD-before-going-to-AUTO_RE.patch
new file mode 100644
index 0000000..ca35006
--- /dev/null
+++ b/0438-service-pass-via-FAILED-DEAD-before-going-to-AUTO_RE.patch
@@ -0,0 +1,58 @@
+From 00da183d99c9a310266e8eb5ed4b9b3ef87e484f Mon Sep 17 00:00:00 2001
+From: Michal Schmidt <mschmidt at redhat.com>
+Date: Tue, 26 Jun 2012 11:42:52 +0200
+Subject: [PATCH] service: pass via FAILED/DEAD before going to AUTO_RESTART
+
+With misconfigured mysql, which uses Restart=always, the following two
+messages would loop indefinitely and the "systemctl start" would never
+finish:
+  Job pending for unit, delaying automatic restart.
+  mysqld.service holdoff time over, scheduling restart.
+
+In service_enter_dead() always set the state to SERVICE_FAILED/DEAD first
+before setting SERVICE_AUTO_RESTART. This is to allow running jobs to
+complete. OnFailure will be also triggered at this point, so there's no
+need to do it again from service_stop() (where it was added in commit
+f0c7b229).
+
+Note that OnFailure units should better trigger only after giving up
+auto-restarting, but that's for another patch to solve.
+
+https://bugzilla.redhat.com/show_bug.cgi?id=832039
+(cherry picked from commit 0c7f15b3a95c3596a4756de5c44eb1fdcd0034fc)
+---
+ src/core/service.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/core/service.c b/src/core/service.c
+index 55a20e0..ef37a5a 100644
+--- a/src/core/service.c
++++ b/src/core/service.c
+@@ -1889,6 +1889,8 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
+         if (f != SERVICE_SUCCESS)
+                 s->result = f;
+ 
++        service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
++
+         if (allow_restart &&
+             !s->forbid_restart &&
+             (s->restart == SERVICE_RESTART_ALWAYS ||
+@@ -1902,8 +1904,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
+                         goto fail;
+ 
+                 service_set_state(s, SERVICE_AUTO_RESTART);
+-        } else
+-                service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
++        }
+ 
+         s->forbid_restart = false;
+ 
+@@ -2510,7 +2511,7 @@ static int service_stop(Unit *u) {
+ 
+         /* A restart will be scheduled or is in progress. */
+         if (s->state == SERVICE_AUTO_RESTART) {
+-                service_enter_dead(s, SERVICE_SUCCESS, false);
++                service_set_state(s, SERVICE_DEAD);
+                 return 0;
+         }
+ 
diff --git a/systemd.spec b/systemd.spec
index bd5b04c..d88820a 100644
--- a/systemd.spec
+++ b/systemd.spec
@@ -3,7 +3,7 @@
 Name:           systemd
 Url:            http://www.freedesktop.org/wiki/Software/systemd
 Version:        44
-Release:        16%{?gitcommit:.git%{gitcommit}}%{?dist}
+Release:        17%{?gitcommit:.git%{gitcommit}}%{?dist}
 License:        GPLv2+
 Group:          System Environment/Base
 Summary:        A System and Service Manager
@@ -490,6 +490,14 @@ Patch0427:      0427-journal-fix-SD_JOURNAL_SYSTEM_ONLY-flag.patch
 Patch0428:      0428-journal-rotate-on-SIGUSR2.patch
 Patch0429:      0429-journal-fix-monotonic-seeking.patch
 Patch0430:      0430-systemd-return-error-when-asked-to-stop-unknown-unit.patch
+Patch0431:      0431-F17-Temporarily-revert-systemd-return-error-when-ask.patch
+Patch0432:      0432-logind-expose-CanGraphical-and-CanTTY-properties-on-.patch
+Patch0433:      0433-logind-introduce-a-state-for-session-being-one-of-on.patch
+Patch0434:      0434-man-document-new-sd_session_get_state-call.patch
+Patch0435:      0435-login-wrap-CanTTY-and-CanGraphical-seat-attributes-i.patch
+Patch0436:      0436-preset-don-t-look-for-preset-files-in-lib-unless-usr.patch
+Patch0437:      0437-service-fix-incorrect-argument.patch
+Patch0438:      0438-service-pass-via-FAILED-DEAD-before-going-to-AUTO_RE.patch
 
 # For sysvinit tools
 Obsoletes:      SysVinit < 2.86-24, sysvinit < 2.86-24
@@ -511,8 +519,8 @@ Obsoletes:      systemd < 38-5
 # old nfs-server.service forked daemons from ExecStartPre/Post:
 Conflicts:      nfs-utils < 1:1.2.6
 # usage of 'systemctl stop' on a non-existent unit in ExecStartPre:
-Conflicts:      rsyslog < 5.8.10-2
-Conflicts:      syslog-ng < 3.2.5-15
+#Conflicts:      rsyslog < 5.8.10-2
+#Conflicts:      syslog-ng < 3.2.5-15
 
 %description
 systemd is a system and service manager for Linux, compatible with
@@ -654,6 +662,11 @@ ln -s loginctl %{buildroot}%{_bindir}/systemd-loginctl
 ln -s journalctl %{buildroot}%{_bindir}/systemd-journalctl
 ln -s systemctl %{buildroot}%{_bindir}/systemd-systemctl
 
+# Short-term workaround for bz#834118 - s390(x) have no VTs
+%ifarch s390 s390x
+find %{buildroot}%{_prefix}/lib -name '*vconsole*' -delete
+%endif
+
 %post
 /sbin/ldconfig
 /usr/bin/systemd-machine-id-setup > /dev/null 2>&1 || :
@@ -870,6 +883,12 @@ mv /etc/systemd/system/default.target.save /etc/systemd/system/default.target >/
 %{_bindir}/systemd-analyze
 
 %changelog
+* Tue Jun 26 2012 Michal Schmidt <mschmidt at redhat.com> - 44-17
+- Temporarily revert patch for #732874 until the syslog units are fixed.
+- logind improvements (CanTTY, CanGraphical, 'closing' session state).
+- Fix for auto-restart (#832039).
+- Don't ship systemd-vconsole-setup on S390(x) (workaround for #834118).
+
 * Wed Jun 20 2012 Michal Schmidt <mschmidt at redhat.com> - 44-16
 - Add conflicts with syslog units that do unprotected 'systemctl stop' on
   a non-existent unit in their ExecStartPre.


More information about the scm-commits mailing list