[systemd-commits] 6 commits - Makefile.am TODO man/systemd.special.xml man/tmpfiles.d.xml src/core src/cryptsetup src/shared src/tmpfiles units/cryptsetup-pre.target

Lennart Poettering lennart at kemper.freedesktop.org
Tue Jun 17 15:20:33 PDT 2014


 Makefile.am                           |    3 
 TODO                                  |   29 --------
 man/systemd.special.xml               |   22 ++++++
 man/tmpfiles.d.xml                    |   33 +++++++++-
 src/core/namespace.c                  |    4 +
 src/cryptsetup/cryptsetup-generator.c |    2 
 src/shared/util.c                     |   40 ++++++++++++
 src/shared/util.h                     |    2 
 src/tmpfiles/tmpfiles.c               |  112 +++++++++++++++++++++-------------
 units/cryptsetup-pre.target           |   11 +++
 10 files changed, 186 insertions(+), 72 deletions(-)

New commits:
commit 9542239eaf481decca6c254dffb3f2b4e716545e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jun 18 00:07:56 2014 +0200

    cryptsetup: introduce new cryptsetup-pre.traget unit so that services can make sure they are started before and stopped after any LUKS setup
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1097938

diff --git a/Makefile.am b/Makefile.am
index e428141..dea0633 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3933,7 +3933,8 @@ systemgenerator_PROGRAMS += \
 	systemd-cryptsetup-generator
 
 dist_systemunit_DATA += \
-	units/cryptsetup.target
+	units/cryptsetup.target \
+	units/cryptsetup-pre.target
 
 systemd_cryptsetup_SOURCES = \
 	src/cryptsetup/cryptsetup.c
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index cda6edd..f29cc23 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -52,6 +52,7 @@
                 <filename>bluetooth.target</filename>,
                 <filename>ctrl-alt-del.target</filename>,
                 <filename>cryptsetup.target</filename>,
+                <filename>cryptsetup-pre.target</filename>,
                 <filename>dbus.service</filename>,
                 <filename>dbus.socket</filename>,
                 <filename>default.target</filename>,
@@ -841,6 +842,27 @@
 
                 <variablelist>
                         <varlistentry>
+                                <term><filename>cryptsetup-pre.target</filename></term>
+                                <listitem>
+                                        <para>This passive target unit
+                                        may be pulled in by services
+                                        that want to run before any
+                                        encrypted block device is set
+                                        up. All encrypted block
+                                        devices are set up after this
+                                        target has been reached. Since
+                                        the shutdown order is
+                                        implicitly the reverse
+                                        start-up order between units
+                                        this target is particularly
+                                        useful to ensure that a
+                                        service is shut down only
+                                        after all encrypted block
+                                        devices are fully
+                                        stopped.</para>
+                                </listitem>
+                        </varlistentry>
+                        <varlistentry>
                                 <term><filename>local-fs-pre.target</filename></term>
                                 <listitem>
                                         <para>This target unit is
diff --git a/src/cryptsetup/cryptsetup-generator.c b/src/cryptsetup/cryptsetup-generator.c
index f4eeb2a..dfdca1e 100644
--- a/src/cryptsetup/cryptsetup-generator.c
+++ b/src/cryptsetup/cryptsetup-generator.c
@@ -127,7 +127,7 @@ static int create_disk(
                 "Conflicts=umount.target\n"
                 "BindsTo=dev-mapper-%i.device\n"
                 "IgnoreOnIsolate=true\n"
-                "After=systemd-readahead-collect.service systemd-readahead-replay.service\n",
+                "After=systemd-readahead-collect.service systemd-readahead-replay.service cryptsetup-pre.target\n",
                 f);
 
         if (!nofail)
diff --git a/units/cryptsetup-pre.target b/units/cryptsetup-pre.target
new file mode 100644
index 0000000..6535341
--- /dev/null
+++ b/units/cryptsetup-pre.target
@@ -0,0 +1,11 @@
+#  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=Encrypted Volumes (Pre)
+Documentation=man:systemd.special(7)
+RefuseManualStart=yes

