[systemd-commits] 10 commits - .gitignore Makefile.am TODO src/core src/shared src/system-update-generator src/update-done sysusers.d/.gitignore units/.gitignore units/systemd-journal-catalog-update.service.in units/systemd-networkd.service.in units/systemd-sysctl.service.in units/systemd-sysusers.service.in units/systemd-timesyncd.service.in units/systemd-tmpfiles-clean.service.in units/systemd-tmpfiles-setup.service.in units/systemd-udev-hwdb-update.service.in units/systemd-udevd.service.in units/systemd-update-done.service.in

Lennart Poettering lennart at kemper.freedesktop.org
Fri Jun 13 04:26:43 PDT 2014


 .gitignore                                            |    1 
 Makefile.am                                           |   51 +++++++-
 TODO                                                  |    4 
 src/core/condition.c                                  |   40 ++++++
 src/core/load-fragment-gperf.gperf.m4                 |    1 
 src/shared/condition-util.c                           |    9 -
 src/shared/condition-util.h                           |    1 
 src/system-update-generator/system-update-generator.c |   10 -
 src/update-done/Makefile                              |    1 
 src/update-done/update-done.c                         |  104 ++++++++++++++++++
 sysusers.d/.gitignore                                 |    1 
 units/.gitignore                                      |    4 
 units/systemd-journal-catalog-update.service.in       |   22 +++
 units/systemd-networkd.service.in                     |    2 
 units/systemd-sysctl.service.in                       |    5 
 units/systemd-sysusers.service.in                     |   22 +++
 units/systemd-timesyncd.service.in                    |    2 
 units/systemd-tmpfiles-clean.service.in               |    5 
 units/systemd-tmpfiles-setup.service.in               |    8 -
 units/systemd-udev-hwdb-update.service.in             |   22 +++
 units/systemd-udevd.service.in                        |    2 
 units/systemd-update-done.service.in                  |   23 +++
 22 files changed, 289 insertions(+), 51 deletions(-)

New commits:
commit ecde7065f7b11a7a226d2f7b0e90e998a6347a59
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 13:10:30 2014 +0200

    units: rebuild /etc/passwd, the udev hwdb and the journal catalog files on boot
    
    Only when necessary of course, nicely guarded with the new
    ConditionNeedsUpdate= condition we added.

diff --git a/Makefile.am b/Makefile.am
index 8fd933b..abf8a2b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -491,6 +491,7 @@ nodist_systemunit_DATA = \
 	units/systemd-udevd.service \
 	units/systemd-udev-trigger.service \
 	units/systemd-udev-settle.service \
+	units/systemd-udev-hwdb-update.service \
 	units/debug-shell.service \
 	units/initrd-parse-etc.service \
 	units/initrd-cleanup.service \
@@ -1783,10 +1784,17 @@ systemd_sysusers_LDADD = \
 rootlibexec_PROGRAMS += \
 	systemd-sysusers
 
+nodist_systemunit_DATA += \
+	units/systemd-sysusers.service
+
+SYSINIT_TARGET_WANTS += \
+	systemd-sysusers.service
+
 nodist_sysusers_DATA = \
 	sysusers.d/systemd.conf
 
 EXTRA_DIST += \
+	units/systemd-sysusers.service.in \
 	sysusers.d/systemd.conf.in
 
 INSTALL_DIRS += \
@@ -2753,19 +2761,23 @@ CLEANFILES += \
 EXTRA_DIST += \
 	units/systemd-udevd.service.in \
 	units/systemd-udev-trigger.service.in \
-	units/systemd-udev-settle.service.in
+	units/systemd-udev-settle.service.in \
+	units/systemd-udev-hwdb-update.service.in
 
 CLEANFILES += \
 	units/systemd-udevd.service \
 	units/systemd-udev-trigger.service \
-	units/systemd-udev-settle.service
+	units/systemd-udev-settle.service \
+	units/systemd-udev-hwdb-update.service
 
 SOCKETS_TARGET_WANTS += \
 	systemd-udevd-control.socket \
 	systemd-udevd-kernel.socket
