diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | man/tmpfiles.d.xml | 28 | ||||
-rw-r--r-- | src/core/namespace.c | 151 | ||||
-rw-r--r-- | src/delta/delta.c | 31 | ||||
-rw-r--r-- | src/kernel-install/kernel-install | 4 | ||||
-rw-r--r-- | src/libsystemd/libsystemd.pc.in | 2 | ||||
-rw-r--r-- | src/libudev/libudev.pc.in | 2 | ||||
-rw-r--r-- | src/machine/machinectl.c | 30 | ||||
-rw-r--r-- | src/nspawn/nspawn-mount.c | 2 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 2 | ||||
-rw-r--r-- | src/shared/acl-util.c | 2 | ||||
-rw-r--r-- | src/shared/logs-show.c | 2 | ||||
-rwxr-xr-x | test/TEST-03-JOBS/test-jobs.sh | 2 |
14 files changed, 170 insertions, 91 deletions
diff --git a/Makefile.am b/Makefile.am index f2d8bf57f7..73144b165c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -6054,6 +6054,7 @@ EXTRA_DIST += \ # ------------------------------------------------------------------------------ substitutions = \ + '|rootlibdir=$(rootlibdir)|' \ '|rootlibexecdir=$(rootlibexecdir)|' \ '|rootbindir=$(rootbindir)|' \ '|bindir=$(bindir)|' \ diff --git a/configure.ac b/configure.ac index 0b10fc7de7..1cee7adbb6 100644 --- a/configure.ac +++ b/configure.ac @@ -97,8 +97,6 @@ AC_PATH_PROG([M4], [m4]) AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon], [$PATH:/usr/sbin:/sbin]) AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck], [$PATH:/usr/sbin:/sbin]) -AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap], [$PATH:/usr/sbin:/sbin]) - AC_PATH_PROG([KILL], [kill], [/usr/bin/kill], [$PATH:/usr/sbin:/sbin]) AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod], [$PATH:/usr/sbin:/sbin]) diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index e040a1636d..92620f0a24 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -117,8 +117,8 @@ type, path, mode, ownership, age, and argument fields:</para> <programlisting>#Type Path Mode UID GID Age Argument - d /run/user 0755 root root 10d - - L /tmp/foobar - - - - /dev/null</programlisting> +d /run/user 0755 root root 10d - +L /tmp/foobar - - - - /dev/null</programlisting> <para>Fields may be enclosed within quotes and contain C-style escapes.</para> @@ -159,7 +159,7 @@ <term><varname>d</varname></term> <listitem><para>Create a directory. The mode and ownership will be adjusted if specified and the directory already exists. Contents of this directory are subject - to time based cleanup if the time argument is specified.</para></listitem> + to time based cleanup if the age argument is specified.</para></listitem> </varlistentry> <varlistentry> @@ -171,9 +171,13 @@ <varlistentry> <term><varname>e</varname></term> - <listitem><para>Similar to <varname>d</varname>, but the directory will not be - created if it does not exist. Lines of this type accept shell-style globs in - place of normal path names.</para></listitem> + <listitem><para>Similar to <varname>d</varname>, but the directory will not be created if + it does not exist. Lines of this type accept shell-style globs in place of normal path + names. For this entry to be useful, at least one of the mode, uid, gid, or age arguments + must be specified, since otherwise this entry has no effect. If the age argument is + <literal>0</literal>, contents of the directory will be unconditionally deleted every time + <command>systemd-tmpfiles --clean</command> is run. This can be useful when combined with + <varname>!</varname>, see the examples.</para></listitem> </varlistentry> <varlistentry> @@ -680,6 +684,18 @@ e /var/chache/dnf/ - - - 30d <filename>/var/chache/dnf/</filename> will be removed after they have not been accessed in 30 days.</para> </example> + + <example> + <title>Empty the contents of the a cache directory on boot</title> + + <programlisting># /usr/lib/tmpfiles.d/krb5rcache.conf +e! /var/cache/krb5rcache - - - 0 +</programlisting> + + <para>Any files and subdirectories in <filename>/var/cache/krb5rcache/</filename> + will be removed on boot. The directory will not be created. + </para> + </example> </refsect1> <refsect1> diff --git a/src/core/namespace.c b/src/core/namespace.c index db9a7aa5e7..f361e139ac 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -58,8 +58,7 @@ typedef enum MountMode { } MountMode; typedef struct BindMount { - const char *path; /* stack memory, doesn't need to be freed explicitly */ - char *chased; /* malloc()ed memory, needs to be freed */ + char *path; MountMode mode; bool ignore; /* Ignore if path does not exist */ } BindMount; @@ -155,10 +154,23 @@ static const TargetMount protect_system_strict_table[] = { { "/root", READWRITE, true }, /* ProtectHome= */ }; -static void set_bind_mount(BindMount **p, const char *path, MountMode mode, bool ignore) { - (*p)->path = path; - (*p)->mode = mode; - (*p)->ignore = ignore; +static void set_bind_mount(BindMount *p, char *path, MountMode mode, bool ignore) { + p->path = path; + p->mode = mode; + p->ignore = ignore; +} + +static int append_one_mount(BindMount **p, const char *root_directory, + const char *path, MountMode mode, bool ignore) { + char *lpath; + assert(p); + + lpath = prefix_root(root_directory, path); + if (!lpath) + return -ENOMEM; + + set_bind_mount((*p)++, lpath, mode, ignore); + return 0; } static int append_mounts(BindMount **p, char **strv, MountMode mode) { @@ -168,6 +180,7 @@ static int append_mounts(BindMount **p, char **strv, MountMode mode) { STRV_FOREACH(i, strv) { bool ignore = false; + char *path; if (IN_SET(mode, INACCESSIBLE, READONLY, READWRITE) && startswith(*i, "-")) { (*i)++; @@ -177,8 +190,11 @@ static int append_mounts(BindMount **p, char **strv, MountMode mode) { if (!path_is_absolute(*i)) return -EINVAL; - set_bind_mount(p, *i, mode, ignore); - (*p)++; + path = strdup(*i); + if (!path) + return -ENOMEM; + + set_bind_mount((*p)++, path, mode, ignore); } return 0; @@ -196,13 +212,16 @@ static int append_target_mounts(BindMount **p, const char *root_directory, const * declaration we do not support "-" at the beginning. */ const TargetMount *m = &mounts[i]; - const char *path = prefix_roota(root_directory, m->path); + char *path; + + path = prefix_root(root_directory, m->path); + if (!path) + return -ENOMEM; if (!path_is_absolute(path)) return -EINVAL; - set_bind_mount(p, path, m->mode, m->ignore); - (*p)++; + set_bind_mount((*p)++, path, m->mode, m->ignore); } return 0; @@ -309,6 +328,7 @@ static void drop_duplicates(BindMount *m, unsigned *n) { * above. */ if (previous && path_equal(f->path, previous->path)) { log_debug("%s is duplicate.", f->path); + f->path = mfree(f->path); continue; } @@ -336,6 +356,7 @@ static void drop_inaccessible(BindMount *m, unsigned *n) { * it, as inaccessible paths really should drop the entire subtree. */ if (clear && path_startswith(f->path, clear)) { log_debug("%s is masked by %s.", f->path, clear); + f->path = mfree(f->path); continue; } @@ -375,6 +396,7 @@ static void drop_nop(BindMount *m, unsigned *n) { /* We found it, let's see if it's the same mode, if so, we can drop this entry */ if (found && p->mode == f->mode) { log_debug("%s is redundant by %s", f->path, p->path); + f->path = mfree(f->path); continue; } } @@ -401,6 +423,7 @@ static void drop_outside_root(const char *root_directory, BindMount *m, unsigned if (!path_startswith(f->path, root_directory)) { log_debug("%s is outside of root directory.", f->path); + f->path = mfree(f->path); continue; } @@ -651,19 +674,23 @@ static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned * chase the symlinks on our own first. This call wil do so for all entries and remove all entries where we * can't resolve the path, and which have been marked for such removal. */ - for (f = m, t = m; f < m+*n; f++) { + for (f = m, t = m; f < m + *n; f++) { + _cleanup_free_ char *chased = NULL; - r = chase_symlinks(f->path, root_directory, &f->chased); - if (r == -ENOENT && f->ignore) /* Doesn't exist? Then remove it! */ + r = chase_symlinks(f->path, root_directory, &chased); + if (r == -ENOENT && f->ignore) { + /* Doesn't exist? Then remove it! */ + f->path = mfree(f->path); continue; + } if (r < 0) return log_debug_errno(r, "Failed to chase symlinks for %s: %m", f->path); - if (path_equal(f->path, f->chased)) - f->chased = mfree(f->chased); - else { - log_debug("Chased %s → %s", f->path, f->chased); - f->path = f->chased; + if (!path_equal(f->path, chased)) { + log_debug("Chased %s → %s", f->path, chased); + r = free_and_replace(f->path, chased); + if (r < 0) + return r; } *t = *f; @@ -724,96 +751,96 @@ int setup_namespace( BindMount *m, *mounts = NULL; bool make_slave = false; - unsigned n; + unsigned n_mounts; int r = 0; if (mount_flags == 0) mount_flags = MS_SHARED; - n = namespace_calculate_mounts(ns_info, - read_write_paths, - read_only_paths, - inaccessible_paths, - tmp_dir, var_tmp_dir, - protect_home, protect_system); + n_mounts = namespace_calculate_mounts(ns_info, + read_write_paths, + read_only_paths, + inaccessible_paths, + tmp_dir, var_tmp_dir, + protect_home, protect_system); /* Set mount slave mode */ - if (root_directory || n > 0) + if (root_directory || n_mounts > 0) make_slave = true; - if (n > 0) { - m = mounts = (BindMount *) alloca0(n * sizeof(BindMount)); + if (n_mounts > 0) { + m = mounts = (BindMount *) alloca0(n_mounts * sizeof(BindMount)); r = append_mounts(&m, read_write_paths, READWRITE); if (r < 0) - return r; + goto finish; r = append_mounts(&m, read_only_paths, READONLY); if (r < 0) - return r; + goto finish; r = append_mounts(&m, inaccessible_paths, INACCESSIBLE); if (r < 0) - return r; + goto finish; if (tmp_dir) { - m->path = prefix_roota(root_directory, "/tmp"); - m->mode = PRIVATE_TMP; - m++; + r = append_one_mount(&m, root_directory, "/tmp", PRIVATE_TMP, false); + if (r < 0) + goto finish; } if (var_tmp_dir) { - m->path = prefix_roota(root_directory, "/var/tmp"); - m->mode = PRIVATE_VAR_TMP; - m++; + r = append_one_mount(&m, root_directory, "/var/tmp", PRIVATE_VAR_TMP, false); + if (r < 0) + goto finish; } if (ns_info->private_dev) { - m->path = prefix_roota(root_directory, "/dev"); - m->mode = PRIVATE_DEV; - m++; + r = append_one_mount(&m, root_directory, "/dev", PRIVATE_DEV, false); + if (r < 0) + goto finish; } if (ns_info->protect_kernel_tunables) { r = append_protect_kernel_tunables(&m, root_directory); if (r < 0) - return r; + goto finish; } if (ns_info->protect_kernel_modules) { r = append_protect_kernel_modules(&m, root_directory); if (r < 0) - return r; + goto finish; } if (ns_info->protect_control_groups) { - m->path = prefix_roota(root_directory, "/sys/fs/cgroup"); - m->mode = READONLY; - m++; + r = append_one_mount(&m, root_directory, "/sys/fs/cgroup", READONLY, false); + if (r < 0) + goto finish; } r = append_protect_home(&m, root_directory, protect_home); if (r < 0) - return r; + goto finish; r = append_protect_system(&m, root_directory, protect_system); if (r < 0) - return r; + goto finish; - assert(mounts + n == m); + assert(mounts + n_mounts == m); /* Resolve symlinks manually first, as mount() will always follow them relative to the host's * root. Moreover we want to suppress duplicates based on the resolved paths. This of course is a bit * racy. */ - r = chase_all_symlinks(root_directory, mounts, &n); + r = chase_all_symlinks(root_directory, mounts, &n_mounts); if (r < 0) goto finish; - qsort(mounts, n, sizeof(BindMount), mount_path_compare); + qsort(mounts, n_mounts, sizeof(BindMount), mount_path_compare); - drop_duplicates(mounts, &n); - drop_outside_root(root_directory, mounts, &n); - drop_inaccessible(mounts, &n); - drop_nop(mounts, &n); + drop_duplicates(mounts, &n_mounts); + drop_outside_root(root_directory, mounts, &n_mounts); + drop_inaccessible(mounts, &n_mounts); + drop_nop(mounts, &n_mounts); } if (unshare(CLONE_NEWNS) < 0) { @@ -843,25 +870,25 @@ int setup_namespace( } } - if (n > 0) { + if (n_mounts > 0) { char **blacklist; unsigned j; /* First round, add in all special mounts we need */ - for (m = mounts; m < mounts + n; ++m) { + for (m = mounts; m < mounts + n_mounts; ++m) { r = apply_mount(m, tmp_dir, var_tmp_dir); if (r < 0) goto finish; } /* Create a blacklist we can pass to bind_mount_recursive() */ - blacklist = newa(char*, n+1); - for (j = 0; j < n; j++) + blacklist = newa(char*, n_mounts+1); + for (j = 0; j < n_mounts; j++) blacklist[j] = (char*) mounts[j].path; blacklist[j] = NULL; /* Second round, flip the ro bits if necessary. */ - for (m = mounts; m < mounts + n; ++m) { + for (m = mounts; m < mounts + n_mounts; ++m) { r = make_read_only(m, blacklist); if (r < 0) goto finish; @@ -886,8 +913,8 @@ int setup_namespace( r = 0; finish: - for (m = mounts; m < mounts + n; m++) - free(m->chased); + for (m = mounts; m < mounts + n_mounts; m++) + free(m->path); return r; } diff --git a/src/delta/delta.c b/src/delta/delta.c index 6848662ccb..04de75475d 100644 --- a/src/delta/delta.c +++ b/src/delta/delta.c @@ -355,6 +355,21 @@ static int enumerate_dir(Hashmap *top, Hashmap *bottom, Hashmap *drops, const ch } } +static int should_skip_prefix(const char* p) { +#ifdef HAVE_SPLIT_USR + int r; + _cleanup_free_ char *target = NULL; + + r = chase_symlinks(p, NULL, &target); + if (r < 0) + return r; + + return !streq(p, target) && nulstr_contains(prefixes, target); +#else + return 0; +#endif +} + static int process_suffix(const char *suffix, const char *onlyprefix) { const char *p; char *f; @@ -382,6 +397,15 @@ static int process_suffix(const char *suffix, const char *onlyprefix) { NULSTR_FOREACH(p, prefixes) { _cleanup_free_ char *t = NULL; + int skip; + + skip = should_skip_prefix(p); + if (skip < 0) { + r = skip; + goto finish; + } + if (skip) + continue; t = strjoin(p, "/", suffix); if (!t) { @@ -459,6 +483,13 @@ static int process_suffix_chop(const char *arg) { /* Strip prefix from the suffix */ NULSTR_FOREACH(p, prefixes) { const char *suffix; + int skip; + + skip = should_skip_prefix(p); + if (skip < 0) + return skip; + if (skip) + continue; suffix = startswith(arg, p); if (suffix) { diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index 0c0ee718ac..a95b9717f0 100644 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -127,7 +127,7 @@ case $COMMAND in "$f" add "$KERNEL_VERSION" "$BOOT_DIR_ABS" "$KERNEL_IMAGE" x=$? if [[ $x == $SKIP_REMAINING ]]; then - return 0 + exit 0 fi ((ret+=$x)) fi @@ -140,7 +140,7 @@ case $COMMAND in "$f" remove "$KERNEL_VERSION" "$BOOT_DIR_ABS" x=$? if [[ $x == $SKIP_REMAINING ]]; then - return 0 + exit 0 fi ((ret+=$x)) fi diff --git a/src/libsystemd/libsystemd.pc.in b/src/libsystemd/libsystemd.pc.in index e8f79507ea..7e6d4999cb 100644 --- a/src/libsystemd/libsystemd.pc.in +++ b/src/libsystemd/libsystemd.pc.in @@ -7,7 +7,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ -libdir=@libdir@ +libdir=@rootlibdir@ includedir=@includedir@ Name: systemd diff --git a/src/libudev/libudev.pc.in b/src/libudev/libudev.pc.in index a0f3f524e0..770c92209e 100644 --- a/src/libudev/libudev.pc.in +++ b/src/libudev/libudev.pc.in @@ -7,7 +7,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ -libdir=@libdir@ +libdir=@rootlibdir@ includedir=@includedir@ Name: libudev diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 7b9be3b425..9c754b4327 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -330,10 +330,12 @@ static int list_machines(int argc, char *argv[], void *userdata) { printf("-\n"); } - if (arg_legend && n_machines > 0) - printf("\n%zu machines listed.\n", n_machines); - else - printf("No machines.\n"); + if (arg_legend) { + if (n_machines > 0) + printf("\n%zu machines listed.\n", n_machines); + else + printf("No machines.\n"); + } out: clean_machine_info(machines, n_machines); @@ -463,10 +465,12 @@ static int list_images(int argc, char *argv[], void *userdata) { (int) max_mtime, strna(format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime))); } - if (arg_legend && n_images > 0) - printf("\n%zu images listed.\n", n_images); - else - printf("No images.\n"); + if (arg_legend) { + if (n_images > 0) + printf("\n%zu images listed.\n", n_images); + else + printf("No images.\n"); + } return 0; } @@ -2489,10 +2493,12 @@ static int list_transfers(int argc, char *argv[], void *userdata) { (int) max_local, transfers[j].local, (int) max_remote, transfers[j].remote); - if (arg_legend && n_transfers > 0) - printf("\n%zu transfers listed.\n", n_transfers); - else - printf("No transfers.\n"); + if (arg_legend) { + if (n_transfers > 0) + printf("\n%zu transfers listed.\n", n_transfers); + else + printf("No transfers.\n"); + } return 0; } diff --git a/src/nspawn/nspawn-mount.c b/src/nspawn/nspawn-mount.c index 392498d1bb..0c24b8e18a 100644 --- a/src/nspawn/nspawn-mount.c +++ b/src/nspawn/nspawn-mount.c @@ -429,7 +429,7 @@ int mount_all(const char *dest, o = options; } - r = mount_verbose(mount_table[k].fatal ? LOG_ERR : LOG_WARNING, + r = mount_verbose(mount_table[k].fatal ? LOG_ERR : LOG_DEBUG, mount_table[k].what, where, mount_table[k].type, diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 673e616911..1563644e4b 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4033,7 +4033,7 @@ int main(int argc, char *argv[]) { bool root_device_rw = true, home_device_rw = true, srv_device_rw = true; _cleanup_close_ int master = -1, image_fd = -1; _cleanup_fdset_free_ FDSet *fds = NULL; - int r, n_fd_passed, loop_nr = -1, ret = EXIT_FAILURE; + int r, n_fd_passed, loop_nr = -1, ret = EXIT_SUCCESS; char veth_name[IFNAMSIZ] = ""; bool secondary = false, remove_subvol = false; pid_t pid = 0; diff --git a/src/shared/acl-util.c b/src/shared/acl-util.c index 2aa951fce9..79a3b9591d 100644 --- a/src/shared/acl-util.c +++ b/src/shared/acl-util.c @@ -162,7 +162,7 @@ int add_base_acls_if_needed(acl_t *acl_p, const char *path) { int acl_search_groups(const char *path, char ***ret_groups) { _cleanup_strv_free_ char **g = NULL; - _cleanup_(acl_free) acl_t acl = NULL; + _cleanup_(acl_freep) acl_t acl = NULL; bool ret = false; acl_entry_t entry; int r; diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index f9d9c4ed62..5ad5ade31e 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -418,7 +418,7 @@ static int output_short( if (flags & OUTPUT_NO_HOSTNAME) { /* Suppress display of the hostname if this is requested. */ - hostname = NULL; + hostname = mfree(hostname); hostname_len = 0; } diff --git a/test/TEST-03-JOBS/test-jobs.sh b/test/TEST-03-JOBS/test-jobs.sh index fa6cf4181a..48926290a6 100755 --- a/test/TEST-03-JOBS/test-jobs.sh +++ b/test/TEST-03-JOBS/test-jobs.sh @@ -68,7 +68,7 @@ START_SEC=$(date -u '+%s') systemctl start --wait wait2.service || exit 1 END_SEC=$(date -u '+%s') ELAPSED=$(($END_SEC-$START_SEC)) -[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 3 ]] || exit 1 +[[ "$ELAPSED" -ge 2 ]] && [[ "$ELAPSED" -le 4 ]] || exit 1 # wait5fail fails, so systemctl should fail START_SEC=$(date -u '+%s') |