]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #12750 from keszybz/tmpfiles-c-copy
authorLennart Poettering <lennart@poettering.net>
Thu, 11 Jul 2019 16:13:19 +0000 (18:13 +0200)
committerGitHub <noreply@github.com>
Thu, 11 Jul 2019 16:13:19 +0000 (18:13 +0200)
Make tmpfiles C use --root

1  2 
man/tmpfiles.d.xml
src/tmpfiles/tmpfiles.c

diff --combined man/tmpfiles.d.xml
index ac6565ec93cb62a4f7aa5b8a5c20c78a7232fc71,26afc116b77d3e72badba2e914f3f946c35a2208..f097045b7bbeea4c8420695aa77ac536e8576689
  <filename>…</filename>
  <filename>/usr/share/user-tmpfiles.d/*.conf</filename>
      </literallayout></para>
+     <programlisting>#Type Path                                     Mode User Group Age         Argument
+ f     /file/to/create                          mode user group -           content
+ F     /file/to/create-or-truncate              mode user group -           content
+ w     /file/to/write-to                        -    -    -     -           content
+ d     /directory/to/create-and-cleanup         mode user group cleanup-age -
+ D     /directory/to/create-and-remove          mode user group cleanup-age -
+ e     /directory/to/cleanup                    mode user group cleanup-age -
+ v     /subvolume/to/create                     mode user group -           -
+ v     /subvolume-or-directory/to/create        mode user group -           -
+ Q     /subvolume/to/create                     mode user group -           -
+ p     /fifo/to/create                          mode user group -           -
+ L     /symlink/to/create                       -    -    -     -           symlink/target/path
+ c     /dev/char-device-to-create               mode user group -           -
+ b     /dev/block-device-to-create              mode user group -           -
+ # p+, L+, c+, b+ create target unconditionally
+ C     /target/to/create                        -    -    -     -           /source/to/copy
+ x     /path-or-glob/to/ignore                  -    -    -     -           -
+ X     /path-or-glob/to/ignore/recursively      -    -    -     -           -
+ r     /empty/dir/to/remove                     -    -    -     -           -
+ R     /dir/to/remove/recursively               -    -    -     -           -
+ z     /path-or-glob/to/adjust/mode             mode user group -           MAC context
+ Z     /path-or-glob/to/adjust/mode/recursively mode user group -           MAC context
+ t     /path-or-glob/to/set/xattrs              -    -    -     -           xattrs
+ T     /path-or-glob/to/set/xattrs/recursively  -    -    -     -           xattrs
+ h     /path-or-glob/to/set/attrs               -    -    -     -           file attrs
+ H     /path-or-glob/to/set/attrs/recursively   -    -    -     -           file attrs
+ a     /path-or-glob/to/set/acls                -    -    -     -           POSIX ACLs
+ A     /path-or-glob/to/set/acls/recursively    -    -    -     -           POSIX ACLs
+ # a+, A+ append ACLs
+ </programlisting>
    </refsynopsisdiv>
  
    <refsect1>
@@@ -495,14 -526,6 +526,14 @@@ w- /proc/sys/vm/swappiness - - - - 10</
        lines, when omitted or when set to <literal>-</literal>, the file ownership will not be modified. These
        parameters are ignored for <varname>x</varname>, <varname>r</varname>, <varname>R</varname>,
        <varname>L</varname>, <varname>t</varname>, and <varname>a</varname> lines.</para>
 +
 +      <para>This field should generally only reference system users/groups, i.e. users/groups that are
 +      guaranteed to be resolvable during early boot. If this field references users/groups that only become
 +      resolveable during later boot (i.e. after NIS, LDAP or a similar networked directory service become
 +      available), execution of the operations declared by the line will likely fail. Also see <ulink
 +      url="https://systemd.io/UIDS-GIDS.html#notes-on-resolvability-of-user-and-group-names">Notes on
 +      Resolvability of User and Group Names</ulink> for more information on requirements on system user/group
 +      definitions.</para>
      </refsect2>
  
      <refsect2>
diff --combined src/tmpfiles/tmpfiles.c
index ef817fca4f7024157003c39b7e17d403ad72573d,36ffd072b4475add024d02b9081dad4c339e08f0..02eecf3e3af0e8339a189e7de211cc602769376e
@@@ -461,6 -461,38 +461,6 @@@ static bool unix_socket_alive(const cha
          return !!set_get(unix_sockets, (char*) fn);
  }
  
 -static int dir_is_mount_point(DIR *d, const char *subdir) {
 -
 -        int mount_id_parent, mount_id;
 -        int r_p, r;
 -
 -        r_p = name_to_handle_at_loop(dirfd(d), ".", NULL, &mount_id_parent, 0);
 -        if (r_p < 0)
 -                r_p = -errno;
 -
 -        r = name_to_handle_at_loop(dirfd(d), subdir, NULL, &mount_id, 0);
 -        if (r < 0)
 -                r = -errno;
 -
 -        /* got no handle; make no assumptions, return error */
 -        if (r_p < 0 && r < 0)
 -                return r_p;
 -
 -        /* got both handles; if they differ, it is a mount point */
 -        if (r_p >= 0 && r >= 0)
 -                return mount_id_parent != mount_id;
 -
 -        /* got only one handle; assume different mount points if one
 -         * of both queries was not supported by the filesystem */
 -        if (IN_SET(r_p, -ENOSYS, -EOPNOTSUPP) || IN_SET(r, -ENOSYS, -EOPNOTSUPP))
 -                return true;
 -
 -        /* return error */
 -        if (r_p < 0)
 -                return r_p;
 -        return r;
 -}
 -
  static DIR* xopendirat_nomod(int dirfd, const char *path) {
          DIR *dir;
  
@@@ -525,19 -557,13 +525,19 @@@ static int dir_cleanup
                  /* Try to detect bind mounts of the same filesystem instance; they
                   * do not differ in device major/minors. This type of query is not
                   * supported on all kernels or filesystem types though. */
 -                if (S_ISDIR(s.st_mode) && dir_is_mount_point(d, dent->d_name) > 0) {
 -                        log_debug("Ignoring \"%s/%s\": different mount of the same filesystem.",
 -                                  p, dent->d_name);
 -                        continue;
 +                if (S_ISDIR(s.st_mode)) {
 +                        int q;
 +
 +                        q = fd_is_mount_point(dirfd(d), dent->d_name, 0);
 +                        if (q < 0)
 +                                log_debug_errno(q, "Failed to determine whether \"%s/%s\" is a mount point, ignoring: %m", p, dent->d_name);
 +                        else if (q > 0) {
 +                                log_debug("Ignoring \"%s/%s\": different mount of the same filesystem.", p, dent->d_name);
 +                                continue;
 +                        }
                  }
  
 -                sub_path = strjoin(p, "/", dent->d_name);
 +                sub_path = path_join(p, dent->d_name);
                  if (!sub_path) {
                          r = log_oom();
                          goto finish;
                                  continue;
                          }
  
 -                        if (mountpoint && S_ISREG(s.st_mode))
 -                                if (s.st_uid == 0 && STR_IN_SET(dent->d_name,
 -                                                                ".journal",
 -                                                                "aquota.user",
 -                                                                "aquota.group")) {
 -                                        log_debug("Skipping \"%s\".", sub_path);
 -                                        continue;
 -                                }
 +                        if (mountpoint &&
 +                            S_ISREG(s.st_mode) &&
 +                            s.st_uid == 0 &&
 +                            STR_IN_SET(dent->d_name,
 +                                       ".journal",
 +                                       "aquota.user",
 +                                       "aquota.group")) {
 +                                log_debug("Skipping \"%s\".", sub_path);
 +                                continue;
 +                        }
  
                          /* Ignore sockets that are listed in /proc/net/unix */
                          if (S_ISSOCK(s.st_mode) && unix_socket_alive(sub_path)) {
@@@ -923,7 -947,7 +923,7 @@@ static int parse_xattrs_from_arg(Item *
          for (;;) {
                  _cleanup_free_ char *name = NULL, *value = NULL, *xattr = NULL;
  
 -                r = extract_first_word(&p, &xattr, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
 +                r = extract_first_word(&p, &xattr, NULL, EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE);
                  if (r < 0)
                          log_warning_errno(r, "Failed to parse extended attribute '%s', ignoring: %m", p);
                  if (r <= 0)
@@@ -2471,14 -2495,15 +2471,14 @@@ static int patch_var_run(const char *fn
          if (isempty(k)) /* Don't complain about other paths than /var/run, and not about /var/run itself either. */
                  return 0;
  
 -        n = strjoin("/run/", k);
 +        n = path_join("/run", k);
          if (!n)
                  return log_oom();
  
          /* Also log about this briefly. We do so at LOG_NOTICE level, as we fixed up the situation automatically, hence
           * there's no immediate need for action by the user. However, in the interest of making things less confusing
           * to the user, let's still inform the user that these snippets should really be updated. */
 -
 -        log_notice("[%s:%u] Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", fname, line, *path, n);
 +        log_syntax(NULL, LOG_NOTICE, fname, line, 0, "Line references path below legacy directory /var/run/, updating %s → %s; please update the tmpfiles.d/ drop-in file accordingly.", *path, n);
  
          free_and_replace(*path, n);
  
@@@ -2501,7 -2526,7 +2501,7 @@@ static int parse_line(const char *fname
          r = extract_many_words(
                          &buffer,
                          NULL,
 -                        EXTRACT_QUOTES,
 +                        EXTRACT_UNQUOTE,
                          &action,
                          &path,
                          &mode,
  
          case COPY_FILES:
                  if (!i.argument) {
-                         i.argument = strappend("/usr/share/factory/", i.path);
+                         i.argument = path_join(arg_root, "/usr/share/factory/", i.path);
                          if (!i.argument)
                                  return log_oom();
                  } else if (!path_is_absolute(i.argument)) {
                          *invalid_config = true;
                          log_error("[%s:%u] Source path is not absolute.", fname, line);
                          return -EBADMSG;
+                 } else if (arg_root) {
+                         char *p;
+                         p = prefix_root(arg_root, i.argument);
+                         if (!p)
+                                 return log_oom();
+                         free_and_replace(i.argument, p);
                  }
  
                  path_simplify(i.argument, false);
          if (arg_root) {
                  char *p;
  
 -                p = prefix_root(arg_root, i.path);
 +                p = path_join(arg_root, i.path);
                  if (!p)
                          return log_oom();
                  free_and_replace(i.path, p);
          }