[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