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:
commit
a63212834e
@ -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>
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user