[systemd-commits] 12 commits - src/core src/login src/network src/shared units/console-getty.service.m4.in units/container-getty at .service.m4.in units/getty at .service.m4 units/serial-getty at .service.m4 units/systemd-networkd.service.in

Lennart Poettering lennart at kemper.freedesktop.org
Wed Dec 18 09:21:55 PST 2013


 src/core/device.c                    |   12 +---
 src/core/execute.c                   |   98 +++++++++++++++++++++++++++--------
 src/core/main.c                      |    3 -
 src/core/manager.c                   |   20 +++----
 src/core/service.c                   |   96 +++++++++++++++++-----------------
 src/core/shutdown.c                  |    1 
 src/core/umount.c                    |   42 ++++++++++-----
 src/login/logind-acl.c               |    7 +-
 src/login/logind-dbus.c              |   73 ++++++++------------------
 src/login/logind.c                   |   14 ++---
 src/login/sysfs-show.c               |   50 ++++++++---------
 src/network/networkd-manager.c       |    7 +-
 src/shared/log.c                     |   23 ++++++--
 src/shared/ptyfwd.c                  |    9 ++-
 src/shared/util.c                    |   10 +++
 src/shared/util.h                    |    2 
 units/console-getty.service.m4.in    |    2 
 units/container-getty at .service.m4.in |    2 
 units/getty at .service.m4              |    2 
 units/serial-getty at .service.m4       |    2 
 units/systemd-networkd.service.in    |    1 
 21 files changed, 279 insertions(+), 197 deletions(-)

New commits:
commit e7d43b3cc30764138c90eaaf95d3d8f49e448890
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 18:14:10 2013 +0100

    ptyfwd: make master terminal attributes raw, too

diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 72aa59e..85fc8f1 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -343,8 +343,8 @@ static int process_pty_loop(int master, sigset_t *mask, pid_t kill_pid, int sign
 int process_pty(int master, sigset_t *mask, pid_t kill_pid, int signo) {
         struct termios saved_stdin_attr, raw_stdin_attr;
         struct termios saved_stdout_attr, raw_stdout_attr;
-        bool saved_stdin = false;
-        bool saved_stdout = false;
+        struct termios master_attr;
+        bool saved_stdin = false, saved_stdout = false;
         struct winsize ws;
         int r;
 
@@ -369,6 +369,11 @@ int process_pty(int master, sigset_t *mask, pid_t kill_pid, int signo) {
                 tcsetattr(STDOUT_FILENO, TCSANOW, &raw_stdout_attr);
         }
 
+        if (tcgetattr(master, &master_attr) >= 0) {
+                cfmakeraw(&master_attr);
+                tcsetattr(master, TCSANOW, &master_attr);
+        }
+
         r = process_pty_loop(master, mask, kill_pid, signo);
 
         if (saved_stdout)

commit ccf22d4a104e6ed2666d6c5b4031981a84787790
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 17:48:31 2013 +0100

    units: when spawning a getty configure TERM explicitly
    
    This way we can make use of our logic to automatically determine an
    appropriate TERM for a specific tty.

diff --git a/units/console-getty.service.m4.in b/units/console-getty.service.m4.in
index 464732c..8ac51a4 100644
--- a/units/console-getty.service.m4.in
+++ b/units/console-getty.service.m4.in
@@ -15,7 +15,7 @@ After=rc-local.service
 Before=getty.target
 
 [Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600
+ExecStart=-/sbin/agetty --noclear --keep-baud console 115200,38400,9600 $TERM
 Type=idle
 Restart=always
 RestartSec=0
diff --git a/units/container-getty at .service.m4.in b/units/container-getty at .service.m4.in
index abc58cb..4f7794b 100644
--- a/units/container-getty at .service.m4.in
+++ b/units/container-getty at .service.m4.in
@@ -16,7 +16,7 @@ Before=getty.target
 IgnoreOnIsolate=yes
 
 [Service]
-ExecStart=-/sbin/agetty --noclear --keep-baud pts/%I 115200,38400,9600
+ExecStart=-/sbin/agetty --noclear --keep-baud pts/%I 115200,38400,9600 $TERM
 Type=idle
 Restart=always
 RestartSec=0
diff --git a/units/getty at .service.m4 b/units/getty at .service.m4
index 253da85..aa853b8 100644
--- a/units/getty at .service.m4
+++ b/units/getty at .service.m4
@@ -27,7 +27,7 @@ ConditionPathExists=/dev/tty0
 
 [Service]
 # the VT is cleared by TTYVTDisallocate
-ExecStart=-/sbin/agetty --noclear %I
+ExecStart=-/sbin/agetty --noclear %I $TERM
 Type=idle
 Restart=always
 RestartSec=0
diff --git a/units/serial-getty at .service.m4 b/units/serial-getty at .service.m4
index e32c6b7..0e612bb 100644
--- a/units/serial-getty at .service.m4
+++ b/units/serial-getty at .service.m4
@@ -22,7 +22,7 @@ Before=getty.target
 IgnoreOnIsolate=yes
 
 [Service]
-ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600
+ExecStart=-/sbin/agetty --keep-baud %I 115200,38400,9600 $TERM
 Type=idle
 Restart=always
 RestartSec=0

commit 7cae38c4fa51a56cd13ff028278efe7fae3c222c
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 17:41:16 2013 +0100

    execute: set TERM even if we don't open the tty on our own
    
    This way, when a tty path is configured TERM is set, which is nice to
    set a useful term for gettys.

diff --git a/src/core/execute.c b/src/core/execute.c
index 5abc69d..4265717 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1017,6 +1017,81 @@ static void do_idle_pipe_dance(int idle_pipe[4]) {
                 close_nointr_nofail(idle_pipe[3]);
 }
 
+static int build_environment(
+                ExecContext *c,
+                unsigned n_fds,
+                const char *home,
+                const char *username,
+                const char *shell,
+                char ***ret) {
+
+        _cleanup_strv_free_ char **our_env = NULL;
+        unsigned n_env = 0;
+        char *x;
+
+        assert(c);
+        assert(ret);
+
+        our_env = new(char*, 8);
+        if (!our_env)
+                return -ENOMEM;
+
+        if (n_fds > 0) {
+                if (asprintf(&x, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+
+                if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+        }
+
+        if (home) {
+                x = strappend("HOME=", home);
+                if (!x)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+        }
+
+        if (username) {
+                x = strappend("LOGNAME=", username);
+                if (!x)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+
+                x = strappend("USER=", username);
+                if (!x)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+        }
+
+        if (shell) {
+                x = strappend("SHELL=", shell);
+                if (!x)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+        }
+
+        if (is_terminal_input(c->std_input) ||
+            c->std_output == EXEC_OUTPUT_TTY ||
+            c->std_error == EXEC_OUTPUT_TTY ||
+            c->tty_path) {
+
+                x = strdup(default_term_for_tty(tty_path(c)));
+                if (!x)
+                        return -ENOMEM;
+                our_env[n_env++] = x;
+        }
+
+        our_env[n_env++] = NULL;
+        assert(n_env <= 8);
+
+        *ret = our_env;
+        our_env = NULL;
+
+        return 0;
+}
+
 int exec_spawn(ExecCommand *command,
                char **argv,
                ExecContext *context,
@@ -1089,7 +1164,7 @@ int exec_spawn(ExecCommand *command,
         if (pid == 0) {
                 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
                 const char *username = NULL, *home = NULL, *shell = NULL;
-                unsigned n_dont_close = 0, n_env = 0;
+                unsigned n_dont_close = 0;
                 int dont_close[n_fds + 3];
                 uid_t uid = (uid_t) -1;
                 gid_t gid = (gid_t) -1;
@@ -1485,29 +1560,12 @@ int exec_spawn(ExecCommand *command,
                         }
                 }
 
-                our_env = new(char*, 8);
-                if (!our_env ||
-                    (n_fds > 0 && (
-                            asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
-                            asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0)) ||
-                    (home && asprintf(our_env + n_env++, "HOME=%s", home) < 0) ||
-                    (username && (
-                            asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
-                            asprintf(our_env + n_env++, "USER=%s", username) < 0)) ||
-                    (shell && asprintf(our_env + n_env++, "SHELL=%s", shell) < 0) ||
-                    ((is_terminal_input(context->std_input) ||
-                      context->std_output == EXEC_OUTPUT_TTY ||
-                      context->std_error == EXEC_OUTPUT_TTY) && (
-                              !(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))))) {
-
-                        err = -ENOMEM;
+                err = build_environment(context, n_fds, home, username, shell, &our_env);
+                if (r < 0) {
                         r = EXIT_MEMORY;
                         goto fail_child;
                 }
 
-                our_env[n_env++] = NULL;
-                assert(n_env <= 8);
-
                 final_env = strv_env_merge(5,
                                            environment,
                                            our_env,

commit ddae67fa1bdd86b480a60ad6fc1d90d6f35a03d0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 17:16:33 2013 +0100

    loginctl: when showing device tree of seats with no devices show something useful

diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index 3286411..939bd61 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -179,6 +179,8 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
         first = udev_enumerate_get_list_entry(e);
         if (first)
                 show_sysfs_one(udev, seat, &first, "/", prefix, n_columns);
+        else
+                printf("%s%s%s\n", prefix, draw_special_char(DRAW_TREE_RIGHT), "(none)");
 
         return r;
 }

commit 06acf2d46a38bec212d78094e6ef8b100679048a
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 17:13:42 2013 +0100

    core,logind: libudev usage modernizations
    
    Always use cleanup logic and don't eat up errors returned by libudev

diff --git a/src/core/umount.c b/src/core/umount.c
index e7460cb..30111be 100644
--- a/src/core/umount.c
+++ b/src/core/umount.c
@@ -202,9 +202,10 @@ finish:
 }
 
 static int loopback_list_get(MountPoint **head) {
-        _cleanup_udev_unref_ struct udev *udev;
         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        int r;
 
         assert(head);
 
@@ -216,13 +217,21 @@ static int loopback_list_get(MountPoint **head) {
         if (!e)
                 return -ENOMEM;
 
-        if (udev_enumerate_add_match_subsystem(e, "block") < 0 ||
-            udev_enumerate_add_match_sysname(e, "loop*") < 0 ||
-            udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL) < 0)
-                return -EIO;
+        r = udev_enumerate_add_match_subsystem(e, "block");
+        if (r < 0)
+                return r;
+
+        r = udev_enumerate_add_match_sysname(e, "loop*");
+        if (r < 0)
+                return r;
 
-        if (udev_enumerate_scan_devices(e) < 0)
-                return -EIO;
+        r = udev_enumerate_add_match_sysattr(e, "loop/backing_file", NULL);
+        if (r < 0)
+                return r;
+
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
@@ -257,9 +266,10 @@ static int loopback_list_get(MountPoint **head) {
 }
 
 static int dm_list_get(MountPoint **head) {
-        _cleanup_udev_unref_ struct udev *udev;
         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *item = NULL, *first = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
+        int r;
 
         assert(head);
 
@@ -271,15 +281,19 @@ static int dm_list_get(MountPoint **head) {
         if (!e)
                 return -ENOMEM;
 
-        if (udev_enumerate_add_match_subsystem(e, "block") < 0 ||
-            udev_enumerate_add_match_sysname(e, "dm-*") < 0)
-                return -EIO;
+        r = udev_enumerate_add_match_subsystem(e, "block");
+        if (r < 0)
+                return r;
+
+        r = udev_enumerate_add_match_sysname(e, "dm-*");
+        if (r < 0)
+                return r;
 
-        if (udev_enumerate_scan_devices(e) < 0)
-                return -EIO;
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
-
         udev_list_entry_foreach(item, first) {
                 MountPoint *m;
                 _cleanup_udev_device_unref_ struct udev_device *d;
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c
index 2568eb0..d4f95f5 100644
--- a/src/login/logind-dbus.c
+++ b/src/login/logind-dbus.c
@@ -42,6 +42,7 @@
 #include "bus-error.h"
 #include "logind.h"
 #include "bus-errors.h"
+#include "udev-util.h"
 
 static int property_get_idle_hint(
                 sd_bus *bus,
@@ -1059,29 +1060,25 @@ static int method_set_user_linger(sd_bus *bus, sd_bus_message *message, void *us
 }
 
 static int trigger_device(Manager *m, struct udev_device *d) {
-        struct udev_enumerate *e;
+        _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
         struct udev_list_entry *first, *item;
         int r;
 
         assert(m);
 
         e = udev_enumerate_new(m->udev);
-        if (!e) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (!e)
+                return -ENOMEM;
 
         if (d) {
-                if (udev_enumerate_add_match_parent(e, d) < 0) {
-                        r = -EIO;
-                        goto finish;
-                }
+                r = udev_enumerate_add_match_parent(e, d);
+                if (r < 0)
+                        return r;
         }
 
-        if (udev_enumerate_scan_devices(e) < 0) {
-                r = -EIO;
-                goto finish;
-        }
+        r = udev_enumerate_scan_devices(e);
+        if (r < 0)
+                return r;
 
         first = udev_enumerate_get_list_entry(e);
         udev_list_entry_foreach(item, first) {
@@ -1091,27 +1088,19 @@ static int trigger_device(Manager *m, struct udev_device *d) {
                 p = udev_list_entry_get_name(item);
 
                 t = strappend(p, "/uevent");
-                if (!t) {
-                        r = -ENOMEM;
-                        goto finish;
-                }
+                if (!t)
+                        return -ENOMEM;
 
                 write_string_file(t, "change");
         }
 
-        r = 0;
-
-finish:
-        if (e)
-                udev_enumerate_unref(e);
-
-        return r;
+        return 0;
 }
 
 static int attach_device(Manager *m, const char *seat, const char *sysfs) {
+        _cleanup_udev_device_unref_ struct udev_device *d = NULL;
         _cleanup_free_ char *rule = NULL, *file = NULL;
         const char *id_for_seat;
-        struct udev_device *d;
         int r;
 
         assert(m);
@@ -1122,40 +1111,26 @@ static int attach_device(Manager *m, const char *seat, const char *sysfs) {
         if (!d)
                 return -ENODEV;
 
-        if (!udev_device_has_tag(d, "seat")) {
-                r = -ENODEV;
-                goto finish;
-        }
+        if (!udev_device_has_tag(d, "seat"))
+                return -ENODEV;
 
         id_for_seat = udev_device_get_property_value(d, "ID_FOR_SEAT");
-        if (!id_for_seat) {
-                r = -ENODEV;
-                goto finish;
-        }
+        if (!id_for_seat)
+                return -ENODEV;
 
-        if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (asprintf(&file, "/etc/udev/rules.d/72-seat-%s.rules", id_for_seat) < 0)
+                return -ENOMEM;
 
-        if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0) {
-                r = -ENOMEM;
-                goto finish;
-        }
+        if (asprintf(&rule, "TAG==\"seat\", ENV{ID_FOR_SEAT}==\"%s\", ENV{ID_SEAT}=\"%s\"", id_for_seat, seat) < 0)
+                return -ENOMEM;
 
         mkdir_p_label("/etc/udev/rules.d", 0755);
         label_init("/etc");
         r = write_string_file_atomic_label(file, rule);
         if (r < 0)
-                goto finish;
-
-        r = trigger_device(m, d);
-
-finish:
-        if (d)
-                udev_device_unref(d);
+                return r;
 
-        return r;
+        return trigger_device(m, d);
 }
 
 static int flush_devices(Manager *m) {
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index 05cb787..3286411 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -42,10 +42,10 @@ static int show_sysfs_one(
         assert(prefix);
 
         while (*item) {
+                _cleanup_udev_device_unref_ struct udev_device *d = NULL;
                 struct udev_list_entry *next, *lookahead;
-                struct udev_device *d;
                 const char *sn, *name, *sysfs, *subsystem, *sysname;
-                char *l, *k;
+                _cleanup_free_ char *k = NULL, *l = NULL;
                 bool is_master;
 
                 sysfs = udev_list_entry_get_name(*item);
@@ -64,7 +64,6 @@ static int show_sysfs_one(
 
                 /* Explicitly also check for tag 'seat' here */
                 if (!streq(seat, sn) || !udev_device_has_tag(d, "seat")) {
-                        udev_device_unref(d);
                         *item = udev_list_entry_get_next(*item);
                         continue;
                 }
@@ -86,21 +85,17 @@ static int show_sysfs_one(
 
                         if (path_startswith(lookahead_sysfs, sub) &&
                             !path_startswith(lookahead_sysfs, sysfs)) {
-                                struct udev_device *lookahead_d;
+                                _cleanup_udev_device_unref_ struct udev_device *lookahead_d = NULL;
 
                                 lookahead_d = udev_device_new_from_syspath(udev, lookahead_sysfs);
                                 if (lookahead_d) {
                                         const char *lookahead_sn;
-                                        bool found;
 
                                         lookahead_sn = udev_device_get_property_value(d, "ID_SEAT");
                                         if (isempty(lookahead_sn))
                                                 lookahead_sn = "seat0";
 
-                                        found = streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat");
-                                        udev_device_unref(lookahead_d);
-
-                                        if (found)
+                                        if (streq(seat, lookahead_sn) && udev_device_has_tag(lookahead_d, "seat"))
                                                 break;
                                 }
                         }
@@ -109,43 +104,43 @@ static int show_sysfs_one(
                 }
 
                 k = ellipsize(sysfs, n_columns, 20);
-                printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT),
-                                   k ? k : sysfs);
-                free(k);
+                if (!k)
+                        return -ENOMEM;
+
+                printf("%s%s%s\n", prefix, draw_special_char(lookahead ? DRAW_TREE_BRANCH : DRAW_TREE_RIGHT), k);
 
                 if (asprintf(&l,
                              "%s%s:%s%s%s%s",
                              is_master ? "[MASTER] " : "",
                              subsystem, sysname,
-                             name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0) {
-                        udev_device_unref(d);
+                             name ? " \"" : "", name ? name : "", name ? "\"" : "") < 0)
                         return -ENOMEM;
-                }
 
-                k = ellipsize(l, n_columns, 70);
-                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ",
-                                   k ? k : l);
                 free(k);
-                free(l);
+                k = ellipsize(l, n_columns, 70);
+                if (!k)
+                        return -ENOMEM;
+
+                printf("%s%s%s\n", prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ", k);
 
                 *item = next;
                 if (*item) {
-                        char *p;
+                        _cleanup_free_ char *p = NULL;
 
                         p = strappend(prefix, lookahead ? draw_special_char(DRAW_TREE_VERT) : "  ");
-                        show_sysfs_one(udev, seat, item, sysfs, p ? p : prefix, n_columns - 2);
-                        free(p);
-                }
+                        if (!p)
+                                return -ENOMEM;
 
-                udev_device_unref(d);
+                        show_sysfs_one(udev, seat, item, sysfs, p, n_columns - 2);
+                }
         }
 
         return 0;
 }
 
 int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
-        _cleanup_udev_unref_ struct udev *udev;
         _cleanup_udev_enumerate_unref_ struct udev_enumerate *e = NULL;
+        _cleanup_udev_unref_ struct udev *udev = NULL;
         struct udev_list_entry *first = NULL;
         int r;
 

commit e120204729764f6243b60899eb907103e678bee2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 17:12:15 2013 +0100

    core,logind,networkd: check for udev device initialization via enumeration matches
    
    Instead of checking each device after we got it, check wuth an
    enumeration filter instead, to make it more efficient.

diff --git a/src/core/device.c b/src/core/device.c
index c93c947..72d98ae 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -303,14 +303,6 @@ static int device_process_new_device(Manager *m, struct udev_device *dev) {
 
         assert(m);
 
-#if 0
-        /* FIXME: this is always false for devices received from udev_monitor */
-
-        /* Don't pick up devices before udev finished initialization for them */
-        if (!udev_device_get_is_initialized(dev))
-                return 0;
-#endif
-
         sysfs = udev_device_get_syspath(dev);
         if (!sysfs)
                 return 0;
@@ -557,6 +549,10 @@ static int device_enumerate(Manager *m) {
         if (r < 0)
                 goto fail;
 
+        r = udev_enumerate_add_match_is_initialized(e);
+        if (r < 0)
+                goto fail;
+
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
                 goto fail;
diff --git a/src/login/logind-acl.c b/src/login/logind-acl.c
index 09a6f6d..dc86f0f 100644
--- a/src/login/logind-acl.c
+++ b/src/login/logind-acl.c
@@ -210,6 +210,10 @@ int devnode_acl_all(struct udev *udev,
         if (r < 0)
                 return r;
 
+        r = udev_enumerate_add_match_is_initialized(e);
+        if (r < 0)
+                return r;
+
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
                 return r;
@@ -223,9 +227,6 @@ int devnode_acl_all(struct udev *udev,
                 if (!d)
                         return -ENOMEM;
 
-                if (!udev_device_get_is_initialized(d))
-                        continue;
-
                 sn = udev_device_get_property_value(d, "ID_SEAT");
                 if (isempty(sn))
                         sn = "seat0";
diff --git a/src/login/logind.c b/src/login/logind.c
index b97ba6d..48da7b1 100644
--- a/src/login/logind.c
+++ b/src/login/logind.c
@@ -198,6 +198,10 @@ static int manager_enumerate_devices(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = udev_enumerate_add_match_is_initialized(e);
+        if (r < 0)
+                return r;
+
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
                 return r;
@@ -211,9 +215,6 @@ static int manager_enumerate_devices(Manager *m) {
                 if (!d)
                         return -ENOMEM;
 
-                if (!udev_device_get_is_initialized(d))
-                        continue;
-
                 k = manager_process_seat_device(m, d);
                 if (k < 0)
                         r = k;
@@ -249,6 +250,10 @@ static int manager_enumerate_buttons(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = udev_enumerate_add_match_is_initialized(e);
+        if (r < 0)
+                return r;
+
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
                 return r;
@@ -262,9 +267,6 @@ static int manager_enumerate_buttons(Manager *m) {
                 if (!d)
                         return -ENOMEM;
 
-                if (!udev_device_get_is_initialized(d))
-                        continue;
-
                 k = manager_process_button_device(m, d);
                 if (k < 0)
                         r = k;
diff --git a/src/login/sysfs-show.c b/src/login/sysfs-show.c
index f7d11dd..05cb787 100644
--- a/src/login/sysfs-show.c
+++ b/src/login/sysfs-show.c
@@ -170,7 +170,10 @@ int show_sysfs(const char *seat, const char *prefix, unsigned n_columns) {
                 r = udev_enumerate_add_match_tag(e, seat);
         else
                 r = udev_enumerate_add_match_tag(e, "seat");
+        if (r < 0)
+                return r;
 
+        r = udev_enumerate_add_match_is_initialized(e);
         if (r < 0)
                 return r;
 
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index 6998562..c48c018 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -171,6 +171,10 @@ int manager_udev_enumerate_links(Manager *m) {
         if (r < 0)
                 return r;
 
+        r = udev_enumerate_add_match_is_initialized(e);
+        if (r < 0)
+                return r;
+
         r = udev_enumerate_scan_devices(e);
         if (r < 0)
                 return r;
@@ -184,9 +188,6 @@ int manager_udev_enumerate_links(Manager *m) {
                 if (!d)
                         return -ENOMEM;
 
-                if (!udev_device_get_is_initialized(d))
-                        continue;
-
                 k = manager_process_link(m, d);
                 if (k < 0)
                         r = k;

commit fa28bc2df724e4aff46d19cb7aa732cc64c71061
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 03:46:53 2013 +0100

    core: priorize notification fd processing over notification fd process via sd-event's logic

diff --git a/src/core/manager.c b/src/core/manager.c
index 6a75597..634b141 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -135,6 +135,12 @@ static int manager_setup_notify(Manager *m) {
                 return -errno;
         }
 
+        /* Process signals a bit earlier than SIGCHLD, so that we can
+         * still identify to which service an exit message belongs */
+        r = sd_event_source_set_priority(m->notify_event_source, -7);
+        if (r < 0)
+                return r;
+
         sa.un.sun_path[0] = '@';
         m->notify_socket = strdup(sa.un.sun_path);
         if (!m->notify_socket)
@@ -367,7 +373,10 @@ static int manager_setup_signals(Manager *m) {
         if (r < 0)
                 return r;
 
-        /* Process signals a bit earlier than the rest of things */
+        /* Process signals a bit earlier than the rest of things, but
+         * later that notify_fd processing, so that the notify
+         * processing can still figure out to which process/service a
+         * message belongs, before we reap the process. */
         r = sd_event_source_set_priority(m->signal_event_source, -5);
         if (r < 0)
                 return r;
@@ -1331,7 +1340,6 @@ static int manager_dispatch_sigchld(Manager *m) {
         for (;;) {
                 siginfo_t si = {};
                 Unit *u;
-                int r;
 
                 /* First we call waitd() for a PID and do not reap the
                  * zombie. That way we can still access /proc/$PID for
@@ -1357,14 +1365,6 @@ static int manager_dispatch_sigchld(Manager *m) {
                         log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
                 }
 
-                /* Let's flush any message the dying child might still
-                 * have queued for us. This ensures that the process
-                 * still exists in /proc so that we can figure out
-                 * which cgroup and hence unit it belongs to. */
-                r = manager_dispatch_notify_fd(m->notify_event_source, m->notify_fd, EPOLLIN, m);
-                if (r < 0)
-                        return r;
-
                 /* And now figure out the unit this belongs to */
                 u = hashmap_get(m->watch_pids, LONG_TO_PTR(si.si_pid));
                 if (!u)

commit 0e6eaa2d98fffa86d29a9616485b7ade5c160638
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 16:49:15 2013 +0100

    log: when we log to /dev/console and got disconnected (maybe due to vhangup) reconnect

diff --git a/src/shared/log.c b/src/shared/log.c
index 85ed6ec..b5b82f6 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -335,8 +335,25 @@ static int write_to_console(
                 IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF);
         IOVEC_SET_STRING(iovec[n++], "\n");
 
-        if (writev(console_fd, iovec, n) < 0)
-                return -errno;
+        if (writev(console_fd, iovec, n) < 0) {
+
+                if (errno == EIO && getpid() == 1) {
+
+                        /* If somebody tried to kick us from our
+                         * console tty (via vhangup() or suchlike),
+                         * try to reconnect */
+
+                        log_close_console();
+                        log_open_console();
+
+                        if (console_fd < 0)
+                                return 0;
+
+                        if (writev(console_fd, iovec, n) < 0)
+                                return -errno;
+                } else
+                        return -errno;
+        }
 
         return 1;
 }

commit 74f9e0f20368116fe09f9bf0e5eb0aba08e6ee42
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 16:45:20 2013 +0100

    units: run systemd-networkd.service only if CAP_NET_ADMIN capability is around
    
    This has the effect that systemd-networkd won't run in containers
    without network namespacing wher CAP_NET_ADMIN is (usually) not
    available. It will still run in containers with network namespacing on
    (where CAP_NET_ADMIN is usually avilable).
    
    We might remove this condition check again if networkd provides services
    to apps that also are useful in containers lacking network namespacing,
    however, as long as it doesn't it should be handled like udevd and be
    excluded in such containers.

diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
index 95205cd..c12f398 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -11,6 +11,7 @@ Documentation=man:systemd-networkd.service(8)
 DefaultDependencies=no
 Before=network.target
 Wants=network.target
+ConditionCapability=CAP_NET_ADMIN
 
 [Service]
 Type=notify

commit 220ec97ad65150542bb9c8a1ba20b19ea0d49ff8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 05:09:53 2013 +0100

    core: in a container log to /dev/console if "debug" is specified

diff --git a/src/core/main.c b/src/core/main.c
index e00d070..eac4fe6 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -417,7 +417,7 @@ static int parse_proc_cmdline_word(const char *word) {
                  * will block with every log message for for 60 seconds,
                  * before they give up. */
                 log_set_max_level(LOG_DEBUG);
-                log_set_target(LOG_TARGET_KMSG);
+                log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_CONSOLE : LOG_TARGET_KMSG);
         } else if (!in_initrd()) {
                 unsigned i;
 

commit 99f098257f5e4135609edc3df965ebf27975df18
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 05:07:34 2013 +0100

    log: don't reopen /dev/console each time we call log_open()
    
    Instead, force reopen it only if we really really have to.

diff --git a/src/core/main.c b/src/core/main.c
index eb5413e..e00d070 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1328,6 +1328,7 @@ int main(int argc, char *argv[]) {
                 /* Running inside a container, as PID 1 */
                 arg_running_as = SYSTEMD_SYSTEM;
                 log_set_target(LOG_TARGET_CONSOLE);
+                log_close_console(); /* force reopen of /dev/console */
                 log_open();
 
                 /* For the later on, see above... */
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
index 31129b7..8420a67 100644
--- a/src/core/shutdown.c
+++ b/src/core/shutdown.c
@@ -155,6 +155,7 @@ int main(int argc, char *argv[]) {
 
         log_parse_environment();
         log_set_target(LOG_TARGET_CONSOLE); /* syslog will die if not gone yet */
+        log_close_console(); /* force reopen of /dev/console */
         log_open();
 
         umask(0022);
diff --git a/src/shared/log.c b/src/shared/log.c
index 2517f5d..85ed6ec 100644
--- a/src/shared/log.c
+++ b/src/shared/log.c
@@ -272,8 +272,6 @@ int log_open(void) {
         log_close_journal();
         log_close_syslog();
 
-        /* Get the real /dev/console if we are PID=1, hence reopen */
-        log_close_console();
         return log_open_console();
 }
 

commit bf108e5541e2a3cbc6f0c59e93665eceb7a5ce05
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Dec 18 04:19:20 2013 +0100

    service: watch main pid even in final states
    
    In some circumstances, for example when start-up times out we
    immediately jump into the final state, at which point we still should
    try to watch the main pid so that the SIGCHLD allows us to quickly
    move into dead state.

diff --git a/src/core/service.c b/src/core/service.c
index 67cf630..fa47061 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -1488,7 +1488,8 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                    SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
                     SERVICE_AUTO_RESTART))
                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@@ -1496,7 +1497,9 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL)) {
+                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                    SERVICE_STOP_POST,
+                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_main_pid(s);
                 s->main_command = NULL;
         }
@@ -1504,7 +1507,8 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                    SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_control_pid(s);
                 s->control_command = NULL;
@@ -1561,22 +1565,16 @@ static int service_coldplug(Unit *u) {
 
         if (s->deserialized_state != s->state) {
 
-                if (s->deserialized_state == SERVICE_START_PRE ||
-                    s->deserialized_state == SERVICE_START ||
-                    s->deserialized_state == SERVICE_START_POST ||
-                    s->deserialized_state == SERVICE_RELOAD ||
-                    s->deserialized_state == SERVICE_STOP ||
-                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
-                    s->deserialized_state == SERVICE_STOP_SIGKILL ||
-                    s->deserialized_state == SERVICE_STOP_POST ||
-                    s->deserialized_state == SERVICE_FINAL_SIGTERM ||
-                    s->deserialized_state == SERVICE_FINAL_SIGKILL) {
+                if (IN_SET(s->deserialized_state,
+                           SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
+                           SERVICE_RELOAD,
+                           SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                           SERVICE_STOP_POST,
+                           SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
 
                         usec_t k;
 
-                        k = s->deserialized_state == SERVICE_START_PRE || s->deserialized_state == SERVICE_START ||
-                                s->deserialized_state == SERVICE_START_POST || s->deserialized_state == SERVICE_RELOAD ?
-                                s->timeout_start_usec : s->timeout_stop_usec;
+                        k = IN_SET(s->deserialized_state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD) ? s->timeout_start_usec : s->timeout_stop_usec;
 
                         /* For the start/stop timeouts 0 means off */
                         if (k > 0) {
@@ -1594,38 +1592,30 @@ static int service_coldplug(Unit *u) {
                                 return r;
                 }
 
-                if ((s->deserialized_state == SERVICE_START &&
-                     (s->type == SERVICE_FORKING ||
-                      s->type == SERVICE_DBUS ||
-                      s->type == SERVICE_ONESHOT ||
-                      s->type == SERVICE_NOTIFY)) ||
-                    s->deserialized_state == SERVICE_START_POST ||
-                    s->deserialized_state == SERVICE_RUNNING ||
-                    s->deserialized_state == SERVICE_RELOAD ||
-                    s->deserialized_state == SERVICE_STOP ||
-                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
-                    s->deserialized_state == SERVICE_STOP_SIGKILL)
-                        if (s->main_pid > 0) {
-                                r = unit_watch_pid(UNIT(s), s->main_pid);
-                                if (r < 0)
-                                        return r;
-                        }
+                if (pid_valid(s->main_pid) &&
+                    ((s->deserialized_state == SERVICE_START && IN_SET(s->type, SERVICE_FORKING, SERVICE_DBUS, SERVICE_ONESHOT, SERVICE_NOTIFY)) ||
+                     IN_SET(s->deserialized_state,
+                            SERVICE_START, SERVICE_START_POST,
+                            SERVICE_RUNNING, SERVICE_RELOAD,
+                            SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                            SERVICE_STOP_POST,
+                            SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
+                        r = unit_watch_pid(UNIT(s), s->main_pid);
+                        if (r < 0)
+                                return r;
+                }
 
-                if (s->deserialized_state == SERVICE_START_PRE ||
-                    s->deserialized_state == SERVICE_START ||
-                    s->deserialized_state == SERVICE_START_POST ||
-                    s->deserialized_state == SERVICE_RELOAD ||
-                    s->deserialized_state == SERVICE_STOP ||
-                    s->deserialized_state == SERVICE_STOP_SIGTERM ||
-                    s->deserialized_state == SERVICE_STOP_SIGKILL ||
-                    s->deserialized_state == SERVICE_STOP_POST ||
-                    s->deserialized_state == SERVICE_FINAL_SIGTERM ||
-                    s->deserialized_state == SERVICE_FINAL_SIGKILL)
-                        if (s->control_pid > 0) {
-                                r = unit_watch_pid(UNIT(s), s->control_pid);
-                                if (r < 0)
-                                        return r;
-                        }
+                if (pid_valid(s->control_pid) &&
+                    IN_SET(s->deserialized_state,
+                           SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
+                           SERVICE_RELOAD,
+                           SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
+                           SERVICE_STOP_POST,
+                           SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
+                        r = unit_watch_pid(UNIT(s), s->control_pid);
+                        if (r < 0)
+                                return r;
+                }
 
                 if (IN_SET(s->deserialized_state, SERVICE_START_POST, SERVICE_RUNNING, SERVICE_RELOAD))
                         service_start_watchdog(s);
@@ -3022,6 +3012,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                 /* If there is still a control process, wait for that first */
                                 break;
 
+                        case SERVICE_STOP_POST:
+                        case SERVICE_FINAL_SIGTERM:
+                        case SERVICE_FINAL_SIGKILL:
+
+                                if (!control_pid_good(s))
+                                        service_enter_dead(s, f, true);
+                                break;
+
                         default:
                                 assert_not_reached("Uh, main process died at wrong time.");
                         }
@@ -3163,7 +3161,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                         case SERVICE_STOP_POST:
                         case SERVICE_FINAL_SIGTERM:
                         case SERVICE_FINAL_SIGKILL:
-                                service_enter_dead(s, f, true);
+                                if (main_pid_good(s) <= 0)
+                                        service_enter_dead(s, f, true);
                                 break;
 
                         default:
@@ -3327,6 +3326,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
 
                 break;
 
+        case SERVICE_STOP_POST:
         case SERVICE_FINAL_SIGTERM:
         case SERVICE_FINAL_SIGKILL:
                 if (main_pid_good(s) <= 0 && !control_pid_good(s))
diff --git a/src/shared/util.c b/src/shared/util.c
index 2cf9fbe..f598971 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6088,3 +6088,13 @@ int namespace_enter(int pidns_fd, int mntns_fd, int root_fd) {
 
         return 0;
 }
+
+bool pid_valid(pid_t pid) {
+        if (pid <= 0)
+                return false;
+
+        if (kill(pid, 0) >= 0)
+                return true;
+
+        return errno != ESRCH;
+}
diff --git a/src/shared/util.h b/src/shared/util.h
index ddb3518..3e0a6d5 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -804,3 +804,5 @@ int container_get_leader(const char *machine, pid_t *pid);
 
 int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *root_fd);
 int namespace_enter(int pidns_fd, int mntns_fd, int root_fd);
+
+bool pid_valid(pid_t pid);



More information about the systemd-commits mailing list