chiark / gitweb /
sd-booted: update sd_booted() check a bit
authorLennart Poettering <lennart@poettering.net>
Fri, 15 Mar 2013 15:41:40 +0000 (16:41 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 15 Mar 2013 15:49:08 +0000 (16:49 +0100)
Previously we were testing whether /sys/fs/cgroup/systemd/ was a mount
point. This might be problematic however, when the cgroup trees are bind
mounted into a container from the host (which should be absolutely
valid), which might create the impression that the container was running
systemd, but only the host actually is.

Replace this by a check for the existance of the directory
/run/systemd/system/, which should work unconditionally, since /run can
never be a bind mount but *must* be a tmpfs on systemd systems, which is
flushed at boots. This means that data in /run always reflects
information about the current boot, and only of the local container,
which makes it the perfect choice for a check like this.

(As side effect this is nice to Ubuntu people who now use logind with
the systemd cgroup hierarchy, where the old sd_booted() check misdetects
systemd, even though they still run legacy Upstart.)

man/sd_booted.xml
src/core/mount-setup.c
src/libsystemd-daemon/sd-daemon.c

index 34f2cbf..ce5a34d 100644 (file)
                 implementation.</para>
 
                 <para>Internally, this function checks whether the
-                <filename>/sys/fs/cgroup/systemd</filename> virtual file
-                system is mounted, by comparing the st_dev value of
-                the <function>stat()</function> data of
-                <filename>/sys/fs/cgroup</filename> and
-                <filename>/sys/fs/cgroup/systemd</filename>.</para>
+                directory <filename>/run/systemd/system/</filename>
+                exists. A simple check like this can also be
+                implemented trivially in shell or any other
+                language.</para>
 
                 <para>For details about the algorithm check the
                 liberally licensed reference implementation sources:
index 42cdc6d..ce10be9 100644 (file)
@@ -440,7 +440,11 @@ int mount_setup(bool loaded_policy) {
                 if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0)
                         log_warning("Failed to set up the root directory for shared mount propagation: %m");
 
-        /* Create a few directories we always want around */
+        /* Create a few directories we always want around, Note that
+         * sd_booted() checks for /run/systemd/system, so this mkdir
+         * really needs to stay for good, otherwise software that
+         * copied sd-daemon.c into their sources will misdetect
+         * systemd. */
         mkdir_label("/run/systemd", 0755);
         mkdir_label("/run/systemd/system", 0755);
 
index 5b92e2e..79d8ca3 100644 (file)
@@ -519,18 +519,15 @@ _sd_export_ int sd_booted(void) {
 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
         return 0;
 #else
+        struct stat st;
 
-        struct stat a, b;
+        /* We test whether the runtime unit file directory has been
+         * created. This takes place in mount-setup.c, so is
+         * guaranteed to happen very early during boot. */
 
-        /* We simply test whether the systemd cgroup hierarchy is
-         * mounted */
-
-        if (lstat("/sys/fs/cgroup", &a) < 0)
-                return 0;
-
-        if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
+        if (lstat("/run/systemd/system/", &st) < 0)
                 return 0;
 
-        return a.st_dev != b.st_dev;
+        return !!S_ISDIR(st.st_mode);
 #endif
 }