[systemd-commits] 2 commits - src/shared src/systemctl

Lennart Poettering lennart at kemper.freedesktop.org
Mon Mar 10 20:46:51 PDT 2014


 src/shared/util.c         |   24 ++++++++++++++++--------
 src/shared/util.h         |   15 +++++++++++++++
 src/systemctl/systemctl.c |   35 ++++++++++++++++++++++++-----------
 3 files changed, 55 insertions(+), 19 deletions(-)

New commits:
commit f39d4a08e746e703d562076a0f622eb91dbdcd3e
Author: Harald Hoyer <harald at redhat.com>
Date:   Thu Mar 6 16:35:02 2014 +0100

    systemctl: for switch-root check, if we switch to a systemd init
    
    If "systemctl switch-root" is called with a specific "INIT" or
    /proc/cmdline contains "init=", then systemd would not serialize
    itsself.
    
    Let systemctl check, if the new init is in the standard systemd
    installation path and if so, clear the INIT parameter,
    to let systemd serialize itsself.

diff --git a/src/shared/util.h b/src/shared/util.h
index 11d2866..cc52ae7 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -813,6 +813,19 @@ int unlink_noerrno(const char *path);
                 _c_;                                    \
         })
 
+#define strappenda3(a, b, c)                                    \
+        ({                                                      \
+                const char *_a_ = (a), *_b_ = (b), *_c_ = (c);  \
+                char *_d_;                                      \
+                size_t _x_, _y_, _z_;                           \
+                _x_ = strlen(_a_);                              \
+                _y_ = strlen(_b_);                              \
+                _z_ = strlen(_c_);                              \
+                _d_ = alloca(_x_ + _y_ + _z_ + 1);              \
+                strcpy(stpcpy(stpcpy(_d_, _a_), _b_), _c_);     \
+                _d_;                                            \
+        })
+
 #define procfs_file_alloca(pid, field)                                  \
         ({                                                              \
                 pid_t _pid_ = (pid);                                    \
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index f395265..17ad7f0 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -4282,8 +4282,8 @@ static int show_environment(sd_bus *bus, char **args) {
 
 static int switch_root(sd_bus *bus, char **args) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        _cleanup_free_ char *init = NULL;
-        const char *root;
+        _cleanup_free_ char *cmdline_init = NULL;
+        const char *root, *init;
         unsigned l;
         int r;
 
@@ -4296,20 +4296,33 @@ static int switch_root(sd_bus *bus, char **args) {
         root = args[1];
 
         if (l >= 3)
-                init = strdup(args[2]);
+                init = args[2];
         else {
-                parse_env_file("/proc/cmdline", WHITESPACE,
-                               "init", &init,
-                               NULL);
+                r = parse_env_file("/proc/cmdline", WHITESPACE,
+                                   "init", &cmdline_init,
+                                   NULL);
+                if (r < 0)
+                        log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
 
-                if (!init)
-                        init = strdup("");
+                init = cmdline_init;
         }
 
-        if (!init)
-                return log_oom();
+        if (isempty(init))
+                init = NULL;
+
+        if (init) {
+                const char *root_systemd_path = NULL, *root_init_path = NULL;
+
+                root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
+                root_init_path = strappenda3(root, "/", init);
+
+                /* If the passed init is actually the same as the
+                 * systemd binary, then let's suppress it. */
+                if (files_same(root_init_path, root_systemd_path) > 0)
+                        init = NULL;
+        }
 
-        log_debug("switching root - root: %s; init: %s", root, init);
+        log_debug("Switching root - root: %s; init: %s", root, strna(init));
 
         r = sd_bus_call_method(
                         bus,

commit 9d9951a460a90ef0e1e0384742cefdcf85193f8c
Author: Harald Hoyer <harald at redhat.com>
Date:   Thu Mar 6 09:12:57 2014 +0100

    util: add files_same() helper function
    
    files_same() returns
         1, if the files are the same
         0, if the files have different inode/dev numbers
     errno, for any stat error

diff --git a/src/shared/util.c b/src/shared/util.c
index d28caae..10f113b 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -3198,19 +3198,27 @@ bool on_tty(void) {
         return cached_on_tty;
 }
 
-int running_in_chroot(void) {
-        struct stat a = {}, b = {};
+int files_same(const char *filea, const char *fileb) {
+        struct stat a, b;
 
-        /* Only works as root */
-        if (stat("/proc/1/root", &a) < 0)
+        if (stat(filea, &a) < 0)
                 return -errno;
 
-        if (stat("/", &b) < 0)
+        if (stat(fileb, &b) < 0)
                 return -errno;
 
-        return
-                a.st_dev != b.st_dev ||
-                a.st_ino != b.st_ino;
+        return a.st_dev == b.st_dev &&
+               a.st_ino == b.st_ino;
+}
+
+int running_in_chroot(void) {
+        int ret;
+
+        ret = files_same("/proc/1/root", "/");
+        if (ret < 0)
+                return ret;
+
+        return ret == 0;
 }
 
 static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
diff --git a/src/shared/util.h b/src/shared/util.h
index c2bc977..11d2866 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -451,6 +451,8 @@ static inline const char *ansi_highlight_off(void) {
         return on_tty() ? ANSI_HIGHLIGHT_OFF : "";
 }
 
+int files_same(const char *filea, const char *fileb);
+
 int running_in_chroot(void);
 
 char *ellipsize(const char *s, size_t length, unsigned percent);



More information about the systemd-commits mailing list