+
 SYSINIT_TARGET_WANTS += \
 	systemd-udevd.service \
-	systemd-udev-trigger.service
+	systemd-udev-trigger.service \
+	systemd-udev-hwdb-update.service
 
 rootbin_PROGRAMS += \
 	udevadm
@@ -3540,7 +3552,8 @@ dist_systemunit_DATA += \
 
 nodist_systemunit_DATA += \
 	units/systemd-journald.service \
-	units/systemd-journal-flush.service
+	units/systemd-journal-flush.service \
+	units/systemd-journal-catalog-update.service
 
 dist_pkgsysconf_DATA += \
 	src/journal/journald.conf
@@ -3557,11 +3570,13 @@ SOCKETS_TARGET_WANTS += \
 
 SYSINIT_TARGET_WANTS += \
 	systemd-journald.service \
-	systemd-journal-flush.service
+	systemd-journal-flush.service \
+	systemd-journal-catalog-update.service
 
 EXTRA_DIST += \
 	units/systemd-journald.service.in \
 	units/systemd-journal-flush.service.in \
+	units/systemd-journal-catalog-update.service.in \
 	src/journal/journald-gperf.gperf
 
 CLEANFILES += \
diff --git a/units/.gitignore b/units/.gitignore
index 45ddab7..8ae6ca8 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -32,6 +32,7 @@
 /systemd-initctl.service
 /systemd-journal-flush.service
 /systemd-journal-gatewayd.service
+/systemd-journal-catalog-update.service
 /systemd-journald.service
 /systemd-kexec.service
 /systemd-localed.service
@@ -54,12 +55,14 @@
 /systemd-shutdownd.service
 /systemd-suspend.service
 /systemd-sysctl.service
+/systemd-sysusers.service
 /systemd-timedated.service
 /systemd-timesyncd.service
 /systemd-tmpfiles-clean.service
 /systemd-tmpfiles-setup-dev.service
 /systemd-tmpfiles-setup.service
 /systemd-tmpfiles.service
+/systemd-udev-hwdb-update.service
 /systemd-udev-settle.service
 /systemd-udev-trigger.service
 /systemd-udevd.service
diff --git a/units/systemd-journal-catalog-update.service.in b/units/systemd-journal-catalog-update.service.in
new file mode 100644
index 0000000..d45381d
--- /dev/null
+++ b/units/systemd-journal-catalog-update.service.in
@@ -0,0 +1,22 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rebuild Journal Catalog
+Documentation=man:systemd-journald.service(8) man:journald.conf(5)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target systemd-update-done.service
+RefuseManualStart=yes
+RefuseManualStop=yes
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/journalctl --update-catalog
diff --git a/units/systemd-networkd.service.in b/units/systemd-networkd.service.in
index 48f4d63..57c3fbf 100644
--- a/units/systemd-networkd.service.in
+++ b/units/systemd-networkd.service.in
@@ -9,7 +9,7 @@
 Description=Network Service
 Documentation=man:systemd-networkd.service(8)
 DefaultDependencies=no
-After=dbus.service network-pre.target
+After=dbus.service network-pre.target systemd-sysusers.service
 Before=network.target
 Wants=network.target
 ConditionCapability=CAP_NET_ADMIN
diff --git a/units/systemd-sysusers.service.in b/units/systemd-sysusers.service.in
new file mode 100644
index 0000000..e123f39
--- /dev/null
+++ b/units/systemd-sysusers.service.in
@@ -0,0 +1,22 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Create System Users
+Documentation=man:sysusers.d(5) man:systemd-sysusers.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target shutdown.target systemd-update-done.service
+RefuseManualStart=yes
+RefuseManualStop=yes
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-sysusers
diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in
index 3a1bc48..a20621d 100644
--- a/units/systemd-timesyncd.service.in
+++ b/units/systemd-timesyncd.service.in
@@ -11,7 +11,7 @@ Documentation=man:systemd-timesyncd.service(8)
 ConditionCapability=CAP_SYS_TIME
 DefaultDependencies=off
 RequiresMountsFor=/var/lib/systemd/clock
