From 2904e949f23aeb17b7e21a2a0f8c43f959a07f98 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 16 Nov 2015 15:25:42 +0100 Subject: tmpfiles: create subvolumes for "v", "q", and "Q" only if / is a subvolume It's not a good idea to create subvolumes for parts of the OS tree (such as /home, or /var) if the root directory is not a subvolume too. We shouldn't assume control of "heavier" objects such as subvolumes, if the originating object (the root directory) is a "light-weight" object, i.e. a plain directory. Effectively this means that chroot() environments that are run on a plain directory do not have to deal with problems around systemd creating subvolumes that cannot be removed with a simple "rm" anymore. However, if the chroot manager creates a proper subvolume for such an environment it will also get further subvolumes placed in there, under the assumption that the manager understands the concept of subvolumes in that case. --- src/basic/btrfs-util.c | 18 +++++++++++++++--- src/basic/btrfs-util.h | 4 +++- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'src/basic') diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index 290fabdeff..8c90e1e4a2 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -105,7 +105,7 @@ int btrfs_is_filesystem(int fd) { return F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC); } -int btrfs_is_subvol(int fd) { +int btrfs_is_subvol_fd(int fd) { struct stat st; assert(fd >= 0); @@ -121,6 +121,18 @@ int btrfs_is_subvol(int fd) { return btrfs_is_filesystem(fd); } +int btrfs_is_subvol(const char *path) { + _cleanup_close_ int fd = -1; + + assert(path); + + fd = open(path, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY); + if (fd < 0) + return -errno; + + return btrfs_is_subvol_fd(fd); +} + int btrfs_subvol_make(const char *path) { struct btrfs_ioctl_vol_args args = {}; _cleanup_close_ int fd = -1; @@ -1682,7 +1694,7 @@ int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlag assert(old_fd >= 0); assert(new_path); - r = btrfs_is_subvol(old_fd); + r = btrfs_is_subvol_fd(old_fd); if (r < 0) return r; if (r == 0) { @@ -1868,7 +1880,7 @@ int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool insert_intermed */ if (subvol_id == 0) { - r = btrfs_is_subvol(fd); + r = btrfs_is_subvol_fd(fd); if (r < 0) return r; if (!r) diff --git a/src/basic/btrfs-util.h b/src/basic/btrfs-util.h index fc9efd72d5..8c11ce35d2 100644 --- a/src/basic/btrfs-util.h +++ b/src/basic/btrfs-util.h @@ -56,7 +56,9 @@ typedef enum BtrfsRemoveFlags { } BtrfsRemoveFlags; int btrfs_is_filesystem(int fd); -int btrfs_is_subvol(int fd); + +int btrfs_is_subvol_fd(int fd); +int btrfs_is_subvol(const char *path); int btrfs_reflink(int infd, int outfd); int btrfs_clone_range(int infd, uint64_t in_offset, int ofd, uint64_t out_offset, uint64_t sz); -- cgit v1.2.3-54-g00ecf