1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-01-08 21:17:47 +03:00

Merge pull request #1915 from poettering/btrfs-root-subvol

tmpfiles: create subvolumes for "v", "q", and "Q" only if / is a subv…
This commit is contained in:
David Herrmann 2015-11-16 15:48:21 +01:00
commit 920a726221
4 changed files with 49 additions and 13 deletions

View File

@ -169,13 +169,15 @@
<varlistentry>
<term><varname>v</varname></term>
<listitem><para>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 <varname>d</varname>. A subvolume created with this
line type is not assigned to any higher-level quota
group. For that, use <varname>q</varname> or
<varname>Q</varname>, which allow creating simple quota group
hierarchies, see below.</para></listitem>
exist yet, the file system supports subvolumes (btrfs), and
the system itself is installed into a subvolume
(specifically: the root directory <filename>/</filename> is
itself a subvolume). Otherwise, create a normal directory, in
the same way as <varname>d</varname>. A subvolume created
with this line type is not assigned to any higher-level
quota group. For that, use <varname>q</varname> or
<varname>Q</varname>, which allow creating simple quota
group hierarchies, see below.</para></listitem>
</varlistentry>
<varlistentry>

View File

@ -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;
@ -1686,7 +1698,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) {
@ -1872,7 +1884,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)

View File

@ -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);

View File

@ -1226,8 +1226,28 @@ static int create_item(Item *i) {
mkdir_parents_label(i->path, 0755);
if (IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) {
RUN_WITH_UMASK((~i->mode) & 0777)
r = btrfs_subvol_make(i->path);
if (btrfs_is_subvol(isempty(arg_root) ? "/" : arg_root) <= 0)
/* Don't create a subvolume unless the
* root directory is one, too. We do
* this under the assumption that if
* the root directory is just a plain
* directory (i.e. very light-weight),
* we shouldn't try to split it up
* into subvolumes (i.e. more
* heavy-weight). Thus, chroot()
* environments and suchlike will get
* a full brtfs subvolume set up below
* their tree only if they
* specifically set up a btrfs
* subvolume for the root dir too. */
r = -ENOTTY;
else {
RUN_WITH_UMASK((~i->mode) & 0777)
r = btrfs_subvol_make(i->path);
}
} else
r = 0;