-After=systemd-remount-fs.service systemd-tmpfiles-setup.service
+After=systemd-remount-fs.service systemd-tmpfiles-setup.service systemd-sysusers.service
 Before=sysinit.target shutdown.target
 Conflicts=shutdown.target
 Wants=time-sync.target
diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
index 747c9a8..d3c6da8 100644
--- a/units/systemd-tmpfiles-setup.service.in
+++ b/units/systemd-tmpfiles-setup.service.in
@@ -10,7 +10,7 @@ Description=Create Volatile Files and Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
 Conflicts=shutdown.target
-After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target systemd-sysusers.service
 Before=sysinit.target shutdown.target
 RefuseManualStart=yes
 RefuseManualStop=yes
diff --git a/units/systemd-udev-hwdb-update.service.in b/units/systemd-udev-hwdb-update.service.in
new file mode 100644
index 0000000..4e7b845
--- /dev/null
+++ b/units/systemd-udev-hwdb-update.service.in
@@ -0,0 +1,22 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Rebuild Hardware Database
+Documentation=man:udev(7) man:systemd-udevd.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service systemd-remount-fs.service
+Before=sysinit.target shutdown.target systemd-update-done.service
+RefuseManualStart=yes
+RefuseManualStop=yes
+ConditionNeedsUpdate=/etc
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootbindir@/udevadm hwdb --update
diff --git a/units/systemd-udevd.service.in b/units/systemd-udevd.service.in
index ddee015..f6acd6f 100644
--- a/units/systemd-udevd.service.in
+++ b/units/systemd-udevd.service.in
@@ -10,7 +10,7 @@ Description=udev Kernel Device Manager
 Documentation=man:systemd-udevd.service(8) man:udev(7)
 DefaultDependencies=no
 Wants=systemd-udevd-control.socket systemd-udevd-kernel.socket
-After=systemd-udevd-control.socket systemd-udevd-kernel.socket
+After=systemd-udevd-control.socket systemd-udevd-kernel.socket systemd-udev-hwdb-update.service systemd-sysusers.service
 Before=sysinit.target
 ConditionPathIsReadWrite=/sys
 

commit a55654d598c78f8e084aa6a18fec6eff900c9aed
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:52:31 2014 +0200

    core: add new ConditionNeedsUpdate= unit condition
    
    This new condition allows checking whether /etc or /var are out-of-date
    relative to /usr. This is the counterpart for the update flag managed by
    systemd-update-done.service. Services that want to be started once after
    /usr got updated should use:
    
            [Unit]
            ConditionNeedsUpdate=/etc
            Before=systemd-update-done.service
    
    This makes sure that they are only run if /etc is out-of-date relative
    to /usr. And that it will be executed after systemd-update-done.service
    which is responsible for marking /etc up-to-date relative to the current
    /usr.
    
    ConditionNeedsUpdate= will also checks whether /etc is actually
    writable, and not trigger if it isn't, since no update is possible then.

diff --git a/src/core/condition.c b/src/core/condition.c
index 833bcdf..410fb36 100644
--- a/src/core/condition.c
+++ b/src/core/condition.c
@@ -90,6 +90,36 @@ static bool condition_test_capability(Condition *c) {
         return !!(capabilities & (1ULL << value)) == !c->negate;
 }
 
