From d7b8eec7dc7fe307d3a08b32cf1a9ad4276ce6d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 27 Dec 2014 18:46:36 +0100 Subject: [PATCH] tmpfiles: add new line type 'v' for creating btrfs subvolumes --- man/tmpfiles.d.xml | 11 +++++++++++ src/core/main.c | 7 ++++--- src/core/namespace.c | 3 ++- src/core/socket.c | 1 + src/hostname/hostnamed.c | 1 + src/locale/localed.c | 1 + src/login/logind-dbus.c | 3 ++- src/resolve/resolved.c | 1 + src/shared/btrfs-util.c | 20 ++++++++++++++++++++ src/shared/btrfs-util.h | 1 + src/shared/fileio-label.c | 5 +++-- src/shared/label.c | 4 +++- src/shared/label.h | 4 ++-- src/shared/socket-label.c | 3 ++- src/sysusers/sysusers.c | 1 + src/test/test-udev.c | 1 + src/timedate/timedated.c | 1 + src/tmpfiles/tmpfiles.c | 28 +++++++++++++++++++++++----- src/udev/udev-node.c | 1 + src/udev/udevadm.c | 1 + src/udev/udevd.c | 7 ++++--- src/update-done/update-done.c | 1 + 22 files changed, 87 insertions(+), 19 deletions(-) diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 4f2e6406a..398b3f732 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -167,6 +167,17 @@ L /tmp/foobar - - - - /dev/null Create or empty a directory. + + v + Create a + subvolume if the path does not + exist yet and the file system + supports this (btrfs). Otherwise + create a normal directory, in + the same way as + d. + + p p+ diff --git a/src/core/main.c b/src/core/main.c index 300567a92..87d54caac 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -42,9 +42,7 @@ #include "sd-daemon.h" #include "sd-messages.h" #include "sd-bus.h" -#include "manager.h" #include "log.h" -#include "load-fragment.h" #include "fdset.h" #include "special.h" #include "conf-parser.h" @@ -64,9 +62,12 @@ #include "env-util.h" #include "clock-util.h" #include "fileio.h" -#include "dbus-manager.h" #include "bus-error.h" #include "bus-util.h" +#include "selinux-util.h" +#include "manager.h" +#include "dbus-manager.h" +#include "load-fragment.h" #include "mount-setup.h" #include "loopback-setup.h" diff --git a/src/core/namespace.c b/src/core/namespace.c index 4c411096a..5b408e06a 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -35,7 +35,6 @@ #include "strv.h" #include "util.h" #include "path-util.h" -#include "namespace.h" #include "missing.h" #include "execute.h" #include "loopback-setup.h" @@ -43,6 +42,8 @@ #include "dev-setup.h" #include "def.h" #include "label.h" +#include "selinux-util.h" +#include "namespace.h" typedef enum MountMode { /* This is ordered by priority! */ diff --git a/src/core/socket.c b/src/core/socket.c index 8fa55e0b0..b671fffc5 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -48,6 +48,7 @@ #include "smack-util.h" #include "bus-util.h" #include "bus-error.h" +#include "selinux-util.h" #include "dbus-socket.h" #include "unit.h" #include "socket.h" diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index b230ff6d5..7cd4a1d00 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -33,6 +33,7 @@ #include "label.h" #include "bus-util.h" #include "event-util.h" +#include "selinux-util.h" #define VALID_DEPLOYMENT_CHARS (DIGITS LETTERS "-.:") diff --git a/src/locale/localed.c b/src/locale/localed.c index 072354162..529a9abfd 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -39,6 +39,7 @@ #include "bus-message.h" #include "event-util.h" #include "locale-util.h" +#include "selinux-util.h" #ifdef HAVE_XKBCOMMON #include diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index c0d130947..26ce8fe11 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -39,9 +39,10 @@ #include "audit.h" #include "bus-util.h" #include "bus-error.h" -#include "logind.h" #include "bus-common-errors.h" #include "udev-util.h" +#include "selinux-util.h" +#include "logind.h" static int property_get_idle_hint( sd_bus *bus, diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c index c0ab947c0..ce15a8011 100644 --- a/src/resolve/resolved.c +++ b/src/resolve/resolved.c @@ -24,6 +24,7 @@ #include "mkdir.h" #include "label.h" #include "capability.h" +#include "selinux-util.h" #include "resolved-manager.h" #include "resolved-conf.h" diff --git a/src/shared/btrfs-util.c b/src/shared/btrfs-util.c index 84c81106f..9b47330a6 100644 --- a/src/shared/btrfs-util.c +++ b/src/shared/btrfs-util.c @@ -33,6 +33,8 @@ #include "macro.h" #include "strv.h" #include "copy.h" +#include "selinux-util.h" +#include "smack-util.h" #include "btrfs-ctree.h" #include "btrfs-util.h" @@ -184,6 +186,24 @@ int btrfs_subvol_make(const char *path) { return 0; } +int btrfs_subvol_make_label(const char *path) { + int r; + + assert(path); + + r = mac_selinux_create_file_prepare(path, S_IFDIR); + if (r < 0) + return r; + + r = btrfs_subvol_make(path); + mac_selinux_create_file_clear(); + + if (r < 0) + return r; + + return mac_smack_fix(path, false, false); +} + int btrfs_subvol_remove(const char *path) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; diff --git a/src/shared/btrfs-util.h b/src/shared/btrfs-util.h index f51f37a65..dff8c015a 100644 --- a/src/shared/btrfs-util.h +++ b/src/shared/btrfs-util.h @@ -37,6 +37,7 @@ typedef struct BtrfsSubvolInfo { int btrfs_is_snapshot(int fd); int btrfs_subvol_make(const char *path); +int btrfs_subvol_make_label(const char *path); int btrfs_subvol_remove(const char *path); int btrfs_subvol_snapshot(const char *old_path, const char *new_path, bool read_only, bool fallback_copy); diff --git a/src/shared/fileio-label.c b/src/shared/fileio-label.c index 294c9e6ba..5fd69e058 100644 --- a/src/shared/fileio-label.c +++ b/src/shared/fileio-label.c @@ -23,9 +23,10 @@ #include #include -#include "fileio-label.h" -#include "label.h" #include "util.h" +#include "selinux-util.h" +#include "label.h" +#include "fileio-label.h" int write_string_file_atomic_label(const char *fn, const char *line) { int r; diff --git a/src/shared/label.c b/src/shared/label.c index 0af41afa7..82f10b21b 100644 --- a/src/shared/label.c +++ b/src/shared/label.c @@ -19,8 +19,10 @@ along with systemd; If not, see . ***/ -#include "label.h" +#include "selinux-util.h" +#include "smack-util.h" #include "util.h" +#include "label.h" int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs) { int r, q; diff --git a/src/shared/label.h b/src/shared/label.h index 3428a8bb7..8070bcb02 100644 --- a/src/shared/label.h +++ b/src/shared/label.h @@ -21,8 +21,8 @@ along with systemd; If not, see . ***/ -#include "selinux-util.h" -#include "smack-util.h" +#include +#include int label_fix(const char *path, bool ignore_enoent, bool ignore_erofs); diff --git a/src/shared/socket-label.c b/src/shared/socket-label.c index b1ef19f26..6806c5115 100644 --- a/src/shared/socket-label.c +++ b/src/shared/socket-label.c @@ -35,9 +35,10 @@ #include "macro.h" #include "util.h" #include "mkdir.h" -#include "socket-util.h" #include "missing.h" #include "label.h" +#include "selinux-util.h" +#include "socket-util.h" int socket_address_listen( const SocketAddress *a, diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 0baa2c39d..5d5f5ea79 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -39,6 +39,7 @@ #include "label.h" #include "fileio-label.h" #include "uid-range.h" +#include "selinux-util.h" typedef enum ItemType { ADD_USER = 'u', diff --git a/src/test/test-udev.c b/src/test/test-udev.c index f2283ec7a..b57d275ef 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -32,6 +32,7 @@ #include #include "missing.h" +#include "selinux-util.h" #include "udev.h" #include "udev-util.h" diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index d50720064..753c3d1d6 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -40,6 +40,7 @@ #include "bus-error.h" #include "bus-common-errors.h" #include "event-util.h" +#include "selinux-util.h" #define NULL_ADJTIME_UTC "0.0 0 0\n0\nUTC\n" #define NULL_ADJTIME_LOCAL "0.0 0 0\n0\nLOCAL\n" diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 44ea51e26..b83085087 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -54,6 +54,8 @@ #include "specifier.h" #include "build.h" #include "copy.h" +#include "selinux-util.h" +#include "btrfs-util.h" /* This reads all files listed in /etc/tmpfiles.d/?*.conf and creates * them in the file system. This is intended to be used to create @@ -66,6 +68,7 @@ typedef enum ItemType { TRUNCATE_FILE = 'F', CREATE_DIRECTORY = 'd', TRUNCATE_DIRECTORY = 'D', + CREATE_SUBVOLUME = 'v', CREATE_FIFO = 'p', CREATE_SYMLINK = 'L', CREATE_CHAR_DEVICE = 'c', @@ -758,17 +761,27 @@ static int create_item(Item *i) { break; - case TRUNCATE_DIRECTORY: case CREATE_DIRECTORY: + case TRUNCATE_DIRECTORY: + case CREATE_SUBVOLUME: - RUN_WITH_UMASK(0000) { + RUN_WITH_UMASK(0000) mkdir_parents_label(i->path, 0755); - r = mkdir_label(i->path, i->mode); + + if (i->type == CREATE_SUBVOLUME) { + RUN_WITH_UMASK((~i->mode) & 0777) + r = btrfs_subvol_make(i->path); + } else + r = 0; + + if (i->type == CREATE_DIRECTORY || r == -ENOTTY) { + RUN_WITH_UMASK(0000) + r = mkdir_label(i->path, i->mode); } if (r < 0) { if (r != -EEXIST) - return log_error_errno(r, "Failed to create directory %s: %m", i->path); + return log_error_errno(r, "Failed to create directory or subvolume %s: %m", i->path); if (stat(i->path, &st) < 0) return log_error_errno(errno, "stat(%s) failed: %m", i->path); @@ -970,6 +983,7 @@ static int remove_item_instance(Item *i, const char *instance) { case CREATE_FILE: case TRUNCATE_FILE: case CREATE_DIRECTORY: + case CREATE_SUBVOLUME: case CREATE_FIFO: case CREATE_SYMLINK: case CREATE_BLOCK_DEVICE: @@ -1014,6 +1028,7 @@ static int remove_item(Item *i) { case CREATE_FILE: case TRUNCATE_FILE: case CREATE_DIRECTORY: + case CREATE_SUBVOLUME: case CREATE_FIFO: case CREATE_SYMLINK: case CREATE_CHAR_DEVICE: @@ -1091,6 +1106,7 @@ static int clean_item(Item *i) { switch (i->type) { case CREATE_DIRECTORY: + case CREATE_SUBVOLUME: case TRUNCATE_DIRECTORY: case IGNORE_PATH: case COPY_FILES: @@ -1289,6 +1305,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { case CREATE_FILE: case TRUNCATE_FILE: case CREATE_DIRECTORY: + case CREATE_SUBVOLUME: case TRUNCATE_DIRECTORY: case CREATE_FIFO: case IGNORE_PATH: @@ -1429,6 +1446,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { } else i->mode = i->type == CREATE_DIRECTORY || + i->type == CREATE_SUBVOLUME || i->type == TRUNCATE_DIRECTORY ? 0755 : 0644; if (age && !streq(age, "-")) { @@ -1636,7 +1654,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) { continue; HASHMAP_FOREACH(j, items, iter) { - if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY) + if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY && j->type != CREATE_SUBVOLUME) continue; if (path_equal(j->path, i->path)) { diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index c30a428ea..499feefce 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -31,6 +31,7 @@ #include "udev.h" #include "smack-util.h" +#include "selinux-util.h" static int node_symlink(struct udev_device *dev, const char *node, const char *slink) { struct stat stats; diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index d9bd69742..a957e9270 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -24,6 +24,7 @@ #include #include +#include "selinux-util.h" #include "udev.h" static int adm_version(struct udev *udev, int argc, char *argv[]) { diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c3678259b..3edb29bde 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -46,13 +46,14 @@ #include #include -#include "udev.h" -#include "udev-util.h" -#include "rtnl-util.h" #include "sd-daemon.h" +#include "rtnl-util.h" #include "cgroup-util.h" #include "dev-setup.h" #include "fileio.h" +#include "selinux-util.h" +#include "udev.h" +#include "udev-util.h" static struct udev_rules *rules; static struct udev_ctrl *udev_ctrl; diff --git a/src/update-done/update-done.c b/src/update-done/update-done.c index a910808d0..561963e5e 100644 --- a/src/update-done/update-done.c +++ b/src/update-done/update-done.c @@ -21,6 +21,7 @@ #include "util.h" #include "label.h" +#include "selinux-util.h" #define MESSAGE \ "This file was created by systemd-update-done. Its only \n" \ -- 2.30.2