<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>
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>
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;
/* 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)) {
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)
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);
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);
}