+static bool condition_test_needs_update(Condition *c) {
+        const char *p;
+        struct stat usr, other;
+
+        assert(c);
+        assert(c->parameter);
+        assert(c->type == CONDITION_NEEDS_UPDATE);
+
+        /* If the file system is read-only we shouldn't suggest an update */
+        if (path_is_read_only_fs(c->parameter) > 0)
+                return c->negate;
+
+        /* Any other failure means we should allow the condition to be true,
+         * so that we rather invoke too many update tools then too
+         * few. */
+
+        if (!path_is_absolute(c->parameter))
+                return !c->negate;
+
+        p = strappenda(c->parameter, "/.updated");
+        if (lstat(p, &other) < 0)
+                return !c->negate;
+
+        if (lstat("/usr/", &usr) < 0)
+                return !c->negate;
+
+        return (usr.st_mtim.tv_sec > other.st_mtim.tv_sec ||
+                (usr.st_mtim.tv_sec == other.st_mtim.tv_sec && usr.st_mtim.tv_nsec > other.st_mtim.tv_nsec)) == !c->negate;
+}
+
 static bool condition_test(Condition *c) {
         assert(c);
 
@@ -169,6 +199,9 @@ static bool condition_test(Condition *c) {
         case CONDITION_ARCHITECTURE:
                 return condition_test_architecture(c);
 
+        case CONDITION_NEEDS_UPDATE:
+                return condition_test_needs_update(c);
+
         case CONDITION_NULL:
                 return !c->negate;
 
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 2d98bba..d97c5c6 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -161,6 +161,7 @@ Unit.ConditionPathIsReadWrite,   config_parse_unit_condition_path,   CONDITION_P
 Unit.ConditionDirectoryNotEmpty, config_parse_unit_condition_path,   CONDITION_DIRECTORY_NOT_EMPTY, 0
 Unit.ConditionFileNotEmpty,      config_parse_unit_condition_path,   CONDITION_FILE_NOT_EMPTY,      0
 Unit.ConditionFileIsExecutable,  config_parse_unit_condition_path,   CONDITION_FILE_IS_EXECUTABLE,  0
+Unit.ConditionNeedsUpdate,       config_parse_unit_condition_path,   CONDITION_NEEDS_UPDATE,        0
 Unit.ConditionKernelCommandLine, config_parse_unit_condition_string, CONDITION_KERNEL_COMMAND_LINE, 0
 Unit.ConditionArchitecture,      config_parse_unit_condition_string, CONDITION_ARCHITECTURE,        0
 Unit.ConditionVirtualization,    config_parse_unit_condition_string, CONDITION_VIRTUALIZATION,      0
diff --git a/src/shared/condition-util.c b/src/shared/condition-util.c
index 1c7d1f6..7b89b0f 100644
--- a/src/shared/condition-util.c
+++ b/src/shared/condition-util.c
@@ -256,6 +256,7 @@ static const char* const condition_type_table[_CONDITION_TYPE_MAX] = {
         [CONDITION_HOST] = "ConditionHost",
         [CONDITION_AC_POWER] = "ConditionACPower",
         [CONDITION_ARCHITECTURE] = "ConditionArchitecture",
+        [CONDITION_NEEDS_UPDATE] = "ConditionNeedsUpdate",
         [CONDITION_NULL] = "ConditionNull"
 };
 
diff --git a/src/shared/condition-util.h b/src/shared/condition-util.h
index 63d945e..0b09f83 100644
--- a/src/shared/condition-util.h
+++ b/src/shared/condition-util.h
@@ -44,6 +44,7 @@ typedef enum ConditionType {
         CONDITION_HOST,
         CONDITION_AC_POWER,
         CONDITION_ARCHITECTURE,
+        CONDITION_NEEDS_UPDATE,
         CONDITION_NULL,
         _CONDITION_TYPE_MAX,
         _CONDITION_TYPE_INVALID = -1
diff --git a/units/systemd-update-done.service.in b/units/systemd-update-done.service.in
index dccb513..1a907f9 100644
--- a/units/systemd-update-done.service.in
+++ b/units/systemd-update-done.service.in
@@ -14,6 +14,8 @@ After=systemd-readahead-collect.service systemd-readahead-replay.service local-f
 Before=sysinit.target shutdown.target
 RefuseManualStart=yes
 RefuseManualStop=yes
+ConditionNeedsUpdate=|/etc
+ConditionNeedsUpdate=|/var
 
 [Service]
 Type=oneshot

commit 8ea48dfcd33e8db0c01bf8c57c3bbcfdc3c86d4b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:43:49 2014 +0200

    update-done: add minimal tool to manage system updates for /etc and /var, if /usr has changed
    
    In order to support offline updates to /usr, we need to be able to run
    certain tasks on next boot-up to bring /etc and /var in line with the
    updated /usr. Hence, let's devise a mechanism how we can detect whether
    /etc or /var are not up-to-date with /usr anymore: we keep "touch
    files" in /etc/.updated and /var/.updated that are mtime-compared with
    /usr. This means:
    
    Whenever the vendor OS tree in /usr is updated, and any services that
    shall be executed at next boot shall be triggered, it is sufficient to
    update the mtime of /usr itself. At next boot, if /etc/.updated and/or
    /var/.updated is older than than /usr (or missing), we know we have to
    run the update tools once. After that is completed we need to update the
    mtime of these files to the one of /usr, to keep track that we made the
    necessary updates, and won't repeat them on next reboot.
    
    A subsequent commit adds a new ConditionNeedsUpdate= condition that
    allows checking on boot whether /etc or /var are outdated and need
    updating.
    
    This is an early step to allow booting up with an empty /etc, with
    automatic rebuilding of the necessary cache files or user databases
    therein, as well as supporting later updates of /usr that then propagate
    to /etc and /var again.

diff --git a/.gitignore b/.gitignore
index cdb2ac9..bcebb96 100644
--- a/.gitignore
+++ b/.gitignore
@@ -109,6 +109,7 @@
 /systemd-tty-ask-password-agent
 /systemd-uaccess
 /systemd-udevd
+/systemd-update-done
 /systemd-update-utmp
 /systemd-user-sessions
 /systemd-vconsole-setup
diff --git a/Makefile.am b/Makefile.am
index 894d445..8fd933b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -361,7 +361,8 @@ rootlibexec_PROGRAMS = \
 	systemd-sysctl \
 	systemd-sleep \
 	systemd-bus-proxyd \
-	systemd-socket-proxyd
+	systemd-socket-proxyd \
+	systemd-update-done
 
 systemgenerator_PROGRAMS = \
 	systemd-getty-generator \
@@ -495,7 +496,8 @@ nodist_systemunit_DATA = \
 	units/initrd-cleanup.service \
 	units/initrd-udevadm-cleanup-db.service \
 	units/initrd-switch-root.service \
-	units/systemd-nspawn at .service
+	units/systemd-nspawn at .service \
+	units/systemd-update-done.service
 
 dist_userunit_DATA = \
 	units/user/basic.target \
@@ -538,7 +540,8 @@ EXTRA_DIST += \
 	units/initrd-cleanup.service.in \
 	units/initrd-udevadm-cleanup-db.service.in \
 	units/initrd-switch-root.service.in \
-	units/systemd-nspawn at .service.in
+	units/systemd-nspawn at .service.in \
+	units/systemd-update-done.service.in
 
 CLEANFILES += \
 	units/console-shell.service.m4 \
@@ -1641,6 +1644,14 @@ systemd_update_utmp_LDADD = \
 	$(AUDIT_LIBS)
 
 # ------------------------------------------------------------------------------
+systemd_update_done_SOURCES = \
+	src/update-done/update-done.c
+
+systemd_update_done_LDADD = \
+	libsystemd-internal.la \
+	libsystemd-shared.la
+
+# ------------------------------------------------------------------------------
 systemd_shutdownd_SOURCES = \
 	src/shutdownd/shutdownd.c
 
@@ -5100,14 +5111,19 @@ RUNLEVEL4_TARGET_WANTS += \
 RUNLEVEL5_TARGET_WANTS += \
 	systemd-update-utmp-runlevel.service
 endif
+
 SYSINIT_TARGET_WANTS += \
-	systemd-update-utmp.service
+	systemd-update-utmp.service \
+	systemd-update-done.service
+
 LOCAL_FS_TARGET_WANTS += \
 	systemd-remount-fs.service \
 	tmp.mount
+
 MULTI_USER_TARGET_WANTS += \
 	getty.target \
 	systemd-ask-password-wall.path
+
 SYSINIT_TARGET_WANTS += \
 	dev-hugepages.mount \
 	dev-mqueue.mount \
diff --git a/src/update-done/Makefile b/src/update-done/Makefile
new file mode 120000
index 0000000..d0b0e8e
--- /dev/null
+++ b/src/update-done/Makefile
@@ -0,0 +1 @@
+../Makefile
\ No newline at end of file
diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c
new file mode 100644
index 0000000..10ba85c
--- /dev/null
+++ b/src/update-done/update-done.c
@@ -0,0 +1,104 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "util.h"
+
+static int apply_timestamp(const char *path, struct timespec *ts) {
+        struct timespec twice[2];
+        struct stat st;
+
+        assert(path);
+        assert(ts);
+
+        if (stat(path, &st) >= 0) {
+                /* Is the timestamp file already newer than the OS? If so, there's nothing to do. */
+                if (st.st_mtim.tv_sec > ts->tv_sec ||
+                    (st.st_mtim.tv_sec == ts->tv_sec && st.st_mtim.tv_nsec >= ts->tv_nsec))
+                        return 0;
+
+                /* It is older? Then let's update it */
+                twice[0] = *ts;
+                twice[1] = *ts;
+
+                if (utimensat(AT_FDCWD, path, twice, AT_SYMLINK_NOFOLLOW) < 0) {
+
+                        if (errno == EROFS) {
+                                log_debug("Can't update timestamp file %s, file system is read-only.", path);
+                                return 0;
+                        }
+
+                        log_error("Failed to update timestamp on %s: %m", path);
+                        return -errno;
+                }
+
+        } else if (errno == ENOENT) {
+                _cleanup_close_ int fd = -1;
+
+                /* The timestamp file doesn't exist yet? Then let's create it. */
+
+                fd = open(path, O_CREAT|O_EXCL|O_WRONLY|O_TRUNC|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0644);
+                if (fd < 0) {
+
+                        if (errno == EROFS) {
+                                log_debug("Can't create timestamp file %s, file system is read-only.", path);
+                                return 0;
+                        }
+
+                        log_error("Failed to create timestamp file %s: %m", path);
+                        return -errno;
+                }
+
+                twice[0] = *ts;
+                twice[1] = *ts;
+
+                if (futimens(fd, twice) < 0) {
+                        log_error("Failed to update timestamp on %s: %m", path);
+                        return -errno;
+                }
+        } else {
+                log_error("Failed to stat() timestamp file %s: %m", path);
+                return -errno;
+        }
+
+        return 0;
+}
+
+int main(int argc, char *argv[]) {
+        struct stat st;
+        int r, q;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (stat("/usr", &st) < 0) {
+                log_error("Failed to stat /usr: %m");
+                return EXIT_FAILURE;
+        }
+
+        r = apply_timestamp("/etc/.updated", &st.st_mtim);
+
+        q = apply_timestamp("/var/.updated", &st.st_mtim);
+        if (q < 0 && r == 0)
+                r = q;
+
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/units/.gitignore b/units/.gitignore
index b8c0845..45ddab7 100644
--- a/units/.gitignore
+++ b/units/.gitignore
@@ -65,6 +65,7 @@
 /systemd-udevd.service
 /systemd-update-utmp-runlevel.service
 /systemd-update-utmp.service
+/systemd-update-done.service
 /systemd-user-sessions.service
 /systemd-vconsole-setup.service
 /user at .service
diff --git a/units/systemd-update-done.service.in b/units/systemd-update-done.service.in
new file mode 100644
index 0000000..dccb513
--- /dev/null
+++ b/units/systemd-update-done.service.in
@@ -0,0 +1,21 @@
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=Update is Completed
+Documentation=man:sysusers.d(5) man:systemd-sysusers(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
+Before=sysinit.target shutdown.target
+RefuseManualStart=yes
+RefuseManualStop=yes
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=@rootlibexecdir@/systemd-update-done

commit dc92e62c6c34f242aa54aa187e50a94ed7695c51
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:39:58 2014 +0200

    condition: minor modernizations

diff --git a/src/core/condition.c b/src/core/condition.c
index 2468458..833bcdf 100644
--- a/src/core/condition.c
+++ b/src/core/condition.c
@@ -27,7 +27,7 @@
 #include <sys/statvfs.h>
 #include <fnmatch.h>
 
-#include <systemd/sd-id128.h>
+#include "sd-id128.h"
 #include "util.h"
 #include "condition.h"
 #include "virt.h"
@@ -52,12 +52,13 @@ static bool condition_test_security(Condition *c) {
                 return use_ima() == !c->negate;
         if (streq(c->parameter, "smack"))
                 return use_smack() == !c->negate;
+
         return c->negate;
 }
 
 static bool condition_test_capability(Condition *c) {
+        _cleanup_fclose_ FILE *f = NULL;
         cap_value_t value;
-        FILE *f;
         char line[LINE_MAX];
         unsigned long long capabilities = -1;
 
@@ -86,8 +87,6 @@ static bool condition_test_capability(Condition *c) {
                 }
         }
 
-        fclose(f);
-
         return !!(capabilities & (1ULL << value)) == !c->negate;
 }
 
diff --git a/src/shared/condition-util.c b/src/shared/condition-util.c
index 9961cb4..1c7d1f6 100644
--- a/src/shared/condition-util.c
+++ b/src/shared/condition-util.c
@@ -177,10 +177,9 @@ bool condition_test_architecture(Condition *c) {
 }
 
 bool condition_test_host(Condition *c) {
+        _cleanup_free_ char *h = NULL;
         sd_id128_t x, y;
-        char *h;
         int r;
-        bool b;
 
         assert(c);
         assert(c->parameter);
@@ -199,10 +198,7 @@ bool condition_test_host(Condition *c) {
         if (!h)
                 return c->negate;
 
-        b = fnmatch(c->parameter, h, FNM_CASEFOLD) == 0;
-        free(h);
-
-        return b == !c->negate;
+        return (fnmatch(c->parameter, h, FNM_CASEFOLD) == 0) == !c->negate;
 }
 
 bool condition_test_ac_power(Condition *c) {

commit d4c049bfcde7bd8ff8baaee4ff8aa3bd16d7be54
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:25:12 2014 +0200

    units: don't conditionalize sysctl service
    
    We install two sysctl snippets ourselves, hence the condition will
    always trigger, so no point in tryng to optimize things with this, it
    just will make things slower, if anything.

diff --git a/units/systemd-sysctl.service.in b/units/systemd-sysctl.service.in
index 5baf22c..5c7c5d7 100644
--- a/units/systemd-sysctl.service.in
+++ b/units/systemd-sysctl.service.in
@@ -13,11 +13,6 @@ Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service
 Before=sysinit.target shutdown.target
 ConditionPathIsReadWrite=/proc/sys/
-ConditionDirectoryNotEmpty=|/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/usr/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/sysctl.d
-ConditionDirectoryNotEmpty=|/etc/sysctl.d
-ConditionDirectoryNotEmpty=|/run/sysctl.d
 
 [Service]
 Type=oneshot

commit db62b5b37e7d9ebf7d6b8f2709e6a51bbf8f77ee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:22:04 2014 +0200

    units: remove conditions from systemd-tmpfiles-setup
    
    There's no point in conditionalizing systemd-tmpfiles at boot, since we
    ship tmpfiles snippets ourselves, hence they will always trigger anyway.
    
    Also, there's no reason to pull in local-fs.target from the service,
    hence drop that.

diff --git a/units/systemd-tmpfiles-clean.service.in b/units/systemd-tmpfiles-clean.service.in
index a5b5acb..5946fcd 100644
--- a/units/systemd-tmpfiles-clean.service.in
+++ b/units/systemd-tmpfiles-clean.service.in
@@ -9,13 +9,8 @@
 Description=Cleanup of Temporary Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Wants=local-fs.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
 Before=sysinit.target shutdown.target
-ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
-ConditionDirectoryNotEmpty=|/run/tmpfiles.d
 
 [Service]
 Type=oneshot
diff --git a/units/systemd-tmpfiles-setup.service.in b/units/systemd-tmpfiles-setup.service.in
index 01043b7..747c9a8 100644
--- a/units/systemd-tmpfiles-setup.service.in
+++ b/units/systemd-tmpfiles-setup.service.in
@@ -9,15 +9,9 @@
 Description=Create Volatile Files and Directories
 Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
 DefaultDependencies=no
-Wants=local-fs.target
 Conflicts=shutdown.target
 After=systemd-readahead-collect.service systemd-readahead-replay.service local-fs.target
 Before=sysinit.target shutdown.target
-ConditionDirectoryNotEmpty=|/usr/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/usr/local/lib/tmpfiles.d
-ConditionDirectoryNotEmpty=|/etc/tmpfiles.d
-ConditionDirectoryNotEmpty=|/run/tmpfiles.d
 RefuseManualStart=yes
 RefuseManualStop=yes
 

commit 9194c8e4c3a85e098799b3096fe65d1aced02fd4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:21:45 2014 +0200

    system-update-generator: modernizations

diff --git a/src/system-update-generator/system-update-generator.c b/src/system-update-generator/system-update-generator.c
index 13b8a0c..4f22c9c 100644
--- a/src/system-update-generator/system-update-generator.c
+++ b/src/system-update-generator/system-update-generator.c
@@ -35,10 +35,9 @@
 static const char *arg_dest = "/tmp";
 
 static int generate_symlink(void) {
-        struct stat st;
-        char _cleanup_free_ *p = NULL;
+        const char *p = NULL;
 
-        if (lstat("/system-update", &st) < 0) {
+        if (access("/system-update", F_OK) < 0) {
                 if (errno == ENOENT)
                         return 0;
 
@@ -46,10 +45,7 @@ static int generate_symlink(void) {
                 return -EINVAL;
         }
 
-        p = strappend(arg_dest, "/default.target");
-        if (!p)
-                return log_oom();
-
+        p = strappenda(arg_dest, "/default.target");
         if (symlink(SYSTEM_DATA_UNIT_PATH "/system-update.target", p) < 0) {
                 log_error("Failed to create symlink %s: %m", p);
                 return -errno;

commit 7de77d1cf5d5b02cec484175774cf429d5464561
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:18:18 2014 +0200

    sysusers: hide generate .conf file

diff --git a/sysusers.d/.gitignore b/sysusers.d/.gitignore
new file mode 100644
index 0000000..9a4436c
--- /dev/null
+++ b/sysusers.d/.gitignore
@@ -0,0 +1 @@
+/systemd.conf

commit dd2552307315381197d2e2bf59cc39d2aa81c652
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:17:30 2014 +0200

    update TODO

diff --git a/TODO b/TODO
index 9a88942..b20a66f 100644
--- a/TODO
+++ b/TODO
@@ -86,10 +86,6 @@ Features:
   do not have to open it to know that it is not interesting for us, for
   the most common operations.
 
-* support transient mount units
-
-* add an "input" group to udev logic and add all input devices to it
-
 * add generator that pulls in systemd-network from containers when
   CAP_NET_ADMIN is set, more than the loopback device is defined, even
   when it is otherwise off

commit 48e93f88ffac3539cad0ea02e9f6d60731a32652
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Jun 13 12:17:11 2014 +0200

    sysusers: move systemd-sysusers to libexec for now

diff --git a/Makefile.am b/Makefile.am
index 685066f..894d445 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1769,7 +1769,7 @@ systemd_sysusers_LDADD = \
 	libsystemd-internal.la \
 	libsystemd-shared.la
 
-rootbin_PROGRAMS += \
+rootlibexec_PROGRAMS += \
 	systemd-sysusers
 
 nodist_sysusers_DATA = \



More information about the systemd-commits mailing list