1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-25 01:34:28 +03:00

Merge pull request #13709 from zachsmith/systemd-tmpfiles-allow-append-to-file

systemd-tmpfiles: allow appending content to file
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2019-10-04 11:59:06 +02:00 committed by GitHub
commit a63212834e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 23 deletions

View File

@ -51,7 +51,7 @@ p /fifo/to/create mode user group - -
L /symlink/to/create - - - - symlink/target/path L /symlink/to/create - - - - symlink/target/path
c /dev/char-device-to-create mode user group - - c /dev/char-device-to-create mode user group - -
b /dev/block-device-to-create mode user group - - b /dev/block-device-to-create mode user group - -
# p+, L+, c+, b+ create target unconditionally # p+, L+, c+, b+ create target unconditionally, w+ appends to the file
C /target/to/create - - - - /source/to/copy C /target/to/create - - - - /source/to/copy
x /path-or-glob/to/ignore - - - - - x /path-or-glob/to/ignore - - - - -
X /path-or-glob/to/ignore/recursively - - - - - X /path-or-glob/to/ignore/recursively - - - - -
@ -167,13 +167,13 @@ L /tmp/foobar - - - - /dev/null</programlisting>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><varname>w</varname></term> <term><varname>w, w+</varname></term>
<listitem><para>Write the argument parameter to a file, if <listitem><para>Write the argument parameter to a file, if the file exists.
the file exists. Lines of this type accept shell-style If suffixed with <varname>+</varname>, the line will be appended to the file.
globs in place of normal path names. The argument parameter If your configuration writes multiple lines to the same file, use <varname>w+</varname>.
will be written without a trailing newline. C-style Lines of this type accept shell-style globs in place of normal path names.
backslash escapes are interpreted. Follows The argument parameter will be written without a trailing newline.
symlinks.</para></listitem> C-style backslash escapes are interpreted. Follows symlinks.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -135,7 +135,7 @@ typedef struct Item {
bool keep_first_level:1; bool keep_first_level:1;
bool force:1; bool append_or_force:1;
bool allow_failure:1; bool allow_failure:1;
@ -987,10 +987,10 @@ static int parse_acls_from_arg(Item *item) {
assert(item); assert(item);
/* If force (= modify) is set, we will not modify the acl /* If append_or_force (= modify) is set, we will not modify the acl
* afterwards, so the mask can be added now if necessary. */ * afterwards, so the mask can be added now if necessary. */
r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->force); r = parse_acl(item->argument, &item->acl_access, &item->acl_default, !item->append_or_force);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring", item->argument); log_warning_errno(r, "Failed to parse ACL \"%s\": %m. Ignoring", item->argument);
#else #else
@ -1075,11 +1075,11 @@ static int fd_set_acls(Item *item, int fd, const char *path, const struct stat *
xsprintf(procfs_path, "/proc/self/fd/%i", fd); xsprintf(procfs_path, "/proc/self/fd/%i", fd);
if (item->acl_access) if (item->acl_access)
r = path_set_acl(procfs_path, path, ACL_TYPE_ACCESS, item->acl_access, item->force); r = path_set_acl(procfs_path, path, ACL_TYPE_ACCESS, item->acl_access, item->append_or_force);
/* set only default acls to folders */ /* set only default acls to folders */
if (r == 0 && item->acl_default && S_ISDIR(st->st_mode)) if (r == 0 && item->acl_default && S_ISDIR(st->st_mode))
r = path_set_acl(procfs_path, path, ACL_TYPE_DEFAULT, item->acl_default, item->force); r = path_set_acl(procfs_path, path, ACL_TYPE_DEFAULT, item->acl_default, item->append_or_force);
if (r > 0) if (r > 0)
return -r; /* already warned */ return -r; /* already warned */
@ -1257,7 +1257,7 @@ static int path_set_attribute(Item *item, const char *path) {
static int write_one_file(Item *i, const char *path) { static int write_one_file(Item *i, const char *path) {
_cleanup_close_ int fd = -1, dir_fd = -1; _cleanup_close_ int fd = -1, dir_fd = -1;
char *bn; char *bn;
int r; int flags, r;
assert(i); assert(i);
assert(path); assert(path);
@ -1272,8 +1272,10 @@ static int write_one_file(Item *i, const char *path) {
bn = basename(path); bn = basename(path);
flags = O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY;
/* Follows symlinks */ /* Follows symlinks */
fd = openat(dir_fd, bn, O_NONBLOCK|O_CLOEXEC|O_WRONLY|O_NOCTTY, i->mode); fd = openat(dir_fd, bn, i->append_or_force ? flags|O_APPEND : flags, i->mode);
if (fd < 0) { if (fd < 0) {
if (errno == ENOENT) { if (errno == ENOENT) {
log_debug_errno(errno, "Not writing missing file \"%s\": %m", path); log_debug_errno(errno, "Not writing missing file \"%s\": %m", path);
@ -1696,7 +1698,7 @@ static int create_device(Item *i, mode_t file_type) {
if ((st.st_mode & S_IFMT) != file_type) { if ((st.st_mode & S_IFMT) != file_type) {
if (i->force) { if (i->append_or_force) {
RUN_WITH_UMASK(0000) { RUN_WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, file_type); mac_selinux_create_file_prepare(i->path, file_type);
@ -1757,7 +1759,7 @@ static int create_fifo(Item *i, const char *path) {
if (!S_ISFIFO(st.st_mode)) { if (!S_ISFIFO(st.st_mode)) {
if (i->force) { if (i->append_or_force) {
RUN_WITH_UMASK(0000) { RUN_WITH_UMASK(0000) {
mac_selinux_create_file_prepare(path, S_IFIFO); mac_selinux_create_file_prepare(path, S_IFIFO);
r = mkfifoat_atomic(pfd, bn, i->mode); r = mkfifoat_atomic(pfd, bn, i->mode);
@ -2012,7 +2014,7 @@ static int create_item(Item *i) {
r = readlink_malloc(i->path, &x); r = readlink_malloc(i->path, &x);
if (r < 0 || !streq(i->argument, x)) { if (r < 0 || !streq(i->argument, x)) {
if (i->force) { if (i->append_or_force) {
mac_selinux_create_file_prepare(i->path, S_IFLNK); mac_selinux_create_file_prepare(i->path, S_IFLNK);
r = symlink_atomic(i->argument, i->path); r = symlink_atomic(i->argument, i->path);
mac_selinux_create_file_clear(); mac_selinux_create_file_clear();
@ -2492,7 +2494,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
ItemArray *existing; ItemArray *existing;
OrderedHashmap *h; OrderedHashmap *h;
int r, pos; int r, pos;
bool force = false, boot = false, allow_failure = false; bool append_or_force = false, boot = false, allow_failure = false;
assert(fname); assert(fname);
assert(line >= 1); assert(line >= 1);
@ -2535,8 +2537,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
for (pos = 1; action[pos]; pos++) { for (pos = 1; action[pos]; pos++) {
if (action[pos] == '!' && !boot) if (action[pos] == '!' && !boot)
boot = true; boot = true;
else if (action[pos] == '+' && !force) else if (action[pos] == '+' && !append_or_force)
force = true; append_or_force = true;
else if (action[pos] == '-' && !allow_failure) else if (action[pos] == '-' && !allow_failure)
allow_failure = true; allow_failure = true;
else { else {
@ -2554,7 +2556,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
} }
i.type = action[0]; i.type = action[0];
i.force = force; i.append_or_force = append_or_force;
i.allow_failure = allow_failure; i.allow_failure = allow_failure;
r = specifier_printf(path, specifier_table, NULL, &i.path); r = specifier_printf(path, specifier_table, NULL, &i.path);
@ -2794,7 +2796,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
size_t n; size_t n;
for (n = 0; n < existing->n_items; n++) { for (n = 0; n < existing->n_items; n++) {
if (!item_compatible(existing->items + n, &i)) { if (!item_compatible(existing->items + n, &i) && !i.append_or_force) {
log_notice("[%s:%u] Duplicate line for path \"%s\", ignoring.", log_notice("[%s:%u] Duplicate line for path \"%s\", ignoring.",
fname, line, i.path); fname, line, i.path);
return 0; return 0;