Merge pull request #1641 from poettering/btrfs-quota

btrfs quota beef up and various other unrelated changes
This commit is contained in:
Daniel Mack
2015-10-23 10:50:53 +02:00
35 changed files with 1319 additions and 201 deletions
+2 -3
View File
@@ -26,6 +26,8 @@ External:
Features:
* do something about "/control" subcgroups in the unified cgroup hierarchy
* when we detect that there are waiting jobs but no running jobs, do something
* push CPUAffinity also into the "cpuset" cgroup controller
@@ -136,9 +138,6 @@ Features:
* .timer units should optionally support CLOCK_BOOTTIME in addition to CLOCK_MONOTONIC
* create a btrfs qgroup for /var/lib/machines, and add all container
subvolumes we create to it.
* When logging about multiple units (stopping BoundTo units, conflicts, etc.),
log both units as UNIT=, so that journalctl -u triggers on both.
+81 -11
View File
@@ -1,5 +1,4 @@
<?xml version="1.0"?>
<!--*-nxml-*-->
<?xml version='1.0'?> <!--*- Mode: nxml; nxml-child-indent: 2; indent-tabs-mode: nil -*-->
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!--
This file is part of systemd.
@@ -172,7 +171,77 @@
<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>.</para></listitem>
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>
<term><varname>q</varname></term>
<listitem><para>Similar to <varname>v</varname>, however
makes sure that the subvolume will be assigned to the same
higher-level quota groups as the subvolume it has been
created in. This ensures that higher-level limits and
accounting applied to the parent subvolume also include the
specified subvolume. On non-btrfs file systems, this line
type is identical to <varname>d</varname>. If the subvolume
already exists and is already assigned to one or more higher
level quota groups no change to the quota hierarchy is
made. Also see <varname>Q</varname> below. See <citerefentry
project='die-net'><refentrytitle>btrfs-qgroup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details about the btrfs quota group
concept.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Q</varname></term>
<listitem><para>Similar to <varname>q</varname>, however
instead of copying the higher-level quota group assignments
from the parent as-is, the lowest quota group of the parent
subvolume is determined that is not the leaf quota
group. Then, an "intermediary" quota group is inserted that
is one level below this level, and shares the same ID part
as the specified subvolume. If no higher-level quota group
exists for the parent subvolume, a new quota group at level
255 sharing the same ID as the specified subvolume is
inserted instead. This new intermediary quota group is then
assigned to the parent subvolume's higher-level quota
groups, and the specified subvolume's leaf quota group is
assigned to it.</para>
<para>Effectively, this has a similar effect as
<varname>q</varname>, however introduces a new higher-level
quota group for the specified subvolume that may be used to
enforce limits and accounting to the specified subvolume and
children subvolume created within it. Thus, by creating
subvolumes only via <varname>q</varname> and
<varname>Q</varname> a concept of "subtree quotas" is
implemented. Each subvolume for which <varname>Q</varname>
is set will get a "subtree" quota group created, and all
child subvolumes created within it will be assigned to
it. Each subvolume for which <varname>q</varname> is set
will not get such a "subtree" quota group, but it is ensured
that they are added to the same "subtree" quota group as their
immediate parents.</para>
<para>It is recommended to use
<varname>Q</varname> for subvolumes that typically contain
further subvolumes, and where it is desirable to have
accounting and quota limits on all child subvolumes
together. Examples for <varname>Q</varname> are typically
<filename>/home</filename> or
<filename>/var/lib/machines</filename>. In contrast,
<varname>q</varname> should be used for subvolumes that
either usually do not include further subvolumes or where no
accounting and quota limits are needed that apply to all
child subvolumes together. Examples for <varname>q</varname>
are typically <filename>/var</filename> or
<filename>/var/tmp</filename>. As with <varname>Q</varname>,
<varname>q</varname> has no effect on the quota group
hierarchy if the subvolume exists and already has at least
one higher-level quota group assigned.</para></listitem>
</varlistentry>
<varlistentry>
@@ -504,13 +573,12 @@
<para>When the age is set to zero, the files are cleaned
unconditionally.</para>
<para>The age field only applies to lines
starting with <varname>d</varname>,
<varname>D</varname>, <varname>v</varname>,
<varname>C</varname>, <varname>x</varname> and
<varname>X</varname>. If omitted or set to
<literal>-</literal>, no automatic clean-up is
done.</para>
<para>The age field only applies to lines starting with
<varname>d</varname>, <varname>D</varname>,
<varname>v</varname>, <varname>q</varname>,
<varname>Q</varname>, <varname>C</varname>, <varname>x</varname>
and <varname>X</varname>. If omitted or set to
<literal>-</literal>, no automatic clean-up is done.</para>
<para>If the age field starts with a tilde character
<literal>~</literal>, the clean-up is only applied to files and
@@ -572,7 +640,9 @@ x /var/tmp/abrt/*</programlisting>
<citerefentry project='man-pages'><refentrytitle>setfattr</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>setfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>getfacl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>chattr</refentrytitle><manvolnum>1</manvolnum></citerefentry>
<citerefentry project='man-pages'><refentrytitle>chattr</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>btrfs-subvolume</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry project='die-net'><refentrytitle>btrfs-qgroup</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
+852 -53
View File
File diff suppressed because it is too large Load Diff
+57 -20
View File
@@ -47,25 +47,17 @@ typedef enum BtrfsSnapshotFlags {
BTRFS_SNAPSHOT_FALLBACK_COPY = 1,
BTRFS_SNAPSHOT_READ_ONLY = 2,
BTRFS_SNAPSHOT_RECURSIVE = 4,
BTRFS_SNAPSHOT_QUOTA = 8,
} BtrfsSnapshotFlags;
typedef enum BtrfsRemoveFlags {
BTRFS_REMOVE_RECURSIVE = 1,
BTRFS_REMOVE_QUOTA = 2,
} BtrfsRemoveFlags;
int btrfs_is_filesystem(int fd);
int btrfs_is_subvol(int fd);
int btrfs_subvol_make(const char *path);
int btrfs_subvol_make_label(const char *path);
int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlags flags);
int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnapshotFlags flags);
int btrfs_subvol_set_read_only_fd(int fd, bool b);
int btrfs_subvol_set_read_only(const char *path, bool b);
int btrfs_subvol_get_read_only_fd(int fd);
int btrfs_subvol_get_id(int fd, const char *subvolume, uint64_t *ret);
int btrfs_subvol_get_id_fd(int fd, uint64_t *ret);
int btrfs_subvol_get_info_fd(int fd, BtrfsSubvolInfo *info);
int btrfs_subvol_get_quota_fd(int fd, BtrfsQuotaInfo *quota);
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);
@@ -78,14 +70,59 @@ int btrfs_defrag(const char *p);
int btrfs_quota_enable_fd(int fd, bool b);
int btrfs_quota_enable(const char *path, bool b);
int btrfs_quota_limit_fd(int fd, uint64_t referenced_max);
int btrfs_quota_limit(const char *path, uint64_t referenced_max);
int btrfs_quota_scan_start(int fd);
int btrfs_quota_scan_wait(int fd);
int btrfs_quota_scan_ongoing(int fd);
int btrfs_resize_loopback_fd(int fd, uint64_t size, bool grow_only);
int btrfs_resize_loopback(const char *path, uint64_t size, bool grow_only);
int btrfs_subvol_remove(const char *path, bool recursive);
int btrfs_subvol_remove_fd(int fd, const char *subvolume, bool recursive);
int btrfs_subvol_make(const char *path);
int btrfs_subvol_make_label(const char *path);
int btrfs_qgroup_create(int fd, uint64_t level, uint64_t id);
int btrfs_qgroup_destroy(int fd, uint64_t level, uint64_t id);
int btrfs_subvol_snapshot_fd(int old_fd, const char *new_path, BtrfsSnapshotFlags flags);
int btrfs_subvol_snapshot(const char *old_path, const char *new_path, BtrfsSnapshotFlags flags);
int btrfs_subvol_remove(const char *path, BtrfsRemoveFlags flags);
int btrfs_subvol_remove_fd(int fd, const char *subvolume, BtrfsRemoveFlags flags);
int btrfs_subvol_set_read_only_fd(int fd, bool b);
int btrfs_subvol_set_read_only(const char *path, bool b);
int btrfs_subvol_get_read_only_fd(int fd);
int btrfs_subvol_get_id(int fd, const char *subvolume, uint64_t *ret);
int btrfs_subvol_get_id_fd(int fd, uint64_t *ret);
int btrfs_subvol_get_parent(int fd, uint64_t subvol_id, uint64_t *ret);
int btrfs_subvol_get_info_fd(int fd, uint64_t subvol_id, BtrfsSubvolInfo *info);
int btrfs_subvol_find_subtree_qgroup(int fd, uint64_t subvol_id, uint64_t *ret);
int btrfs_subvol_get_subtree_quota(const char *path, uint64_t subvol_id, BtrfsQuotaInfo *quota);
int btrfs_subvol_get_subtree_quota_fd(int fd, uint64_t subvol_id, BtrfsQuotaInfo *quota);
int btrfs_subvol_set_subtree_quota_limit(const char *path, uint64_t subvol_id, uint64_t referenced_max);
int btrfs_subvol_set_subtree_quota_limit_fd(int fd, uint64_t subvol_id, uint64_t referenced_max);
int btrfs_subvol_auto_qgroup_fd(int fd, uint64_t subvol_id, bool new_qgroup);
int btrfs_subvol_auto_qgroup(const char *path, uint64_t subvol_id, bool create_intermediary_qgroup);
int btrfs_qgroupid_make(uint64_t level, uint64_t id, uint64_t *ret);
int btrfs_qgroupid_split(uint64_t qgroupid, uint64_t *level, uint64_t *id);
int btrfs_qgroup_create(int fd, uint64_t qgroupid);
int btrfs_qgroup_destroy(int fd, uint64_t qgroupid);
int btrfs_qgroup_destroy_recursive(int fd, uint64_t qgroupid);
int btrfs_qgroup_set_limit_fd(int fd, uint64_t qgroupid, uint64_t referenced_max);
int btrfs_qgroup_set_limit(const char *path, uint64_t qgroupid, uint64_t referenced_max);
int btrfs_qgroup_copy_limits(int fd, uint64_t old_qgroupid, uint64_t new_qgroupid);
int btrfs_qgroup_assign(int fd, uint64_t child, uint64_t parent);
int btrfs_qgroup_unassign(int fd, uint64_t child, uint64_t parent);
int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret);
int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *quota);
int btrfs_qgroup_get_quota(const char *path, uint64_t qgroupid, BtrfsQuotaInfo *quota);
+4
View File
@@ -494,6 +494,10 @@ struct btrfs_ioctl_quota_ctl_args {
#define BTRFS_QGROUP_LIMIT_KEY 244
#endif
#ifndef BTRFS_QGROUP_RELATION_KEY
#define BTRFS_QGROUP_RELATION_KEY 246
#endif
#ifndef BTRFS_ROOT_BACKREF_KEY
#define BTRFS_ROOT_BACKREF_KEY 144
#endif
+18 -5
View File
@@ -796,14 +796,11 @@ bool paths_check_timestamp(const char* const* paths, usec_t *timestamp, bool upd
return changed;
}
int fsck_exists(const char *fstype) {
static int binary_is_good(const char *binary) {
_cleanup_free_ char *p = NULL, *d = NULL;
const char *checker;
int r;
checker = strjoina("fsck.", fstype);
r = find_binary(checker, true, &p);
r = find_binary(binary, true, &p);
if (r < 0)
return r;
@@ -820,6 +817,22 @@ int fsck_exists(const char *fstype) {
return 0;
}
int fsck_exists(const char *fstype) {
const char *checker;
checker = strjoina("fsck.", fstype);
return binary_is_good(checker);
}
int mkfs_exists(const char *fstype) {
const char *mkfs;
mkfs = strjoina("mkfs.", fstype);
return binary_is_good(mkfs);
}
char *prefix_root(const char *root, const char *path) {
char *n, *p;
size_t l;
+1
View File
@@ -63,6 +63,7 @@ int find_binary(const char *name, bool local, char **filename);
bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
int fsck_exists(const char *fstype);
int mkfs_exists(const char *fstype);
/* Iterates through the path prefixes of the specified path, going up
* the tree, to root. Also returns "" (and not "/"!) for the root
+2 -2
View File
@@ -120,7 +120,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
/* This could be a subvolume, try to remove it */
r = btrfs_subvol_remove_fd(fd, de->d_name, true);
r = btrfs_subvol_remove_fd(fd, de->d_name, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
if (r < 0) {
if (r != -ENOTTY && r != -EINVAL) {
if (ret == 0)
@@ -178,7 +178,7 @@ int rm_rf(const char *path, RemoveFlags flags) {
if ((flags & (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) == (REMOVE_SUBVOLUME|REMOVE_ROOT|REMOVE_PHYSICAL)) {
/* Try to remove as subvolume first */
r = btrfs_subvol_remove(path, true);
r = btrfs_subvol_remove(path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
if (r >= 0)
return r;
+4 -13
View File
@@ -2381,25 +2381,16 @@ bool is_device_path(const char *path) {
int dir_is_empty(const char *path) {
_cleanup_closedir_ DIR *d;
struct dirent *de;
d = opendir(path);
if (!d)
return -errno;
for (;;) {
struct dirent *de;
FOREACH_DIRENT(de, d, return -errno)
return 0;
errno = 0;
de = readdir(d);
if (!de && errno != 0)
return -errno;
if (!de)
return 1;
if (!hidden_file(de->d_name))
return 0;
}
return 1;
}
char* dirname_malloc(const char *path) {
+8
View File
@@ -358,6 +358,14 @@ bool is_device_path(const char *path);
int dir_is_empty(const char *path);
char* dirname_malloc(const char *path);
static inline int dir_is_populated(const char *path) {
int r;
r = dir_is_empty(path);
if (r < 0)
return r;
return !r;
}
char* lookup_uid(uid_t uid);
char* getlogname_malloc(void);
char* getusername_malloc(void);
+4 -5
View File
@@ -1173,7 +1173,6 @@ int bus_exec_context_set_transient_property(
unit_write_drop_in_private_format(u, mode, name, "Environment=%s\n", joined);
}
}
return 1;
@@ -1262,6 +1261,10 @@ int bus_exec_context_set_transient_property(
if (r < 0)
return r;
r = sd_bus_message_exit_container(message);
if (r < 0)
return r;
r = fflush_and_check(f);
if (r < 0)
return r;
@@ -1279,10 +1282,6 @@ int bus_exec_context_set_transient_property(
}
}
r = sd_bus_message_exit_container(message);
if (r < 0)
return r;
return 1;
} else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
+2 -2
View File
@@ -78,7 +78,7 @@ TarExport *tar_export_unref(TarExport *e) {
}
if (e->temp_path) {
(void) btrfs_subvol_remove(e->temp_path, false);
(void) btrfs_subvol_remove(e->temp_path, BTRFS_REMOVE_QUOTA);
free(e->temp_path);
}
@@ -283,7 +283,7 @@ int tar_export_start(TarExport *e, const char *path, int fd, ImportCompressType
if (e->st.st_ino == 256) { /* might be a btrfs subvolume? */
BtrfsQuotaInfo q;
r = btrfs_subvol_get_quota_fd(sfd, &q);
r = btrfs_subvol_get_subtree_quota_fd(sfd, 0, &q);
if (r >= 0)
e->quota_referenced = q.referenced;
+2
View File
@@ -235,6 +235,8 @@ static int tar_import_fork_tar(TarImport *i) {
return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path);
} else if (r < 0)
return log_error_errno(errno, "Failed to create subvolume %s: %m", i->temp_path);
else
(void) import_assign_pool_quota_and_warn(i->temp_path);
i->tar_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
if (i->tar_fd < 0)
+3 -2
View File
@@ -138,7 +138,7 @@ int pull_make_local_copy(const char *final, const char *image_root, const char *
if (force_local)
(void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
r = btrfs_subvol_snapshot(final, p, 0);
r = btrfs_subvol_snapshot(final, p, BTRFS_SNAPSHOT_QUOTA);
if (r == -ENOTTY) {
r = copy_tree(final, p, false);
if (r < 0)
@@ -366,9 +366,10 @@ int pull_verify(PullJob *main_job,
log_info("SHA256 checksum of %s is valid.", main_job->url);
assert(!settings_job || settings_job->state == PULL_JOB_DONE);
assert(!settings_job || IN_SET(settings_job->state, PULL_JOB_DONE, PULL_JOB_FAILED));
if (settings_job &&
settings_job->state == PULL_JOB_DONE &&
settings_job->error == 0 &&
!settings_job->etag_exists) {
+12 -4
View File
@@ -490,10 +490,16 @@ static int dkr_pull_make_local_copy(DkrPull *i, DkrPullVersion version) {
return r;
if (version == DKR_PULL_V2) {
char **k = NULL;
char **k;
STRV_FOREACH(k, i->ancestry) {
_cleanup_free_ char *d = strjoin(i->image_root, "/.dkr-", *k, NULL);
r = btrfs_subvol_remove(d, false);
_cleanup_free_ char *d;
d = strjoin(i->image_root, "/.dkr-", *k, NULL);
if (!d)
return -ENOMEM;
r = btrfs_subvol_remove(d, BTRFS_REMOVE_QUOTA);
if (r < 0)
return r;
}
@@ -531,12 +537,14 @@ static int dkr_pull_job_on_open_disk(PullJob *j) {
const char *base_path;
base_path = strjoina(i->image_root, "/.dkr-", base);
r = btrfs_subvol_snapshot(base_path, i->temp_path, BTRFS_SNAPSHOT_FALLBACK_COPY);
r = btrfs_subvol_snapshot(base_path, i->temp_path, BTRFS_SNAPSHOT_FALLBACK_COPY|BTRFS_SNAPSHOT_QUOTA);
} else
r = btrfs_subvol_make(i->temp_path);
if (r < 0)
return log_error_errno(r, "Failed to make btrfs subvolume %s: %m", i->temp_path);
(void) import_assign_pool_quota_and_warn(i->temp_path);
j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
if (j->disk_fd < 0)
return j->disk_fd;
+3 -3
View File
@@ -349,9 +349,9 @@ static int raw_pull_make_local_copy(RawPull *i) {
if (r == -EEXIST)
log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
else if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to copy settings files %s: %m", local_settings);
log_info("Create new settings file '%s.nspawn'", i->local);
log_warning_errno(r, "Failed to copy settings files %s, ignoring: %m", local_settings);
else
log_info("Created new settings file '%s.nspawn'", i->local);
}
return 0;
+5 -3
View File
@@ -247,9 +247,9 @@ static int tar_pull_make_local_copy(TarPull *i) {
if (r == -EEXIST)
log_warning_errno(r, "Settings file %s already exists, not replacing.", local_settings);
else if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to copy settings files %s: %m", local_settings);
log_info("Create new settings file '%s.nspawn'", i->local);
log_warning_errno(r, "Failed to copy settings files %s, ignoring: %m", local_settings);
else
log_info("Created new settings file '%s.nspawn'", i->local);
}
return 0;
@@ -410,6 +410,8 @@ static int tar_pull_job_on_open_disk_tar(PullJob *j) {
return log_error_errno(errno, "Failed to create directory %s: %m", i->temp_path);
} else if (r < 0)
return log_error_errno(errno, "Failed to create subvolume %s: %m", i->temp_path);
else
(void) import_assign_pool_quota_and_warn(i->temp_path);
j->disk_fd = import_fork_tar_x(i->temp_path, &i->tar_pid);
if (j->disk_fd < 0)
+10 -6
View File
@@ -1049,9 +1049,13 @@ error:
}
void session_restore_vt(Session *s) {
static const struct vt_mode mode = {
.mode = VT_AUTO,
};
_cleanup_free_ char *utf8 = NULL;
int vt, kb = K_XLATE;
struct vt_mode mode = { 0 };
int vt, kb, old_fd;
/* We need to get a fresh handle to the virtual terminal,
* since the old file-descriptor is potentially in a hung-up
@@ -1059,7 +1063,7 @@ void session_restore_vt(Session *s) {
* little dance to avoid having the terminal be available
* for reuse before we've cleaned it up.
*/
int old_fd = s->vtfd;
old_fd = s->vtfd;
s->vtfd = -1;
vt = session_open_vt(s);
@@ -1072,13 +1076,13 @@ void session_restore_vt(Session *s) {
if (read_one_line_file("/sys/module/vt/parameters/default_utf8", &utf8) >= 0 && *utf8 == '1')
kb = K_UNICODE;
else
kb = K_XLATE;
(void) ioctl(vt, KDSKBMODE, kb);
mode.mode = VT_AUTO;
(void) ioctl(vt, VT_SETMODE, &mode);
fchown(vt, 0, -1);
(void) fchown(vt, 0, (gid_t) -1);
s->vtfd = safe_close(s->vtfd);
}
+1 -1
View File
@@ -2382,7 +2382,7 @@ static int set_limit(int argc, char *argv[], void *userdata) {
uint64_t limit;
int r;
if (streq(argv[argc-1], "-"))
if (STR_IN_SET(argv[argc-1], "-", "none", "infinity"))
limit = (uint64_t) -1;
else {
r = parse_size(argv[argc-1], 1024, &limit);
+5 -3
View File
@@ -79,7 +79,7 @@ static int property_get_pool_usage(
if (fd >= 0) {
BtrfsQuotaInfo q;
if (btrfs_subvol_get_quota_fd(fd, &q) >= 0)
if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
usage = q.referenced;
}
@@ -115,7 +115,7 @@ static int property_get_pool_limit(
if (fd >= 0) {
BtrfsQuotaInfo q;
if (btrfs_subvol_get_quota_fd(fd, &q) >= 0)
if (btrfs_subvol_get_subtree_quota_fd(fd, 0, &q) >= 0)
size = q.referenced_max;
}
@@ -831,7 +831,9 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
if (r < 0 && r != -ENODEV) /* ignore ENODEV, as that's what is returned if the file system is not on loopback */
return sd_bus_error_set_errnof(error, r, "Failed to adjust loopback limit: %m");
r = btrfs_quota_limit("/var/lib/machines", limit);
(void) btrfs_qgroup_set_limit("/var/lib/machines", 0, limit);
r = btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, limit);
if (r == -ENOTTY)
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
if (r < 0)
+20
View File
@@ -85,6 +85,26 @@ Settings* settings_free(Settings *s) {
return NULL;
}
bool settings_private_network(Settings *s) {
assert(s);
return
s->private_network > 0 ||
s->network_veth > 0 ||
s->network_bridge ||
s->network_interfaces ||
s->network_macvlan ||
s->network_ipvlan;
}
bool settings_network_veth(Settings *s) {
assert(s);
return
s->network_veth > 0 ||
s->network_bridge;
}
DEFINE_CONFIG_PARSE_ENUM(config_parse_volatile_mode, volatile_mode, VolatileMode, "Failed to parse volatile mode");
int config_parse_expose_port(
+3
View File
@@ -75,6 +75,9 @@ typedef struct Settings {
int settings_load(FILE *f, const char *path, Settings **ret);
Settings* settings_free(Settings *s);
bool settings_network_veth(Settings *s);
bool settings_private_network(Settings *s);
DEFINE_TRIVIAL_CLEANUP_FUNC(Settings*, settings_free);
const struct ConfigPerfItem* nspawn_gperf_lookup(const char *key, unsigned length);
+19 -15
View File
@@ -2912,11 +2912,17 @@ static int load_settings(void) {
}
if ((arg_settings_mask & SETTING_CAPABILITY) == 0) {
uint64_t plus;
if (!arg_settings_trusted && settings->capability != 0)
log_warning("Ignoring Capability= setting, file %s is not trusted.", p);
else
arg_retain |= settings->capability;
plus = settings->capability;
if (settings_private_network(settings))
plus |= (1ULL << CAP_NET_ADMIN);
if (!arg_settings_trusted && plus != 0) {
if (settings->capability != 0)
log_warning("Ignoring Capability= setting, file %s is not trusted.", p);
} else
arg_retain |= plus;
arg_retain &= ~settings->drop_capability;
}
@@ -2972,6 +2978,9 @@ static int load_settings(void) {
if (!arg_settings_trusted)
log_warning("Ignoring network settings, file %s is not trusted.", p);
else {
arg_network_veth = settings_private_network(settings);
arg_private_network = settings_private_network(settings);
strv_free(arg_network_interfaces);
arg_network_interfaces = settings->network_interfaces;
settings->network_interfaces = NULL;
@@ -2987,10 +2996,6 @@ static int load_settings(void) {
free(arg_network_bridge);
arg_network_bridge = settings->network_bridge;
settings->network_bridge = NULL;
arg_network_veth = settings->network_veth > 0 || settings->network_bridge;
arg_private_network = true; /* all these settings imply private networking */
}
}
@@ -3096,7 +3101,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
r = btrfs_subvol_snapshot(arg_directory, np, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE);
r = btrfs_subvol_snapshot(arg_directory, np, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
if (r < 0) {
log_error_errno(r, "Failed to create snapshot %s from %s: %m", np, arg_directory);
goto finish;
@@ -3120,7 +3125,7 @@ int main(int argc, char *argv[]) {
}
if (arg_template) {
r = btrfs_subvol_snapshot(arg_template, arg_directory, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE);
r = btrfs_subvol_snapshot(arg_template, arg_directory, (arg_read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
if (r == -EEXIST) {
if (!arg_quiet)
log_info("Directory %s already exists, not populating from template %s.", arg_directory, arg_template);
@@ -3143,10 +3148,9 @@ int main(int argc, char *argv[]) {
} else {
const char *p;
p = strjoina(arg_directory,
argc > optind && path_is_absolute(argv[optind]) ? argv[optind] : "/usr/bin/");
if (access(p, F_OK) < 0) {
log_error("Directory %s lacks the binary to execute or doesn't look like a binary tree. Refusing.", arg_directory);
p = strjoina(arg_directory, "/usr/");
if (laccess(p, F_OK) < 0) {
log_error("Directory %s doesn't look like it has an OS tree. Refusing.", arg_directory);
r = -EINVAL;
goto finish;
}
@@ -3591,7 +3595,7 @@ finish:
if (remove_subvol && arg_directory) {
int k;
k = btrfs_subvol_remove(arg_directory, true);
k = btrfs_subvol_remove(arg_directory, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
if (k < 0)
log_warning_errno(k, "Cannot remove subvolume '%s', ignoring: %m", arg_directory);
}
+27
View File
@@ -19,6 +19,7 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "btrfs-util.h"
#include "util.h"
#include "import-util.h"
@@ -201,3 +202,29 @@ bool dkr_id_is_valid(const char *id) {
return true;
}
int import_assign_pool_quota_and_warn(const char *path) {
int r;
r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
if (r == -ENOTTY) {
log_debug_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, as directory is not on btrfs or not a subvolume. Ignoring.");
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines: %m");
if (r > 0)
log_info("Set up default quota hierarchy for /var/lib/machines.");
r = btrfs_subvol_auto_qgroup(path, 0, true);
if (r == -ENOTTY) {
log_debug_errno(r, "Failed to set up quota hierarchy for %s, as directory is not on btrfs or not a subvolume. Ignoring.", path);
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to set up default quota hierarchy for %s: %m", path);
if (r > 0)
log_info("Set up default quota hierarchy for %s.", path);
return 0;
}
+2
View File
@@ -47,3 +47,5 @@ bool dkr_id_is_valid(const char *id);
bool dkr_ref_is_valid(const char *ref);
bool dkr_digest_is_valid(const char *digest);
#define dkr_tag_is_valid(tag) filename_is_valid(tag)
int import_assign_pool_quota_and_warn(const char *path);
+30 -11
View File
@@ -176,11 +176,10 @@ static int image_make(
return r;
if (r) {
BtrfsSubvolInfo info;
BtrfsQuotaInfo quota;
/* It's a btrfs subvolume */
r = btrfs_subvol_get_info_fd(fd, &info);
r = btrfs_subvol_get_info_fd(fd, 0, &info);
if (r < 0)
return r;
@@ -195,13 +194,17 @@ static int image_make(
if (r < 0)
return r;
r = btrfs_subvol_get_quota_fd(fd, &quota);
if (r >= 0) {
(*ret)->usage = quota.referenced;
(*ret)->usage_exclusive = quota.exclusive;
if (btrfs_quota_scan_ongoing(fd) == 0) {
BtrfsQuotaInfo quota;
(*ret)->limit = quota.referenced_max;
(*ret)->limit_exclusive = quota.exclusive_max;
r = btrfs_subvol_get_subtree_quota_fd(fd, 0, &quota);
if (r >= 0) {
(*ret)->usage = quota.referenced;
(*ret)->usage_exclusive = quota.exclusive;
(*ret)->limit = quota.referenced_max;
(*ret)->limit_exclusive = quota.exclusive_max;
}
}
return 1;
@@ -397,7 +400,7 @@ int image_remove(Image *i) {
switch (i->type) {
case IMAGE_SUBVOLUME:
r = btrfs_subvol_remove(i->path, true);
r = btrfs_subvol_remove(i->path, BTRFS_REMOVE_RECURSIVE|BTRFS_REMOVE_QUOTA);
if (r < 0)
return r;
break;
@@ -587,7 +590,12 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
case IMAGE_DIRECTORY:
new_path = strjoina("/var/lib/machines/", new_name);
r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE);
r = btrfs_subvol_snapshot(i->path, new_path, (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | BTRFS_SNAPSHOT_FALLBACK_COPY | BTRFS_SNAPSHOT_RECURSIVE | BTRFS_SNAPSHOT_QUOTA);
/* Enable "subtree" quotas for the copy, if we didn't
* copy any quota from the source. */
(void) btrfs_subvol_auto_qgroup(i->path, 0, true);
break;
case IMAGE_RAW:
@@ -629,6 +637,10 @@ int image_read_only(Image *i, bool b) {
switch (i->type) {
case IMAGE_SUBVOLUME:
/* Note that we set the flag only on the top-level
* subvolume of the image. */
r = btrfs_subvol_set_read_only(i->path, b);
if (r < 0)
return r;
@@ -729,7 +741,14 @@ int image_set_limit(Image *i, uint64_t referenced_max) {
if (i->type != IMAGE_SUBVOLUME)
return -EOPNOTSUPP;
return btrfs_quota_limit(i->path, referenced_max);
/* We set the quota both for the subvolume as well as for the
* subtree. The latter is mostly for historical reasons, since
* we didn't use to have a concept of subtree quota, and hence
* only modified the subvolume quota. */
(void) btrfs_qgroup_set_limit(i->path, 0, referenced_max);
(void) btrfs_subvol_auto_qgroup(i->path, 0, true);
return btrfs_subvol_set_subtree_quota_limit(i->path, 0, referenced_max);
}
int image_name_lock(const char *name, int operation, LockFile *ret) {
+36 -9
View File
@@ -170,7 +170,7 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
};
_cleanup_close_ int fd = -1, control = -1, loop = -1;
_cleanup_free_ char* loopdev = NULL;
char tmpdir[] = "/tmp/import-mount.XXXXXX", *mntdir = NULL;
char tmpdir[] = "/tmp/machine-pool.XXXXXX", *mntdir = NULL;
bool tmpdir_made = false, mntdir_made = false, mntdir_mounted = false;
char buf[FORMAT_BYTES_MAX];
int r, nr = -1;
@@ -194,14 +194,35 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
r = btrfs_quota_enable("/var/lib/machines", true);
if (r < 0)
log_warning_errno(r, "Failed to enable quota, ignoring: %m");
log_warning_errno(r, "Failed to enable quota for /var/lib/machines, ignoring: %m");
r = btrfs_subvol_auto_qgroup("/var/lib/machines", 0, true);
if (r < 0)
log_warning_errno(r, "Failed to set up default quota hierarchy for /var/lib/machines, ignoring: %m");
return 1;
}
if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0) {
log_debug("/var/lib/machines is already a mount point, not creating loopback file for it.");
return 0;
}
if (path_is_mount_point("/var/lib/machines", AT_SYMLINK_FOLLOW) > 0 ||
dir_is_empty("/var/lib/machines") == 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "/var/lib/machines is not a btrfs file system. Operation is not supported on legacy file systems.");
r = dir_is_populated("/var/lib/machines");
if (r < 0 && r != -ENOENT)
return r;
if (r > 0) {
log_debug("/var/log/machines is already populated, not creating loopback file for it.");
return 0;
}
r = mkfs_exists("btrfs");
if (r == -ENOENT) {
log_debug("mkfs.btrfs is missing, cannot create loopback file for /var/lib/machines.");
return 0;
}
if (r < 0)
return r;
fd = setup_machine_raw(size, error);
if (fd < 0)
@@ -266,6 +287,10 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
if (r < 0)
log_warning_errno(r, "Failed to enable quota, ignoring: %m");
r = btrfs_subvol_auto_qgroup(mntdir, 0, true);
if (r < 0)
log_warning_errno(r, "Failed to set up default quota hierarchy, ignoring: %m");
if (chmod(mntdir, 0700) < 0) {
r = sd_bus_error_set_errnof(error, errno, "Failed to fix owner: %m");
goto fail;
@@ -286,7 +311,7 @@ int setup_machine_directory(uint64_t size, sd_bus_error *error) {
(void) rmdir(mntdir);
(void) rmdir(tmpdir);
return 0;
return 1;
fail:
if (mntdir_mounted)
@@ -370,9 +395,11 @@ int grow_machine_directory(void) {
if (r <= 0)
return r;
r = btrfs_quota_limit("/var/lib/machines", new_size);
if (r < 0)
return r;
/* Also bump the quota, of both the subvolume leaf qgroup, as
* well as of any subtree quota group by the same id but a
* higher level, if it exists. */
(void) btrfs_qgroup_set_limit("/var/lib/machines", 0, new_size);
(void) btrfs_subvol_set_subtree_quota_limit("/var/lib/machines", 0, new_size);
log_info("Grew /var/lib/machines btrfs loopback file system to %s.", format_bytes(buf, sizeof(buf), new_size));
return 1;
+6 -6
View File
@@ -7399,12 +7399,12 @@ static int talk_initctl(void) {
static int systemctl_main(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "list-units", VERB_ANY, 1, VERB_DEFAULT, list_units },
{ "list-unit-files", VERB_ANY, 1, 0, list_unit_files },
{ "list-sockets", VERB_ANY, 1, 0, list_sockets },
{ "list-timers", VERB_ANY, 1, 0, list_timers },
{ "list-jobs", VERB_ANY, 1, 0, list_jobs },
{ "list-machines", VERB_ANY, 1, 0, list_machines },
{ "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT, list_units },
{ "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
{ "list-sockets", VERB_ANY, VERB_ANY, 0, list_sockets },
{ "list-timers", VERB_ANY, VERB_ANY, 0, list_timers },
{ "list-jobs", VERB_ANY, VERB_ANY, 0, list_jobs },
{ "list-machines", VERB_ANY, VERB_ANY, 0, list_machines },
{ "clear-jobs", VERB_ANY, 1, 0, daemon_reload },
{ "cancel", 2, VERB_ANY, 0, cancel_job },
{ "start", 2, VERB_ANY, 0, start_unit },
+58 -10
View File
@@ -27,17 +27,17 @@
#include "btrfs-util.h"
int main(int argc, char *argv[]) {
BtrfsQuotaInfo quota;
int r, fd;
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY);
if (fd < 0)
log_error_errno(errno, "Failed to open root directory: %m");
else {
BtrfsSubvolInfo info;
BtrfsQuotaInfo quota;
char ts[FORMAT_TIMESTAMP_MAX], bs[FORMAT_BYTES_MAX];
BtrfsSubvolInfo info;
r = btrfs_subvol_get_info_fd(fd, &info);
r = btrfs_subvol_get_info_fd(fd, 0, &info);
if (r < 0)
log_error_errno(r, "Failed to get subvolume info: %m");
else {
@@ -45,7 +45,7 @@ int main(int argc, char *argv[]) {
log_info("read-only (search): %s", yes_no(info.read_only));
}
r = btrfs_subvol_get_quota_fd(fd, &quota);
r = btrfs_qgroup_get_quota_fd(fd, 0, &quota);
if (r < 0)
log_error_errno(r, "Failed to get quota info: %m");
else {
@@ -80,15 +80,15 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error_errno(r, "Failed to make snapshot: %m");
r = btrfs_subvol_remove("/xxxtest", false);
r = btrfs_subvol_remove("/xxxtest", BTRFS_REMOVE_QUOTA);
if (r < 0)
log_error_errno(r, "Failed to remove subvolume: %m");
r = btrfs_subvol_remove("/xxxtest2", false);
r = btrfs_subvol_remove("/xxxtest2", BTRFS_REMOVE_QUOTA);
if (r < 0)
log_error_errno(r, "Failed to remove subvolume: %m");
r = btrfs_subvol_remove("/xxxtest3", false);
r = btrfs_subvol_remove("/xxxtest3", BTRFS_REMOVE_QUOTA);
if (r < 0)
log_error_errno(r, "Failed to remove subvolume: %m");
@@ -96,7 +96,7 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error_errno(r, "Failed to make snapshot: %m");
r = btrfs_subvol_remove("/etc2", false);
r = btrfs_subvol_remove("/etc2", BTRFS_REMOVE_QUOTA);
if (r < 0)
log_error_errno(r, "Failed to remove subvolume: %m");
@@ -137,13 +137,61 @@ int main(int argc, char *argv[]) {
if (r < 0)
log_error_errno(r, "Failed to snapshot subvolume: %m");
r = btrfs_subvol_remove("/xxxrectest", true);
r = btrfs_subvol_remove("/xxxrectest", BTRFS_REMOVE_QUOTA|BTRFS_REMOVE_RECURSIVE);
if (r < 0)
log_error_errno(r, "Failed to recursively remove subvolume: %m");
r = btrfs_subvol_remove("/xxxrectest2", true);
r = btrfs_subvol_remove("/xxxrectest2", BTRFS_REMOVE_QUOTA|BTRFS_REMOVE_RECURSIVE);
if (r < 0)
log_error_errno(r, "Failed to recursively remove subvolume: %m");
r = btrfs_subvol_make("/xxxquotatest");
if (r < 0)
log_error_errno(r, "Failed to make subvolume: %m");
r = btrfs_subvol_auto_qgroup("/xxxquotatest", 0, true);
if (r < 0)
log_error_errno(r, "Failed to set up auto qgroup: %m");
r = btrfs_subvol_make("/xxxquotatest/beneath");
if (r < 0)
log_error_errno(r, "Failed to make subvolume: %m");
r = btrfs_subvol_auto_qgroup("/xxxquotatest/beneath", 0, false);
if (r < 0)
log_error_errno(r, "Failed to set up auto qgroup: %m");
r = btrfs_qgroup_set_limit("/xxxquotatest/beneath", 0, 4ULL * 1024 * 1024 * 1024);
if (r < 0)
log_error_errno(r, "Failed to set up quota limit: %m");
r = btrfs_subvol_set_subtree_quota_limit("/xxxquotatest", 0, 5ULL * 1024 * 1024 * 1024);
if (r < 0)
log_error_errno(r, "Failed to set up quota limit: %m");
r = btrfs_subvol_snapshot("/xxxquotatest", "/xxxquotatest2", BTRFS_SNAPSHOT_RECURSIVE|BTRFS_SNAPSHOT_QUOTA);
if (r < 0)
log_error_errno(r, "Failed to setup snapshot: %m");
r = btrfs_qgroup_get_quota("/xxxquotatest2/beneath", 0, &quota);
if (r < 0)
log_error_errno(r, "Failed to query quota: %m");
assert_se(quota.referenced_max == 4ULL * 1024 * 1024 * 1024);
r = btrfs_subvol_get_subtree_quota("/xxxquotatest2", 0, &quota);
if (r < 0)
log_error_errno(r, "Failed to query quota: %m");
assert_se(quota.referenced_max == 5ULL * 1024 * 1024 * 1024);
r = btrfs_subvol_remove("/xxxquotatest", BTRFS_REMOVE_QUOTA|BTRFS_REMOVE_RECURSIVE);
if (r < 0)
log_error_errno(r, "Failed remove subvolume: %m");
r = btrfs_subvol_remove("/xxxquotatest2", BTRFS_REMOVE_QUOTA|BTRFS_REMOVE_RECURSIVE);
if (r < 0)
log_error_errno(r, "Failed remove subvolume: %m");
return 0;
}
+35 -8
View File
@@ -69,6 +69,8 @@ typedef enum ItemType {
CREATE_DIRECTORY = 'd',
TRUNCATE_DIRECTORY = 'D',
CREATE_SUBVOLUME = 'v',
CREATE_SUBVOLUME_INHERIT_QUOTA = 'q',
CREATE_SUBVOLUME_NEW_QUOTA = 'Q',
CREATE_FIFO = 'p',
CREATE_SYMLINK = 'L',
CREATE_CHAR_DEVICE = 'c',
@@ -180,6 +182,8 @@ static bool takes_ownership(ItemType t) {
CREATE_DIRECTORY,
TRUNCATE_DIRECTORY,
CREATE_SUBVOLUME,
CREATE_SUBVOLUME_INHERIT_QUOTA,
CREATE_SUBVOLUME_NEW_QUOTA,
CREATE_FIFO,
CREATE_SYMLINK,
CREATE_CHAR_DEVICE,
@@ -1198,16 +1202,16 @@ static int create_item(Item *i) {
case CREATE_DIRECTORY:
case TRUNCATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
RUN_WITH_UMASK(0000)
mkdir_parents_label(i->path, 0755);
if (i->type == CREATE_SUBVOLUME)
RUN_WITH_UMASK((~i->mode) & 0777) {
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);
log_debug_errno(r, "Creating subvolume \"%s\": %m", i->path);
}
else
} else
r = 0;
if (IN_SET(i->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY) || r == -ENOTTY)
@@ -1236,6 +1240,24 @@ static int create_item(Item *i) {
log_debug("%s directory \"%s\".", creation_mode_verb_to_string(creation), i->path);
if (IN_SET(i->type, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA)) {
r = btrfs_subvol_auto_qgroup(i->path, 0, i->type == CREATE_SUBVOLUME_NEW_QUOTA);
if (r == -ENOTTY) {
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of unsupported file system or because directory is not a subvolume: %m", i->path);
return 0;
}
if (r == -EROFS) {
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" because of read-only file system: %m", i->path);
return 0;
}
if (r < 0)
return log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);
if (r > 0)
log_debug("Adjusted quota for subvolume \"%s\".", i->path);
if (r == 0)
log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
}
r = path_set_perms(i, i->path);
if (r < 0)
return r;
@@ -1492,6 +1514,8 @@ static int remove_item(Item *i) {
case TRUNCATE_FILE:
case CREATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case CREATE_FIFO:
case CREATE_SYMLINK:
case CREATE_CHAR_DEVICE:
@@ -1583,6 +1607,8 @@ static int clean_item(Item *i) {
switch (i->type) {
case CREATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case TRUNCATE_DIRECTORY:
case IGNORE_PATH:
case COPY_FILES:
@@ -1819,6 +1845,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
case CREATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case TRUNCATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH:
@@ -1983,8 +2011,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
i.mode = m;
i.mode_set = true;
} else
i.mode = IN_SET(i.type, CREATE_DIRECTORY, CREATE_SUBVOLUME, TRUNCATE_DIRECTORY)
? 0755 : 0644;
i.mode = IN_SET(i.type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA) ? 0755 : 0644;
if (!isempty(age) && !streq(age, "-")) {
const char *a = age;
@@ -2186,7 +2213,7 @@ static int read_config_file(const char *fn, bool ignore_enoent) {
continue;
ORDERED_HASHMAP_FOREACH(j, items, iter) {
if (j->type != CREATE_DIRECTORY && j->type != TRUNCATE_DIRECTORY && j->type != CREATE_SUBVOLUME)
if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA))
continue;
if (path_equal(j->path, i->path)) {
+2 -2
View File
@@ -7,5 +7,5 @@
# See tmpfiles.d(5) for details
v /home 0755 - - -
v /srv 0755 - - -
Q /home 0755 - - -
q /srv 0755 - - -
+1 -1
View File
@@ -7,7 +7,7 @@
# See tmpfiles.d(5) for details
v /var/lib/machines 0700 - - -
Q /var/lib/machines 0700 - - -
# Remove old temporary snapshots, but only at boot. Ideally we'd have
# "self-destroying" btrfs snapshots that go away if the last last
+2 -2
View File
@@ -8,8 +8,8 @@
# See tmpfiles.d(5) for details
# Clear tmp directories separately, to make them easier to override
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d
q /tmp 1777 root root 10d
q /var/tmp 1777 root root 30d
# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
+1 -1
View File
@@ -7,7 +7,7 @@
# See tmpfiles.d(5) for details
v /var 0755 - - -
q /var 0755 - - -
L /var/run - - - - ../run
+1
View File
@@ -39,6 +39,7 @@ DeviceAllow=char-pts rw
# implement the --image= option. Add these here, too.
DeviceAllow=/dev/loop-control rw
DeviceAllow=block-loop rw
DeviceAllow=block-blkext rw
[Install]
WantedBy=machines.target