commit 6f04529399a7a59cfe549913349176409a4dc2e3
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jun 18 00:02:08 2014 +0200

    tmpfiles: create directories already with the right label, instead of creating them first, and relabeling them afterwards

diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 25c2a8c..9790122 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -691,12 +691,12 @@ static int create_item(Item *i) {
 
                 RUN_WITH_UMASK(0000) {
                         mkdir_parents_label(i->path, 0755);
-                        r = mkdir(i->path, i->mode);
+                        r = mkdir_label(i->path, i->mode);
                 }
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("Failed to create directory %s: %m", i->path);
-                        return -errno;
+                if (r < 0 && r != -EEXIST) {
+                        log_error("Failed to create directory %s: %s", i->path, strerror(-r));
+                        return r;
                 }
 
                 if (stat(i->path, &st) < 0) {

commit 43ad6e31aae7e5d36e8a01968dfdca1d3fedc7fa
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jun 18 00:01:39 2014 +0200

    tmpfiles: w lines should allow following symlinks

diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 8ec8252..25c2a8c 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -494,20 +494,19 @@ static int item_set_perms(Item *i, const char *path) {
 }
 
 static int write_one_file(Item *i, const char *path) {
-        int flags;
-        int fd = -1;
+        _cleanup_close_ int fd = -1;
+        int flags, r = 0;
         struct stat st;
-        int r = 0;
 
         assert(i);
         assert(path);
 
-        flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND :
-                i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC : 0;
+        flags = i->type == CREATE_FILE ? O_CREAT|O_APPEND|O_NOFOLLOW :
+                i->type == TRUNCATE_FILE ? O_CREAT|O_TRUNC|O_NOFOLLOW : 0;
 
-        RUN_WITH_UMASK(0) {
+        RUN_WITH_UMASK(0000) {
                 label_context_set(path, S_IFREG);
-                fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY|O_NOFOLLOW, i->mode);
+                fd = open(path, flags|O_NDELAY|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode);
                 label_context_clear();
         }
 
@@ -525,22 +524,19 @@ static int write_one_file(Item *i, const char *path) {
                 size_t l;
 
                 unescaped = cunescape(i->argument);
-                if (unescaped == NULL) {
-                        safe_close(fd);
+                if (!unescaped)
                         return log_oom();
-                }
 
                 l = strlen(unescaped);
                 n = write(fd, unescaped, l);
 
                 if (n < 0 || (size_t) n < l) {
                         log_error("Failed to write file %s: %s", path, n < 0 ? strerror(-n) : "Short write");
-                        safe_close(fd);
                         return n < 0 ? n : -EIO;
                 }
         }
 
-        safe_close(fd);
+        fd = safe_close(fd);
 
         if (stat(path, &st) < 0) {
                 log_error("stat(%s) failed: %m", path);

commit 3c779fa59d1825d7db2a9516669d34ded7916913
Author: Lennart Poettering <lennart at poettering.net>
Date:   Wed Jun 18 00:01:07 2014 +0200

    update TODO

diff --git a/TODO b/TODO
index f767f1c..43dbcd9 100644
--- a/TODO
+++ b/TODO
@@ -32,10 +32,11 @@ External:
 
 Features:
 
-* tmpfiles: add support for "+" suffix for more commands
+* udev should make /dev/loop-control and /dev/btrfs-control owned by the "disk" group, https://bugzilla.redhat.com/show_bug.cgi?id=1045432
 
 * support empty /etc boots nicely:
-  - tmpfiles: add nice way to copy files /usr/share/etc → /etc
+  - tmpfiles: add nice way to copy files /usr/share/factory/etc → /etc
+  - nspawn/gpt-generator: introduce new gpt partition type for /usr
 
 * generator that automatically discovers btrfs subvolumes, identifies their purpose based on some xattr on them.
 
@@ -65,8 +66,6 @@ Features:
 
 * For timer units: add some mechanisms so that timer units that trigger immediately on boot do not have the services they run added to the initial transaction and thus confuse Type=idle.
 
-* Add RPM macros for registering/unregistering binfmt drop-ins
-
 * Add timeout to early-boot, and shut down the system if it is hit. Solves the laptop-in-bag problem and is useful for embedded cases
 
 * Run most system services with cgroupfs read-only and procfs with a more secure mode (doesn't work, since the hidepid= option is per-pid-namespace, not per-mount)
@@ -267,8 +266,6 @@ Features:
 
 * use "log level" rather than "log priority" everywhere
 
-* timedate: have global on/off switches for auto-time (NTP), and auto-timezone that connman can subscribe to.
-
 * merge unit_kill_common() and unit_kill_context()
 
 * introduce ExecCondition= in services
@@ -375,7 +372,6 @@ Features:
     about it. Should fix both to print nice actionable messages.
   - print nice message from systemctl --failed if there are no entries shown, and hook that into ExecStartPre of rescue.service/emergency.service
   - add new command to systemctl: "systemctl system-reexec" which reexecs as many daemons as virtually possible
-  - systemctl enable: improve the success messages (i.e. more human readable, less shell-like)
   - systemctl enable: fail if target to alias into does not exist? maybe show how many units are enabled afterwards?
   - systemctl: "Journal has been rotated since unit was started." message is misleading
   - support "systemctl stop foobar at .service" to stop all units matching a certain template
@@ -386,14 +382,9 @@ Features:
 * unit install:
   - "systemctl mask" should find all names by which a unit is accessible
     (i.e. by scanning for symlinks to it) and link them all to /dev/null
-  - "systemctl disable" of a unit instance removes all symlinks, but should
-    only remove the instance symlink (systemctl disable of a template
-    unit however should remove them all).
   - systemctl list-unit-files should list generated files (and probably with a new state "generated" for them, or so)
   - systemctl: maybe add "systemctl add-wants" or so...
 
-* deal with sendmail/postfix exclusivity
-
 * timer units:
   - timer units should get the ability to trigger when:
     o CLOCK_REALTIME makes jumps (TFD_TIMER_CANCEL_ON_SET)
@@ -427,19 +418,10 @@ Features:
 * fedup: do not delete initrd on switch-root
 * fedup: generator
 
-* timedated: refuse time changes when NTP is on
-
 * clean up date formatting and parsing so that all absolute/relative timestamps we format can also be parsed
 
 * on shutdown: move utmp, wall, audit logic all into PID 1 (or logind?), get rid of systemd-update-utmp-runlevel
 
-* add "factory" instructions to setup an empty /etc + /var
-    - used to setup a new container from a shared /usr
-    - superset of tmpfiles model
-    - instructions shipped by packages and stored in /usr/lib/
-    - compose /etc/passwd and /etc/group, copy files
-    - able to create uid + gid used by packages, for file ownership
-
 * make repeated alt-ctrl-del presses printing a dump, or even force a reboot without
   waiting for the timeout
 
@@ -471,12 +453,8 @@ Features:
 
 * create /sbin/init symlinks from the build system
 
-* Query Paul Moore about relabelling socket fds while they are open
-
 * allow writing multiple conditions in unit files on one line
 
-* explore multiple service instances per listening socket idea
-
 * MountFlags=shared acts as MountFlags=slave right now.
 
 * drop PID 1 reloading, only do reexecing (difficult: Reload()
@@ -547,7 +525,6 @@ Features:
 * when a bus name of a service disappears from the bus make sure to queue further activation requests
 
 * tmpfiles:
-  - check systemd-tmpfiles for selinux context hookup for mknod(), symlink() and similar
   - apply "x" on "D" too (see patch from William Douglas)
 
 * for services: do not set $HOME in services unless requested

commit dd078a1ef844d2ab66b8fb1e58dd73522262fad6
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jun 17 23:51:21 2014 +0200

    namespace: properly label device nodes we create
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1081429

diff --git a/src/core/namespace.c b/src/core/namespace.c
index 3b5402b..d1513ce 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -42,6 +42,7 @@
 #include "mkdir.h"
 #include "dev-setup.h"
 #include "def.h"
+#include "label.h"
 
 typedef enum MountMode {
         /* This is ordered by priority! */
@@ -223,7 +224,10 @@ static int mount_dev(BindMount *m) {
                         goto fail;
                 }
 
+                label_context_set(d, st.st_mode);
                 r = mknod(dn, st.st_mode, st.st_rdev);
+                label_context_clear();
+
                 if (r < 0) {
                         r = -errno;
                         goto fail;

commit 1554afae546f6cfb8ac85e36300d7bf608886780
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Jun 17 23:50:22 2014 +0200

    tmpfiles: add "+" modifier support to b, c, p lines in addition to L

diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
index 2d8af98..6b27535 100644
--- a/man/tmpfiles.d.xml
+++ b/man/tmpfiles.d.xml
@@ -169,7 +169,15 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
                                 <varlistentry>
                                         <term><varname>p</varname></term>
-                                        <listitem><para>Create a named pipe (FIFO) if it does not exist yet.</para></listitem>
+                                        <term><varname>p+</varname></term>
+                                        <listitem><para>Create a named
+                                        pipe (FIFO) if it does not
+                                        exist yet. If suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        pipe is to be created it will
+                                        be removed and be replaced by
+                                        the pipe.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
@@ -188,12 +196,31 @@ L    /tmp/foobar -    -    -    -   /dev/null</programlisting>
 
                                 <varlistentry>
                                         <term><varname>c</varname></term>
-                                        <listitem><para>Create a character device node if it does not exist yet.</para></listitem>
+                                        <term><varname>c+</varname></term>
+                                        <listitem><para>Create a
+                                        character device node if it
+                                        does not exist yet. If
+                                        suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        device node is to be created
+                                        it will be removed and be
+                                        replaced by the device
+                                        node.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
                                         <term><varname>b</varname></term>
-                                        <listitem><para>Create a block device node if it does not exist yet.</para></listitem>
+                                        <term><varname>b+</varname></term>
+                                        <listitem><para>Create a block
+                                        device node if it does not
+                                        exist yet. If suffixed with
+                                        <varname>+</varname> and a
+                                        file already exists where the
+                                        device node is to be created
+                                        it will be removed and be
+                                        replaced by the device
+                                        node.</para></listitem>
                                 </varlistentry>
 
                                 <varlistentry>
diff --git a/src/shared/util.c b/src/shared/util.c
index fe05820..bce4e63 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -4145,6 +4145,46 @@ int symlink_atomic(const char *from, const char *to) {
         return 0;
 }
 
+int mknod_atomic(const char *path, mode_t mode, dev_t dev) {
+        _cleanup_free_ char *t = NULL;
+
+        assert(path);
+
+        t = tempfn_random(path);
+        if (!t)
+                return -ENOMEM;
+
+        if (mknod(t, mode, dev) < 0)
+                return -errno;
+
+        if (rename(t, path) < 0) {
+                unlink_noerrno(t);
+                return -errno;
+        }
+
+        return 0;
+}
+
+int mkfifo_atomic(const char *path, mode_t mode) {
+        _cleanup_free_ char *t = NULL;
+
+        assert(path);
+
+        t = tempfn_random(path);
+        if (!t)
+                return -ENOMEM;
+
+        if (mkfifo(t, mode) < 0)
+                return -errno;
+
+        if (rename(t, path) < 0) {
+                unlink_noerrno(t);
+                return -errno;
+        }
+
+        return 0;
+}
+
 bool display_is_local(const char *display) {
         assert(display);
 
diff --git a/src/shared/util.h b/src/shared/util.h
index 73f7c0a..6ad43cd 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -523,6 +523,8 @@ int terminal_vhangup(const char *name);
 int vt_disallocate(const char *name);
 
 int symlink_atomic(const char *from, const char *to);
+int mknod_atomic(const char *path, mode_t mode, dev_t dev);
+int mkfifo_atomic(const char *path, mode_t mode);
 
 int fchmod_umask(int fd, mode_t mode);
 
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 0c1c2b1..8ec8252 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -721,25 +721,42 @@ static int create_item(Item *i) {
 
         case CREATE_FIFO:
 
-                label_context_set(i->path, S_IFIFO);
                 RUN_WITH_UMASK(0000) {
+                        label_context_set(i->path, S_IFIFO);
                         r = mkfifo(i->path, i->mode);
+                        label_context_clear();
                 }
-                label_context_clear();
 
-                if (r < 0 && errno != EEXIST) {
-                        log_error("Failed to create fifo %s: %m", i->path);
-                        return -errno;
-                }
+                if (r < 0) {
+                        if (errno != EEXIST) {
+                                log_error("Failed to create fifo %s: %m", i->path);
+                                return -errno;
+                        }
 
-                if (stat(i->path, &st) < 0) {
-                        log_error("stat(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                        if (stat(i->path, &st) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
 
-                if (!S_ISFIFO(st.st_mode)) {
-                        log_error("%s is not a fifo.", i->path);
-                        return -EEXIST;
+                        if (!S_ISFIFO(st.st_mode)) {
+
+                                if (i->force) {
+
+                                        RUN_WITH_UMASK(0000) {
+                                                label_context_set(i->path, S_IFIFO);
+                                                r = mkfifo_atomic(i->path, i->mode);
+                                                label_context_clear();
+                                        }
+
+                                        if (r < 0) {
+                                                log_error("Failed to create fifo %s: %s", i->path, strerror(-r));
+                                                return r;
+                                        }
+                                } else {
+                                        log_debug("%s is not a fifo.", i->path);
+                                        return 0;
+                                }
+                        }
                 }
 
                 r = item_set_perms(i, i->path);
@@ -771,11 +788,13 @@ static int create_item(Item *i) {
                                         label_context_clear();
 
                                         if (r < 0) {
-                                                log_error("symlink(%s, %s) failed: %m", i->argument, i->path);
-                                                return -errno;
+                                                log_error("symlink(%s, %s) failed: %s", i->argument, i->path, strerror(-r));
+                                                return r;
                                         }
-                                } else
+                                } else {
                                         log_debug("%s is not a symlink or does not point to the correct path.", i->path);
+                                        return 0;
+                                }
                         }
                 }
 
@@ -795,7 +814,7 @@ static int create_item(Item *i) {
                         return 0;
                 }
 
-                file_type = (i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR);
+                file_type = i->type == CREATE_BLOCK_DEVICE ? S_IFBLK : S_IFCHR;
 
                 RUN_WITH_UMASK(0000) {
                         label_context_set(i->path, file_type);
@@ -814,16 +833,31 @@ static int create_item(Item *i) {
                                 log_error("Failed to create device node %s: %m", i->path);
                                 return -errno;
                         }
-                }
 
-                if (stat(i->path, &st) < 0) {
-                        log_error("stat(%s) failed: %m", i->path);
-                        return -errno;
-                }
+                        if (stat(i->path, &st) < 0) {
+                                log_error("stat(%s) failed: %m", i->path);
+                                return -errno;
+                        }
 
-                if ((st.st_mode & S_IFMT) != file_type) {
-                        log_error("%s is not a device node.", i->path);
-                        return -EEXIST;
+                        if ((st.st_mode & S_IFMT) != file_type) {
+
+                                if (i->force) {
+
+                                        RUN_WITH_UMASK(0000) {
+                                                label_context_set(i->path, file_type);
+                                                r = mknod_atomic(i->path, i->mode | file_type, i->major_minor);
+                                                label_context_clear();
+                                        }
+
+                                        if (r < 0) {
+                                                log_error("Failed to create device node %s: %s", i->path, strerror(-r));
+                                                return r;
+                                        }
+                                } else {
+                                        log_debug("%s is not a device node.", i->path);
+                                        return 0;
+                                }
+                        }
                 }
 
                 r = item_set_perms(i, i->path);



More information about the systemd-commits mailing list