diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/dbus-automount.c | 22 | ||||
-rw-r--r-- | src/core/dbus-automount.h | 2 | ||||
-rw-r--r-- | src/core/dbus-cgroup.c | 205 | ||||
-rw-r--r-- | src/core/dbus-cgroup.h | 2 | ||||
-rw-r--r-- | src/core/dbus-execute.c | 359 | ||||
-rw-r--r-- | src/core/dbus-execute.h | 2 | ||||
-rw-r--r-- | src/core/dbus-kill.c | 20 | ||||
-rw-r--r-- | src/core/dbus-kill.h | 2 | ||||
-rw-r--r-- | src/core/dbus-mount.c | 28 | ||||
-rw-r--r-- | src/core/dbus-mount.h | 2 | ||||
-rw-r--r-- | src/core/dbus-scope.c | 47 | ||||
-rw-r--r-- | src/core/dbus-scope.h | 2 | ||||
-rw-r--r-- | src/core/dbus-service.c | 58 | ||||
-rw-r--r-- | src/core/dbus-service.h | 2 | ||||
-rw-r--r-- | src/core/dbus-slice.c | 4 | ||||
-rw-r--r-- | src/core/dbus-slice.h | 2 | ||||
-rw-r--r-- | src/core/dbus-socket.c | 4 | ||||
-rw-r--r-- | src/core/dbus-socket.h | 2 | ||||
-rw-r--r-- | src/core/dbus-swap.c | 4 | ||||
-rw-r--r-- | src/core/dbus-swap.h | 2 | ||||
-rw-r--r-- | src/core/dbus-timer.c | 38 | ||||
-rw-r--r-- | src/core/dbus-timer.h | 2 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 40 | ||||
-rw-r--r-- | src/core/dbus-unit.h | 2 | ||||
-rw-r--r-- | src/core/unit.c | 188 | ||||
-rw-r--r-- | src/core/unit.h | 39 |
26 files changed, 602 insertions, 478 deletions
diff --git a/src/core/dbus-automount.c b/src/core/dbus-automount.c index 3c165c41a5..4b1b86f7b9 100644 --- a/src/core/dbus-automount.c +++ b/src/core/dbus-automount.c @@ -38,7 +38,7 @@ static int bus_automount_set_transient_property( Automount *a, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -47,18 +47,21 @@ static int bus_automount_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "TimeoutIdleUSec")) { usec_t timeout_idle_usec; + r = sd_bus_message_read(message, "t", &timeout_idle_usec); if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { char time[FORMAT_TIMESPAN_MAX]; a->timeout_idle_usec = timeout_idle_usec; - unit_write_drop_in_format(UNIT(a), mode, name, "[Automount]\nTimeoutIdleSec=%s\n", - format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC)); + unit_write_settingf(UNIT(a), flags, name, "TimeoutIdleSec=%s\n", + format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC)); } } else return 0; @@ -70,20 +73,17 @@ int bus_automount_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Automount *a = AUTOMOUNT(u); - int r = 0; assert(a); assert(name); assert(message); - if (u->transient && u->load_state == UNIT_STUB) - /* This is a transient unit, let's load a little more */ - - r = bus_automount_set_transient_property(a, name, message, mode, error); + if (u->transient && u->load_state == UNIT_STUB) /* This is a transient unit? let's load a little more */ + return bus_automount_set_transient_property(a, name, message, flags, error); - return r; + return 0; } diff --git a/src/core/dbus-automount.h b/src/core/dbus-automount.h index dc56de954a..378119410c 100644 --- a/src/core/dbus-automount.h +++ b/src/core/dbus-automount.h @@ -23,4 +23,4 @@ extern const sd_bus_vtable bus_automount_vtable[]; -int bus_automount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_automount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index f09d9fecab..0343aaed62 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -334,7 +334,7 @@ static int bus_cgroup_set_transient_property( CGroupContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -344,6 +344,8 @@ static int bus_cgroup_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "Delegate")) { int b; @@ -351,11 +353,11 @@ static int bus_cgroup_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->delegate = b; c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0; - unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no"); + unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b)); } return 1; @@ -388,7 +390,7 @@ static int bus_cgroup_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *t = NULL; r = cg_mask_to_string(mask, &t); @@ -401,7 +403,7 @@ static int bus_cgroup_set_transient_property( else c->delegate_controllers |= mask; - unit_write_drop_in_private_format(u, mode, name, "Delegate=%s", strempty(t)); + unit_write_settingf(u, flags, name, "Delegate=%s", strempty(t)); } return 1; @@ -415,7 +417,7 @@ int bus_cgroup_set_property( CGroupContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { CGroupIOLimitType iol_type; @@ -426,6 +428,8 @@ int bus_cgroup_set_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "CPUAccounting")) { int b; @@ -433,10 +437,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU); - unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no"); + unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b)); } return 1; @@ -449,16 +453,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "CPUWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "CPUWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "CPUWeight="); + unit_write_setting(u, flags, name, "CPUWeight="); else - unit_write_drop_in_private_format(u, mode, name, "CPUWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "CPUWeight=%" PRIu64, weight); } return 1; @@ -471,16 +475,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_cpu_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (weight == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupCPUWeight="); + unit_write_setting(u, flags, name, "StartupCPUWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupCPUWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupCPUWeight=%" PRIu64, weight); } return 1; @@ -493,16 +497,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "CPUShares= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_shares = shares; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "CPUShares="); + unit_write_setting(u, flags, name, "CPUShares="); else - unit_write_drop_in_private_format(u, mode, name, "CPUShares=%" PRIu64, shares); + unit_write_settingf(u, flags, name, "CPUShares=%" PRIu64, shares); } return 1; @@ -515,16 +519,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_cpu_shares = shares; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupCPUShares="); + unit_write_setting(u, flags, name, "StartupCPUShares="); else - unit_write_drop_in_private_format(u, mode, name, "StartupCPUShares=%" PRIu64, shares); + unit_write_settingf(u, flags, name, "StartupCPUShares=%" PRIu64, shares); } return 1; @@ -537,20 +541,20 @@ int bus_cgroup_set_property( return r; if (u64 <= 0) - return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_quota_per_sec_usec = u64; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (c->cpu_quota_per_sec_usec == USEC_INFINITY) - unit_write_drop_in_private_format(u, mode, "CPUQuota", - "CPUQuota="); + unit_write_setting(u, flags, "CPUQuota", "CPUQuota="); else - /* config_parse_cpu_quota() requires an integer, so - * truncating division is used on purpose here. */ - unit_write_drop_in_private_format(u, mode, "CPUQuota", - "CPUQuota=%0.f%%", - (double) (c->cpu_quota_per_sec_usec / 10000)); + /* config_parse_cpu_quota() requires an integer, so truncating division is used on + * purpose here. */ + unit_write_settingf(u, flags, "CPUQuota", + "CPUQuota=%0.f%%", + (double) (c->cpu_quota_per_sec_usec / 10000)); } return 1; @@ -562,10 +566,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->io_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_IO); - unit_write_drop_in_private(u, mode, name, b ? "IOAccounting=yes" : "IOAccounting=no"); + unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b)); } return 1; @@ -578,16 +582,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "IOWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "IOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->io_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_IO); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "IOWeight="); + unit_write_setting(u, flags, name, "IOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "IOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "IOWeight=%" PRIu64, weight); } return 1; @@ -600,16 +604,16 @@ int bus_cgroup_set_property( return r; if (CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupIOWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "StartupIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_io_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_IO); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupIOWeight="); + unit_write_setting(u, flags, name, "StartupIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupIOWeight=%" PRIu64, weight); } return 1; @@ -625,7 +629,7 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceLimit *a = NULL, *b; LIST_FOREACH(device_limits, b, c->io_device_limits) { @@ -666,7 +670,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceLimit *a; _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -691,7 +695,7 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -708,9 +712,9 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID) - return sd_bus_error_set_errnof(error, EINVAL, "IODeviceWeight out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "IODeviceWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceWeight *a = NULL, *b; LIST_FOREACH(device_weights, b, c->io_device_weights) { @@ -743,7 +747,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupIODeviceWeight *a; @@ -767,7 +771,7 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -779,10 +783,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->blockio_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b)); } return 1; @@ -795,16 +799,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->blockio_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "BlockIOWeight="); + unit_write_setting(u, flags, name, "BlockIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "BlockIOWeight=%" PRIu64, weight); } return 1; @@ -817,16 +821,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight value out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_blockio_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupBlockIOWeight="); + unit_write_setting(u, flags, name, "StartupBlockIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupBlockIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupBlockIOWeight=%" PRIu64, weight); } return 1; @@ -846,7 +850,7 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceBandwidth *a = NULL, *b; LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { @@ -887,7 +891,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceBandwidth *a; _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -923,7 +927,8 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); } return 1; @@ -940,9 +945,9 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID) - return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight out of range"); + return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight= out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceWeight *a = NULL, *b; LIST_FOREACH(device_weights, b, c->blockio_device_weights) { @@ -975,7 +980,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupBlockIODeviceWeight *a; @@ -999,7 +1004,8 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); } return 1; @@ -1011,10 +1017,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b)); } return 1; @@ -1028,7 +1034,7 @@ int bus_cgroup_set_property( if (v <= 0) return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "MemoryLow")) c->memory_low = v; else if (streq(name, "MemoryHigh")) @@ -1041,9 +1047,9 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); if (v == CGROUP_LIMIT_MAX) - unit_write_drop_in_private_format(u, mode, name, "%s=infinity", name); + unit_write_settingf(u, flags, name, "%s=infinity", name); else - unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, v); + unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v); } return 1; @@ -1060,7 +1066,7 @@ int bus_cgroup_set_property( if (v <= 0 || v == UINT64_MAX) return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { const char *e; /* Chop off suffix */ @@ -1075,8 +1081,8 @@ int bus_cgroup_set_property( c->memory_max = v; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu32 "%%", name, - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); + unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } return 1; @@ -1090,14 +1096,14 @@ int bus_cgroup_set_property( if (limit <= 0) return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_limit = limit; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); if (limit == (uint64_t) -1) - unit_write_drop_in_private(u, mode, name, "MemoryLimit=infinity"); + unit_write_setting(u, flags, name, "MemoryLimit=infinity"); else - unit_write_drop_in_private_format(u, mode, name, "MemoryLimit=%" PRIu64, limit); + unit_write_settingf(u, flags, name, "MemoryLimit=%" PRIu64, limit); } return 1; @@ -1114,10 +1120,10 @@ int bus_cgroup_set_property( if (limit <= 0 || limit == UINT64_MAX) return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_limit = limit; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private_format(u, mode, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", + unit_write_settingf(u, flags, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } @@ -1135,10 +1141,10 @@ int bus_cgroup_set_property( if (p < 0) return -EINVAL; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->device_policy = p; unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES); - unit_write_drop_in_private_format(u, mode, name, "DevicePolicy=%s", policy); + unit_write_settingf(u, flags, name, "DevicePolicy=%s", policy); } return 1; @@ -1166,7 +1172,7 @@ int bus_cgroup_set_property( if (!in_charset(rwm, "rwm")) return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires combination of rwm flags"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupDeviceAllow *a = NULL, *b; LIST_FOREACH(device_allow, b, c->device_allow) { @@ -1204,7 +1210,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupDeviceAllow *a; @@ -1228,7 +1234,7 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -1240,10 +1246,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_drop_in_private(u, mode, name, b ? "TasksAccounting=yes" : "TasksAccounting=no"); + unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b)); } return 1; @@ -1257,14 +1263,14 @@ int bus_cgroup_set_property( if (limit <= 0) return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_max = limit; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); if (limit == (uint64_t) -1) - unit_write_drop_in_private(u, mode, name, "TasksMax=infinity"); + unit_write_setting(u, flags, name, "TasksMax=infinity"); else - unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu64, limit); + unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit); } return 1; @@ -1281,11 +1287,11 @@ int bus_cgroup_set_property( if (limit <= 0 || limit >= UINT64_MAX) return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_max = limit; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu32 "%%", - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); + unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%", + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } return 1; @@ -1297,11 +1303,11 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->ip_accounting = b; unit_invalidate_cgroup_bpf(u); - unit_write_drop_in_private(u, mode, name, b ? "IPAccounting=yes" : "IPAccounting=no"); + unit_write_settingf(u, flags, name, "IPAccounting=%s", yes_no(b)); } return 1; @@ -1350,7 +1356,7 @@ int bus_cgroup_set_property( if (prefixlen > FAMILY_ADDRESS_SIZE(family)*8) return sd_bus_error_set_errnof(error, EINVAL, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family)); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { IPAddressAccessItem *item; item = new0(IPAddressAccessItem, 1); @@ -1377,7 +1383,7 @@ int bus_cgroup_set_property( *list = ip_address_access_reduce(*list); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; IPAddressAccessItem *item; @@ -1407,7 +1413,8 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); if (*list) { r = bpf_firewall_supported(); @@ -1429,7 +1436,7 @@ int bus_cgroup_set_property( } if (u->transient && u->load_state == UNIT_STUB) { - r = bus_cgroup_set_transient_property(u, c, name, message, mode, error); + r = bus_cgroup_set_transient_property(u, c, name, message, flags, error); if (r != 0) return r; diff --git a/src/core/dbus-cgroup.h b/src/core/dbus-cgroup.h index 0e3b903f6f..0588370aa5 100644 --- a/src/core/dbus-cgroup.h +++ b/src/core/dbus-cgroup.h @@ -26,4 +26,4 @@ extern const sd_bus_vtable bus_cgroup_vtable[]; -int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_cgroup_set_property(Unit *u, CGroupContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 57ccdcbe33..412be2a6c4 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -32,6 +32,7 @@ #include "dbus-execute.h" #include "env-util.h" #include "errno-list.h" +#include "escape.h" #include "execute.h" #include "fd-util.h" #include "fileio.h" @@ -50,6 +51,7 @@ #include "seccomp-util.h" #endif #include "securebits-util.h" +#include "specifier.h" #include "strv.h" #include "syslog-util.h" #include "unit-printf.h" @@ -1037,7 +1039,7 @@ int bus_exec_context_set_transient_property( ExecContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { const char *soft = NULL; @@ -1048,6 +1050,8 @@ int bus_exec_context_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "User")) { const char *uu; @@ -1058,14 +1062,13 @@ int bus_exec_context_set_transient_property( if (!isempty(uu) && !valid_user_group_name_or_id(uu)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid user name: %s", uu); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (isempty(uu)) - c->user = mfree(c->user); - else if (free_and_strdup(&c->user, uu) < 0) - return -ENOMEM; + r = free_and_strdup(&c->user, empty_to_null(uu)); + if (r < 0) + return r; - unit_write_drop_in_private_format(u, mode, name, "User=%s", uu); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "User=%s", uu); } return 1; @@ -1080,14 +1083,13 @@ int bus_exec_context_set_transient_property( if (!isempty(gg) && !valid_user_group_name_or_id(gg)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid group name: %s", gg); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - if (isempty(gg)) - c->group = mfree(c->group); - else if (free_and_strdup(&c->group, gg) < 0) - return -ENOMEM; + r = free_and_strdup(&c->group, empty_to_null(gg)); + if (r < 0) + return r; - unit_write_drop_in_private_format(u, mode, name, "Group=%s", gg); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Group=%s", gg); } return 1; @@ -1105,10 +1107,10 @@ int bus_exec_context_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names"); } - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (strv_length(l) == 0) { c->supplementary_groups = strv_free(c->supplementary_groups); - unit_write_drop_in_private_format(u, mode, name, "%s=", name); + unit_write_settingf(u, flags, name, "%s=", name); } else { _cleanup_free_ char *joined = NULL; @@ -1120,7 +1122,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined); } } @@ -1133,14 +1135,14 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (isempty(id)) c->syslog_identifier = mfree(c->syslog_identifier); else if (free_and_strdup(&c->syslog_identifier, id) < 0) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "SyslogIdentifier=%s", id); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "SyslogIdentifier=%s", id); } return 1; @@ -1154,9 +1156,9 @@ int bus_exec_context_set_transient_property( if (!log_level_is_valid(level)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level; - unit_write_drop_in_private_format(u, mode, name, "SyslogLevel=%i", level); + unit_write_settingf(u, flags, name, "SyslogLevel=%i", level); } return 1; @@ -1170,9 +1172,9 @@ int bus_exec_context_set_transient_property( if (!log_facility_unshifted_is_valid(facility)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority); - unit_write_drop_in_private_format(u, mode, name, "SyslogFacility=%i", facility); + unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility); } return 1; @@ -1187,9 +1189,9 @@ int bus_exec_context_set_transient_property( if (!log_level_is_valid(level)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Maximum log level value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->log_level_max = level; - unit_write_drop_in_private_format(u, mode, name, "LogLevelMax=%i", level); + unit_write_settingf(u, flags, name, "LogLevelMax=%i", level); } return 1; @@ -1230,7 +1232,7 @@ int bus_exec_context_set_transient_property( if (!journal_field_valid(p, eq - (const char*) p, false)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { t = realloc_multiply(c->log_extra_fields, sizeof(struct iovec), c->n_log_extra_fields+1); if (!t) return -ENOMEM; @@ -1247,9 +1249,9 @@ int bus_exec_context_set_transient_property( if (!utf8_is_valid(copy)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz); - unit_write_drop_in_private_format(u, mode, name, "LogExtraFields=%s", (char*) copy); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy); copy = NULL; } @@ -1261,9 +1263,9 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK && n == 0) { + if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) { exec_context_free_log_extra_fields(c); - unit_write_drop_in_private(u, mode, name, "LogExtraFields="); + unit_write_setting(u, flags, name, "LogExtraFields="); } return 1; @@ -1278,7 +1280,7 @@ int bus_exec_context_set_transient_property( if (!secure_bits_is_valid(n)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *str = NULL; c->secure_bits = n; @@ -1286,7 +1288,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "SecureBits=%s", str); + unit_write_settingf(u, flags, name, "SecureBits=%s", str); } return 1; @@ -1297,7 +1299,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *str = NULL; if (streq(name, "CapabilityBoundingSet")) @@ -1309,7 +1311,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str); + unit_write_settingf(u, flags, name, "%s=%s", name, str); } return 1; @@ -1326,9 +1328,9 @@ int bus_exec_context_set_transient_property( if (p == PERSONALITY_INVALID) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->personality = p; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s); + unit_write_settingf(u, flags, name, "%s=%s", name, s); } return 1; @@ -1355,7 +1357,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *joined = NULL; if (strv_length(l) == 0) { @@ -1416,7 +1418,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined); + unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined); } return 1; @@ -1428,7 +1430,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *joined = NULL; if (strv_length(l) == 0) @@ -1458,7 +1460,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined); + unit_write_settingf(u, flags, name, "%s=%s", name, joined); } return 1; @@ -1473,10 +1475,10 @@ int bus_exec_context_set_transient_property( if (n <= 0 || n > ERRNO_MAX) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->syscall_errno = n; - unit_write_drop_in_private_format(u, mode, name, "SystemCallErrorNumber=%d", n); + unit_write_settingf(u, flags, name, "SystemCallErrorNumber=%d", n); } return 1; @@ -1501,7 +1503,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *joined = NULL; if (strv_length(l) == 0) { @@ -1533,7 +1535,7 @@ int bus_exec_context_set_transient_property( if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined); + unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined); } return 1; @@ -1549,7 +1551,7 @@ int bus_exec_context_set_transient_property( if (!sched_policy_is_valid(n)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *str = NULL; c->cpu_sched_policy = n; @@ -1557,7 +1559,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPolicy=%s", str); + unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", str); } return 1; @@ -1572,9 +1574,9 @@ int bus_exec_context_set_transient_property( if (!ioprio_priority_is_valid(n)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_sched_priority = n; - unit_write_drop_in_private_format(u, mode, name, "CPUSchedulingPriority=%i", n); + unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", n); } return 1; @@ -1587,10 +1589,10 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (n == 0) { c->cpuset = mfree(c->cpuset); - unit_write_drop_in_private_format(u, mode, name, "%s=", name); + unit_write_settingf(u, flags, name, "%s=", name); } else { _cleanup_free_ char *str = NULL; uint8_t *l; @@ -1621,7 +1623,7 @@ int bus_exec_context_set_transient_property( if (len != 0) str[len - 1] = '\0'; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, str); + unit_write_settingf(u, flags, name, "%s=%s", name, str); } } @@ -1636,9 +1638,9 @@ int bus_exec_context_set_transient_property( if (!nice_is_valid(n)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->nice = n; - unit_write_drop_in_private_format(u, mode, name, "Nice=%i", n); + unit_write_settingf(u, flags, name, "Nice=%i", n); } return 1; @@ -1653,7 +1655,7 @@ int bus_exec_context_set_transient_property( if (!ioprio_class_is_valid(q)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *s = NULL; r = ioprio_class_to_string_alloc(q, &s); @@ -1663,7 +1665,7 @@ int bus_exec_context_set_transient_property( c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio)); c->ioprio_set = true; - unit_write_drop_in_private_format(u, mode, name, "IOSchedulingClass=%s", s); + unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s); } return 1; @@ -1678,11 +1680,11 @@ int bus_exec_context_set_transient_property( if (!ioprio_priority_is_valid(p)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p); c->ioprio_set = true; - unit_write_drop_in_private_format(u, mode, name, "IOSchedulingPriority=%i", p); + unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p); } return 1; @@ -1697,7 +1699,7 @@ int bus_exec_context_set_transient_property( if (!path_is_absolute(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "TTYPath")) r = free_and_strdup(&c->tty_path, s); else if (streq(name, "RootImage")) @@ -1709,7 +1711,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, s); } return 1; @@ -1731,7 +1733,7 @@ int bus_exec_context_set_transient_property( if (!streq(s, "~") && !path_is_absolute(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(s, "~")) { c->working_directory = mfree(c->working_directory); c->working_directory_home = true; @@ -1744,7 +1746,7 @@ int bus_exec_context_set_transient_property( } c->working_directory_missing_ok = missing_ok; - unit_write_drop_in_private_format(u, mode, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s); } return 1; @@ -1761,10 +1763,10 @@ int bus_exec_context_set_transient_property( if (p < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->std_input = p; - unit_write_drop_in_private_format(u, mode, name, "StandardInput=%s", exec_input_to_string(p)); + unit_write_settingf(u, flags, name, "StandardInput=%s", exec_input_to_string(p)); } return 1; @@ -1781,10 +1783,10 @@ int bus_exec_context_set_transient_property( if (p < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->std_output = p; - unit_write_drop_in_private_format(u, mode, name, "StandardOutput=%s", exec_output_to_string(p)); + unit_write_settingf(u, flags, name, "StandardOutput=%s", exec_output_to_string(p)); } return 1; @@ -1801,10 +1803,10 @@ int bus_exec_context_set_transient_property( if (p < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->std_error = p; - unit_write_drop_in_private_format(u, mode, name, "StandardError=%s", exec_output_to_string(p)); + unit_write_settingf(u, flags, name, "StandardError=%s", exec_output_to_string(p)); } return 1; @@ -1822,7 +1824,7 @@ int bus_exec_context_set_transient_property( else if (!fdname_is_valid(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "StandardInputFileDescriptorName")) { r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, s); @@ -1830,7 +1832,7 @@ int bus_exec_context_set_transient_property( return r; c->std_input = EXEC_INPUT_NAMED_FD; - unit_write_drop_in_private_format(u, mode, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO)); } else if (streq(name, "StandardOutputFileDescriptorName")) { r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, s); @@ -1838,7 +1840,7 @@ int bus_exec_context_set_transient_property( return r; c->std_output = EXEC_OUTPUT_NAMED_FD; - unit_write_drop_in_private_format(u, mode, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO)); } else { assert(streq(name, "StandardErrorFileDescriptorName")); @@ -1848,7 +1850,7 @@ int bus_exec_context_set_transient_property( return r; c->std_error = EXEC_OUTPUT_NAMED_FD; - unit_write_drop_in_private_format(u, mode, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO)); } } @@ -1866,7 +1868,7 @@ int bus_exec_context_set_transient_property( if (!path_is_normalized(s)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "StandardInputFile")) { r = free_and_strdup(&c->stdio_file[STDIN_FILENO], s); @@ -1874,7 +1876,7 @@ int bus_exec_context_set_transient_property( return r; c->std_input = EXEC_INPUT_FILE; - unit_write_drop_in_private_format(u, mode, name, "StandardInput=file:%s", s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s); } else if (streq(name, "StandardOutputFile")) { r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], s); @@ -1882,7 +1884,7 @@ int bus_exec_context_set_transient_property( return r; c->std_output = EXEC_OUTPUT_FILE; - unit_write_drop_in_private_format(u, mode, name, "StandardOutput=file:%s", s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s); } else { assert(streq(name, "StandardErrorFile")); @@ -1892,7 +1894,7 @@ int bus_exec_context_set_transient_property( return r; c->std_error = EXEC_OUTPUT_FILE; - unit_write_drop_in_private_format(u, mode, name, "StandardError=file:%s", s); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s); } } @@ -1906,14 +1908,14 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *encoded = NULL; if (sz == 0) { c->stdin_data = mfree(c->stdin_data); c->stdin_data_size = 0; - unit_write_drop_in_private(u, mode, name, "StandardInputData="); + unit_write_settingf(u, flags, name, "StandardInputData="); } else { void *q; ssize_t n; @@ -1935,7 +1937,7 @@ int bus_exec_context_set_transient_property( c->stdin_data = q; c->stdin_data_size += sz; - unit_write_drop_in_private_format(u, mode, name, "StandardInputData=%s", encoded); + unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded); } } @@ -1954,7 +1956,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "IgnoreSIGPIPE")) c->ignore_sigpipe = b; else if (streq(name, "TTYVHangup")) @@ -1998,7 +2000,7 @@ int bus_exec_context_set_transient_property( else if (streq(name, "LockPersonality")) c->lock_personality = b; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, yes_no(b)); + unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b)); } return 1; @@ -2010,13 +2012,13 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { - if (isempty(id)) - c->utmp_id = mfree(c->utmp_id); - else if (free_and_strdup(&c->utmp_id, id) < 0) - return -ENOMEM; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + + r = free_and_strdup(&c->utmp_id, empty_to_null(id)); + if (r < 0) + return r; - unit_write_drop_in_private_format(u, mode, name, "UtmpIdentifier=%s", strempty(id)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "UtmpIdentifier=%s", strempty(id)); } return 1; @@ -2033,10 +2035,10 @@ int bus_exec_context_set_transient_property( if (m < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->utmp_mode = m; - unit_write_drop_in_private_format(u, mode, name, "UtmpMode=%s", exec_utmp_mode_to_string(m)); + unit_write_settingf(u, flags, name, "UtmpMode=%s", exec_utmp_mode_to_string(m)); } return 1; @@ -2048,13 +2050,13 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { - if (isempty(n)) - c->pam_name = mfree(c->pam_name); - else if (free_and_strdup(&c->pam_name, n) < 0) - return -ENOMEM; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - unit_write_drop_in_private_format(u, mode, name, "PAMName=%s", strempty(n)); + r = free_and_strdup(&c->pam_name, empty_to_null(n)); + if (r < 0) + return r; + + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "PAMName=%s", strempty(n)); } return 1; @@ -2070,14 +2072,18 @@ int bus_exec_context_set_transient_property( if (!strv_env_is_valid(l)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block."); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (strv_length(l) == 0) { c->environment = strv_free(c->environment); - unit_write_drop_in_private_format(u, mode, name, "Environment="); + unit_write_setting(u, flags, name, "Environment="); } else { _cleanup_free_ char *joined = NULL; char **e; + joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C); + if (!joined) + return -ENOMEM; + e = strv_env_merge(2, c->environment, l); if (!e) return -ENOMEM; @@ -2085,11 +2091,7 @@ int bus_exec_context_set_transient_property( strv_free(c->environment); c->environment = e; - joined = strv_join_quoted(l); - if (!joined) - return -ENOMEM; - - unit_write_drop_in_private_format(u, mode, name, "Environment=%s", joined); + unit_write_settingf(u, flags, name, "Environment=%s", joined); } } @@ -2106,14 +2108,18 @@ int bus_exec_context_set_transient_property( if (!strv_env_name_or_assignment_is_valid(l)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list."); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (strv_length(l) == 0) { c->unset_environment = strv_free(c->unset_environment); - unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment="); + unit_write_setting(u, flags, name, "UnsetEnvironment="); } else { _cleanup_free_ char *joined = NULL; char **e; + joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C); + if (!joined) + return -ENOMEM; + e = strv_env_merge(2, c->unset_environment, l); if (!e) return -ENOMEM; @@ -2121,12 +2127,7 @@ int bus_exec_context_set_transient_property( strv_free(c->unset_environment); c->unset_environment = e; - /* We write just the new settings out to file, with unresolved specifiers */ - joined = strv_join_quoted(l); - if (!joined) - return -ENOMEM; - - unit_write_drop_in_private_format(u, mode, name, "UnsetEnvironment=%s", joined); + unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined); } } @@ -2140,9 +2141,9 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->timer_slack_nsec = n; - unit_write_drop_in_private_format(u, mode, name, "TimerSlackNSec=" NSEC_FMT, n); + unit_write_settingf(u, flags, name, "TimerSlackNSec=" NSEC_FMT, n); } return 1; @@ -2157,10 +2158,10 @@ int bus_exec_context_set_transient_property( if (!oom_score_adjust_is_valid(oa)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->oom_score_adjust = oa; c->oom_score_adjust_set = true; - unit_write_drop_in_private_format(u, mode, name, "OOMScoreAdjust=%i", oa); + unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa); } return 1; @@ -2181,8 +2182,17 @@ int bus_exec_context_set_transient_property( if (!f) return -ENOMEM; - STRV_FOREACH(i, c->environment_files) - fprintf(f, "EnvironmentFile=%s", *i); + fputs("EnvironmentFile=\n", f); + + STRV_FOREACH(i, c->environment_files) { + _cleanup_free_ char *q = NULL; + + q = specifier_escape(*i); + if (!q) + return -ENOMEM; + + fprintf(f, "EnvironmentFile=%s\n", q); + } while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) { const char *path; @@ -2199,14 +2209,21 @@ int bus_exec_context_set_transient_property( if (!path_is_absolute(path)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *q = NULL; char *buf; buf = strjoin(b ? "-" : "", path); if (!buf) return -ENOMEM; - fprintf(f, "EnvironmentFile=%s", buf); + q = specifier_escape(buf); + if (!q) { + free(buf); + return -ENOMEM; + } + + fprintf(f, "EnvironmentFile=%s\n", q); r = strv_consume(&l, buf); if (r < 0) @@ -2224,16 +2241,16 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (strv_isempty(l)) { c->environment_files = strv_free(c->environment_files); - unit_write_drop_in_private(u, mode, name, "EnvironmentFile="); + unit_write_setting(u, flags, name, "EnvironmentFile="); } else { r = strv_extend_strv(&c->environment_files, l, true); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, joined); + unit_write_setting(u, flags, name, joined); } } @@ -2250,19 +2267,19 @@ int bus_exec_context_set_transient_property( if (!strv_env_name_is_valid(l)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block."); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (strv_isempty(l)) { c->pass_environment = strv_free(c->pass_environment); - unit_write_drop_in_private_format(u, mode, name, "PassEnvironment="); + unit_write_setting(u, flags, name, "PassEnvironment="); } else { _cleanup_free_ char *joined = NULL; /* We write just the new settings out to file, with unresolved specifiers. */ - joined = strv_join_quoted(l); + joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS); if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "PassEnvironment=%s", joined); + unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined); } } @@ -2291,9 +2308,7 @@ int bus_exec_context_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name); } - if (mode != UNIT_CHECK) { - _cleanup_free_ char *joined = NULL; - + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths")) dirs = &c->read_write_paths; else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths")) @@ -2303,19 +2318,20 @@ int bus_exec_context_set_transient_property( if (strv_length(l) == 0) { *dirs = strv_free(*dirs); - unit_write_drop_in_private_format(u, mode, name, "%s=", name); + unit_write_settingf(u, flags, name, "%s=", name); } else { - r = strv_extend_strv(dirs, l, true); - if (r < 0) - return -ENOMEM; + _cleanup_free_ char *joined = NULL; - joined = strv_join_quoted(*dirs); + joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS); if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined); - } + r = strv_extend_strv(dirs, l, true); + if (r < 0) + return -ENOMEM; + unit_write_settingf(u, flags, name, "%s=%s", name, joined); + } } return 1; @@ -2339,9 +2355,9 @@ int bus_exec_context_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value"); } - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->protect_system = ps; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s); + unit_write_settingf(u, flags, name, "%s=%s", name, s); } return 1; @@ -2365,9 +2381,9 @@ int bus_exec_context_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value"); } - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->protect_home = ph; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s); + unit_write_settingf(u, flags, name, "%s=%s", name, s); } return 1; @@ -2385,10 +2401,10 @@ int bus_exec_context_set_transient_property( if (m < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->keyring_mode = m; - unit_write_drop_in_private_format(u, mode, name, "KeyringMode=%s", exec_keyring_mode_to_string(m)); + unit_write_settingf(u, flags, name, "KeyringMode=%s", exec_keyring_mode_to_string(m)); } return 1; @@ -2405,10 +2421,10 @@ int bus_exec_context_set_transient_property( if (m < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->runtime_directory_preserve_mode = m; - unit_write_drop_in_private_format(u, mode, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m)); + unit_write_settingf(u, flags, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m)); } return 1; @@ -2420,7 +2436,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ExecDirectoryType i; if (streq(name, "UMask")) @@ -2432,7 +2448,7 @@ int bus_exec_context_set_transient_property( break; } - unit_write_drop_in_private_format(u, mode, name, "%s=%040o", name, m); + unit_write_settingf(u, flags, name, "%s=%040o", name, m); } return 1; @@ -2450,8 +2466,7 @@ int bus_exec_context_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not valid: %s", name, *p); } - if (mode != UNIT_CHECK) { - _cleanup_free_ char *joined = NULL; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { char ***dirs = NULL; ExecDirectoryType i; @@ -2465,17 +2480,19 @@ int bus_exec_context_set_transient_property( if (strv_isempty(l)) { *dirs = strv_free(*dirs); - unit_write_drop_in_private_format(u, mode, name, "%s=", name); + unit_write_settingf(u, flags, name, "%s=", name); } else { + _cleanup_free_ char *joined = NULL; + r = strv_extend_strv(dirs, l, true); if (r < 0) return -ENOMEM; - joined = strv_join_quoted(*dirs); + joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS); if (!joined) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, joined); + unit_write_settingf(u, flags, name, "%s=%s", name, joined); } } @@ -2487,13 +2504,13 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (isempty(s)) c->selinux_context = mfree(c->selinux_context); else if (free_and_strdup(&c->selinux_context, s) < 0) return -ENOMEM; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, strempty(s)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(s)); } return 1; @@ -2510,7 +2527,7 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { char **p; bool *b; @@ -2531,45 +2548,45 @@ int bus_exec_context_set_transient_property( *b = ignore; } - unit_write_drop_in_private_format(u, mode, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s)); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s)); } return 1; } else if (streq(name, "RestrictNamespaces")) { - uint64_t flags; + uint64_t rf; - r = sd_bus_message_read(message, "t", &flags); + r = sd_bus_message_read(message, "t", &rf); if (r < 0) return r; - if ((flags & NAMESPACE_FLAGS_ALL) != flags) + if ((rf & NAMESPACE_FLAGS_ALL) != rf) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *s = NULL; - r = namespace_flag_to_string_many(flags, &s); + r = namespace_flag_to_string_many(rf, &s); if (r < 0) return r; - c->restrict_namespaces = flags; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, s); + c->restrict_namespaces = rf; + unit_write_settingf(u, flags, name, "%s=%s", name, s); } return 1; } else if (streq(name, "MountFlags")) { - uint64_t flags; + uint64_t fl; - r = sd_bus_message_read(message, "t", &flags); + r = sd_bus_message_read(message, "t", &fl); if (r < 0) return r; - if (!IN_SET(flags, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE)) + if (!IN_SET(fl, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount propagation flags"); - if (mode != UNIT_CHECK) { - c->mount_flags = flags; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + c->mount_flags = fl; - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, mount_propagation_flags_to_string(flags)); + unit_write_settingf(u, flags, name, "%s=%s", name, mount_propagation_flags_to_string(fl)); } return 1; @@ -2600,7 +2617,7 @@ int bus_exec_context_set_transient_property( if (!IN_SET(mount_flags, 0, MS_REC)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags."); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts, &(BindMount) { .source = strdup(source), @@ -2612,8 +2629,8 @@ int bus_exec_context_set_transient_property( if (r < 0) return r; - unit_write_drop_in_private_format( - u, mode, name, + unit_write_settingf( + u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s:%s:%s", name, ignore_enoent ? "-" : "", @@ -2635,6 +2652,8 @@ int bus_exec_context_set_transient_property( bind_mount_free_many(c->bind_mounts, c->n_bind_mounts); c->bind_mounts = NULL; c->n_bind_mounts = 0; + + unit_write_settingf(u, flags, name, "%s=", name); } return 1; @@ -2671,7 +2690,7 @@ int bus_exec_context_set_transient_property( return -ERANGE; } - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *f = NULL; struct rlimit nl; @@ -2701,7 +2720,7 @@ int bus_exec_context_set_transient_property( return -ENOMEM; } - unit_write_drop_in_private_format(u, mode, name, "%s=%s", name, f); + unit_write_settingf(u, flags, name, "%s=%s", name, f); } return 1; diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h index 631edcc8c8..f30f0774cd 100644 --- a/src/core/dbus-execute.h +++ b/src/core/dbus-execute.h @@ -43,4 +43,4 @@ int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *inte int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); -int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index 4ac9f363cc..bf3bbb2047 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -39,7 +39,7 @@ int bus_kill_context_set_transient_property( KillContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -49,6 +49,8 @@ int bus_kill_context_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "KillMode")) { const char *m; KillMode k; @@ -61,10 +63,10 @@ int bus_kill_context_set_transient_property( if (k < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->kill_mode = k; - unit_write_drop_in_private_format(u, mode, name, "KillMode=%s", kill_mode_to_string(k)); + unit_write_settingf(u, flags, name, "KillMode=%s", kill_mode_to_string(k)); } return 1; @@ -79,10 +81,10 @@ int bus_kill_context_set_transient_property( if (!SIGNAL_VALID(sig)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->kill_signal = sig; - unit_write_drop_in_private_format(u, mode, name, "KillSignal=%s", signal_to_string(sig)); + unit_write_settingf(u, flags, name, "KillSignal=%s", signal_to_string(sig)); } return 1; @@ -94,10 +96,10 @@ int bus_kill_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->send_sighup = b; - unit_write_drop_in_private_format(u, mode, name, "SendSIGHUP=%s", yes_no(b)); + unit_write_settingf(u, flags, name, "SendSIGHUP=%s", yes_no(b)); } return 1; @@ -109,10 +111,10 @@ int bus_kill_context_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->send_sigkill = b; - unit_write_drop_in_private_format(u, mode, name, "SendSIGKILL=%s", yes_no(b)); + unit_write_settingf(u, flags, name, "SendSIGKILL=%s", yes_no(b)); } return 1; diff --git a/src/core/dbus-kill.h b/src/core/dbus-kill.h index 44fb9f9a93..1df3b37c65 100644 --- a/src/core/dbus-kill.h +++ b/src/core/dbus-kill.h @@ -27,4 +27,4 @@ extern const sd_bus_vtable bus_kill_vtable[]; -int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_kill_context_set_transient_property(Unit *u, KillContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c index 794b292ad3..628bce0b6a 100644 --- a/src/core/dbus-mount.c +++ b/src/core/dbus-mount.c @@ -126,18 +126,19 @@ static int bus_mount_set_transient_property( Mount *m, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { const char *new_property; char **property; - char *p; int r; assert(m); assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "What")) property = &m->parameters_fragment.what; else if (streq(name, "Options")) @@ -151,16 +152,13 @@ static int bus_mount_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { - p = strdup(new_property); - if (!p) - return -ENOMEM; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { - unit_write_drop_in_format(UNIT(m), mode, name, "[Mount]\n%s=%s\n", - name, new_property); + r = free_and_strdup(property, new_property); + if (r < 0) + return r; - free(*property); - *property = p; + unit_write_settingf(UNIT(m), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, new_property); } return 1; @@ -170,7 +168,7 @@ int bus_mount_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Mount *m = MOUNT(u); @@ -180,22 +178,22 @@ int bus_mount_set_property( assert(name); assert(message); - r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, mode, error); + r = bus_cgroup_set_property(u, &m->cgroup_context, name, message, flags, error); if (r != 0) return r; if (u->transient && u->load_state == UNIT_STUB) { /* This is a transient unit, let's load a little more */ - r = bus_mount_set_transient_property(m, name, message, mode, error); + r = bus_mount_set_transient_property(m, name, message, flags, error); if (r != 0) return r; - r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, mode, error); + r = bus_exec_context_set_transient_property(u, &m->exec_context, name, message, flags, error); if (r != 0) return r; - r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, mode, error); + r = bus_kill_context_set_transient_property(u, &m->kill_context, name, message, flags, error); if (r != 0) return r; } diff --git a/src/core/dbus-mount.h b/src/core/dbus-mount.h index f0a763788f..5d5e1f679f 100644 --- a/src/core/dbus-mount.h +++ b/src/core/dbus-mount.h @@ -26,5 +26,5 @@ extern const sd_bus_vtable bus_mount_vtable[]; -int bus_mount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_mount_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_mount_commit_properties(Unit *u); diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c index 4737c6d406..9195ad36d0 100644 --- a/src/core/dbus-scope.c +++ b/src/core/dbus-scope.c @@ -73,7 +73,7 @@ static int bus_scope_set_transient_property( Scope *s, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -82,6 +82,8 @@ static int bus_scope_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "PIDs")) { unsigned n = 0; uint32_t pid; @@ -95,7 +97,7 @@ static int bus_scope_set_transient_property( if (pid <= 1) return -EINVAL; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_watch_pid(UNIT(s), pid); if (r < 0 && r != -EEXIST) return r; @@ -117,7 +119,6 @@ static int bus_scope_set_transient_property( } else if (streq(name, "Controller")) { const char *controller; - char *c; /* We can't support direct connections with this, as direct connections know no service or unique name * concept, but the Controller field stores exactly that. */ @@ -131,33 +132,25 @@ static int bus_scope_set_transient_property( if (!isempty(controller) && !service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); - if (mode != UNIT_CHECK) { - if (isempty(controller)) - c = NULL; - else { - c = strdup(controller); - if (!c) - return -ENOMEM; - } - - free(s->controller); - s->controller = c; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + r = free_and_strdup(&s->controller, empty_to_null(controller)); + if (r < 0) + return r; } return 1; } else if (streq(name, "TimeoutStopUSec")) { + uint64_t t; - if (mode != UNIT_CHECK) { - r = sd_bus_message_read(message, "t", &s->timeout_stop_usec); - if (r < 0) - return r; + r = sd_bus_message_read(message, "t", &t); + if (r < 0) + return r; - unit_write_drop_in_private_format(UNIT(s), mode, name, "TimeoutStopSec="USEC_FMT"us", s->timeout_stop_usec); - } else { - r = sd_bus_message_skip(message, "t"); - if (r < 0) - return r; + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + s->timeout_stop_usec = t; + + unit_write_settingf(UNIT(s), flags, name, "TimeoutStopSec=" USEC_FMT "us", t); } return 1; @@ -170,7 +163,7 @@ int bus_scope_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Scope *s = SCOPE(u); @@ -180,18 +173,18 @@ int bus_scope_set_property( assert(name); assert(message); - r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error); + r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); if (r != 0) return r; if (u->load_state == UNIT_STUB) { /* While we are created we still accept PIDs */ - r = bus_scope_set_transient_property(s, name, message, mode, error); + r = bus_scope_set_transient_property(s, name, message, flags, error); if (r != 0) return r; - r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error); + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error); if (r != 0) return r; } diff --git a/src/core/dbus-scope.h b/src/core/dbus-scope.h index c80317c4b2..aa604897eb 100644 --- a/src/core/dbus-scope.h +++ b/src/core/dbus-scope.h @@ -26,7 +26,7 @@ extern const sd_bus_vtable bus_scope_vtable[]; -int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error); int bus_scope_commit_properties(Unit *u); int bus_scope_send_request_stop(Scope *s); diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c index 7b6cb395d8..593094ee33 100644 --- a/src/core/dbus-service.c +++ b/src/core/dbus-service.c @@ -90,7 +90,7 @@ static int bus_service_set_transient_property( Service *s, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -99,6 +99,8 @@ static int bus_service_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "RemainAfterExit")) { int b; @@ -106,9 +108,9 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->remain_after_exit = b; - unit_write_drop_in_private_format(UNIT(s), mode, name, "RemainAfterExit=%s", yes_no(b)); + unit_write_settingf(UNIT(s), flags, name, "RemainAfterExit=%s", yes_no(b)); } return 1; @@ -125,9 +127,9 @@ static int bus_service_set_transient_property( if (k < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->type = k; - unit_write_drop_in_private_format(UNIT(s), mode, name, "Type=%s", service_type_to_string(s->type)); + unit_write_settingf(UNIT(s), flags, name, "Type=%s", service_type_to_string(s->type)); } return 1; @@ -138,9 +140,9 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->runtime_max_usec = u; - unit_write_drop_in_private_format(UNIT(s), mode, name, "RuntimeMaxSec=" USEC_FMT "us", u); + unit_write_settingf(UNIT(s), flags, name, "RuntimeMaxSec=" USEC_FMT "us", u); } return 1; @@ -161,9 +163,9 @@ static int bus_service_set_transient_property( return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid restart setting: %s", v); } - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->restart = sr; - unit_write_drop_in_private_format(UNIT(s), mode, name, "Restart=%s", service_restart_to_string(sr)); + unit_write_settingf(UNIT(s), flags, name, "Restart=%s", service_restart_to_string(sr)); } return 1; @@ -178,7 +180,7 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { int copy; copy = fcntl(fd, F_DUPFD_CLOEXEC, 3); @@ -208,9 +210,9 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->n_fd_store_max = (unsigned) u; - unit_write_drop_in_private_format(UNIT(s), mode, name, "FileDescriptorStoreMax=%" PRIu32, u); + unit_write_settingf(UNIT(s), flags, name, "FileDescriptorStoreMax=%" PRIu32, u); } return 1; @@ -227,9 +229,9 @@ static int bus_service_set_transient_property( if (k < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { s->notify_access = k; - unit_write_drop_in_private_format(UNIT(s), mode, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access)); + unit_write_settingf(UNIT(s), flags, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access)); } return 1; @@ -265,7 +267,7 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ExecCommand *c; c = new0(ExecCommand, 1); @@ -297,7 +299,7 @@ static int bus_service_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; ExecCommand *c; @@ -313,22 +315,28 @@ static int bus_service_set_transient_property( fputs_unlocked("ExecStart=\n", f); LIST_FOREACH(command, c, s->exec_command[SERVICE_EXEC_START]) { - _cleanup_free_ char *a; + _cleanup_free_ char *a = NULL, *t = NULL; + const char *p; + + p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t); + if (!p) + return -ENOMEM; - a = strv_join_quoted(c->argv); + a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS); if (!a) return -ENOMEM; fprintf(f, "ExecStart=%s@%s %s\n", c->flags & EXEC_COMMAND_IGNORE_FAILURE ? "-" : "", - c->path, + p, a); } r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(UNIT(s), mode, name, buf); + + unit_write_setting(UNIT(s), flags, name, buf); } return 1; @@ -341,7 +349,7 @@ int bus_service_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Service *s = SERVICE(u); @@ -351,22 +359,22 @@ int bus_service_set_property( assert(name); assert(message); - r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error); + r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); if (r != 0) return r; if (u->transient && u->load_state == UNIT_STUB) { /* This is a transient unit, let's load a little more */ - r = bus_service_set_transient_property(s, name, message, mode, error); + r = bus_service_set_transient_property(s, name, message, flags, error); if (r != 0) return r; - r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, mode, error); + r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, flags, error); if (r != 0) return r; - r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, mode, error); + r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error); if (r != 0) return r; } diff --git a/src/core/dbus-service.h b/src/core/dbus-service.h index a0f89fa23c..2da29ec601 100644 --- a/src/core/dbus-service.h +++ b/src/core/dbus-service.h @@ -26,5 +26,5 @@ extern const sd_bus_vtable bus_service_vtable[]; -int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_service_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error); int bus_service_commit_properties(Unit *u); diff --git a/src/core/dbus-slice.c b/src/core/dbus-slice.c index d269cb2b1e..fa2ff72151 100644 --- a/src/core/dbus-slice.c +++ b/src/core/dbus-slice.c @@ -32,7 +32,7 @@ int bus_slice_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Slice *s = SLICE(u); @@ -40,7 +40,7 @@ int bus_slice_set_property( assert(name); assert(u); - return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error); + return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); } int bus_slice_commit_properties(Unit *u) { diff --git a/src/core/dbus-slice.h b/src/core/dbus-slice.h index 5855332126..0c21919ad1 100644 --- a/src/core/dbus-slice.h +++ b/src/core/dbus-slice.h @@ -26,5 +26,5 @@ extern const sd_bus_vtable bus_slice_vtable[]; -int bus_slice_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_slice_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_slice_commit_properties(Unit *u); diff --git a/src/core/dbus-socket.c b/src/core/dbus-socket.c index 3c7d99c356..930b7fa87d 100644 --- a/src/core/dbus-socket.c +++ b/src/core/dbus-socket.c @@ -166,7 +166,7 @@ int bus_socket_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Socket *s = SOCKET(u); @@ -175,7 +175,7 @@ int bus_socket_set_property( assert(name); assert(message); - return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error); + return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); } int bus_socket_commit_properties(Unit *u) { diff --git a/src/core/dbus-socket.h b/src/core/dbus-socket.h index ee9663f904..e6db2d0772 100644 --- a/src/core/dbus-socket.h +++ b/src/core/dbus-socket.h @@ -26,5 +26,5 @@ extern const sd_bus_vtable bus_socket_vtable[]; -int bus_socket_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_socket_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_socket_commit_properties(Unit *u); diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c index ae67f3e6d5..795aaa94fe 100644 --- a/src/core/dbus-swap.c +++ b/src/core/dbus-swap.c @@ -96,7 +96,7 @@ int bus_swap_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { Swap *s = SWAP(u); @@ -105,7 +105,7 @@ int bus_swap_set_property( assert(name); assert(message); - return bus_cgroup_set_property(u, &s->cgroup_context, name, message, mode, error); + return bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error); } int bus_swap_commit_properties(Unit *u) { diff --git a/src/core/dbus-swap.h b/src/core/dbus-swap.h index 7df5cc7e54..6cca7483d8 100644 --- a/src/core/dbus-swap.h +++ b/src/core/dbus-swap.h @@ -27,5 +27,5 @@ extern const sd_bus_vtable bus_swap_vtable[]; -int bus_swap_set_property(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_swap_set_property(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); int bus_swap_commit_properties(Unit *u); diff --git a/src/core/dbus-timer.c b/src/core/dbus-timer.c index 282d7f6fab..e4403203ed 100644 --- a/src/core/dbus-timer.c +++ b/src/core/dbus-timer.c @@ -176,7 +176,7 @@ static int bus_timer_set_transient_property( Timer *t, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -185,6 +185,8 @@ static int bus_timer_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (STR_IN_SET(name, "OnActiveSec", "OnBootSec", @@ -204,10 +206,10 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { char time[FORMAT_TIMESPAN_MAX]; - unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC)); + unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC)); v = new0(TimerValue, 1); if (!v) @@ -231,12 +233,12 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = calendar_spec_from_string(str, &c); if (r < 0) return r; - unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, str); + unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str); v = new0(TimerValue, 1); if (!v) { @@ -262,9 +264,9 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { t->accuracy_usec = u; - unit_write_drop_in_private_format(UNIT(t), mode, name, "AccuracySec=" USEC_FMT "us", u); + unit_write_settingf(UNIT(t), flags, name, "AccuracySec=" USEC_FMT "us", u); } return 1; @@ -276,9 +278,9 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { t->random_usec = u; - unit_write_drop_in_private_format(UNIT(t), mode, name, "RandomizedDelaySec=" USEC_FMT "us", u); + unit_write_settingf(UNIT(t), flags, name, "RandomizedDelaySec=" USEC_FMT "us", u); } return 1; @@ -290,9 +292,9 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { t->wake_system = b; - unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, yes_no(b)); + unit_write_settingf(UNIT(t), flags, name, "%s=%s", name, yes_no(b)); } return 1; @@ -304,9 +306,9 @@ static int bus_timer_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { t->remain_after_elapse = b; - unit_write_drop_in_private_format(UNIT(t), mode, name, "%s=%s", name, yes_no(b)); + unit_write_settingf(UNIT(t), flags, name, "%s=%s", name, yes_no(b)); } return 1; @@ -319,21 +321,17 @@ int bus_timer_set_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags mode, sd_bus_error *error) { Timer *t = TIMER(u); - int r; assert(t); assert(name); assert(message); - if (u->transient && u->load_state == UNIT_STUB) { - r = bus_timer_set_transient_property(t, name, message, mode, error); - if (r != 0) - return r; - } + if (u->transient && u->load_state == UNIT_STUB) + return bus_timer_set_transient_property(t, name, message, mode, error); return 0; } diff --git a/src/core/dbus-timer.h b/src/core/dbus-timer.h index e71f6cfefb..d810b048ee 100644 --- a/src/core/dbus-timer.h +++ b/src/core/dbus-timer.h @@ -26,4 +26,4 @@ extern const sd_bus_vtable bus_timer_vtable[]; -int bus_timer_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSetPropertiesMode mode, sd_bus_error *error); +int bus_timer_set_property(Unit *u, const char *name, sd_bus_message *i, UnitWriteFlags flags, sd_bus_error *error); diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index d4bdf1760a..5d4bc28cde 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -1319,7 +1319,7 @@ static int bus_unit_set_transient_property( Unit *u, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -1335,12 +1335,12 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_set_description(u, d); if (r < 0) return r; - unit_write_drop_in_format(u, mode, name, "[Unit]\nDescription=%s", d); + unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Description=%s", d); } return 1; @@ -1352,9 +1352,9 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { u->default_dependencies = b; - unit_write_drop_in_format(u, mode, name, "[Unit]\nDefaultDependencies=%s", yes_no(b)); + unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b)); } return 1; @@ -1371,9 +1371,9 @@ static int bus_unit_set_transient_property( if (m < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { u->collect_mode = m; - unit_write_drop_in_format(u, mode, name, "[Unit]\nCollectMode=%s", collect_mode_to_string(m)); + unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m)); } return 1; @@ -1406,12 +1406,12 @@ static int bus_unit_set_transient_property( if (slice->type != UNIT_SLICE) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_set_slice(u, slice); if (r < 0) return r; - unit_write_drop_in_private_format(u, mode, name, "Slice=%s", s); + unit_write_settingf(u, flags|UNIT_PRIVATE, name, "Slice=%s", s); } return 1; @@ -1448,7 +1448,7 @@ static int bus_unit_set_transient_property( if (!unit_name_is_valid(other, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *label = NULL; r = unit_add_dependency_by_name(u, d, other, NULL, true, UNIT_DEPENDENCY_FILE); @@ -1459,7 +1459,7 @@ static int bus_unit_set_transient_property( if (!label) return -ENOMEM; - unit_write_drop_in_format(u, mode, label, "[Unit]\n%s=%s", name, other); + unit_write_settingf(u, flags, label, "%s=%s", name, other); } } @@ -1484,14 +1484,14 @@ static int bus_unit_set_transient_property( if (action < 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "FailureAction")) u->failure_action = action; else u->success_action = action; - unit_write_drop_in_format(u, mode, name, "%s=%s", name, emergency_action_to_string(action)); + unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action)); } return 1; @@ -1514,7 +1514,7 @@ static int bus_unit_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) + if (!UNIT_WRITE_FLAGS_NOOP(flags)) u->bus_track_add = b; return 1; @@ -1526,7 +1526,7 @@ static int bus_unit_set_transient_property( int bus_unit_set_properties( Unit *u, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, bool commit, sd_bus_error *error) { @@ -1548,12 +1548,13 @@ int bus_unit_set_properties( for (;;) { const char *name; + UnitWriteFlags f; r = sd_bus_message_enter_container(message, 'r', "sv"); if (r < 0) return r; if (r == 0) { - if (for_real || mode == UNIT_CHECK) + if (for_real || UNIT_WRITE_FLAGS_NOOP(flags)) break; /* Reached EOF. Let's try again, and this time for realz... */ @@ -1576,9 +1577,12 @@ int bus_unit_set_properties( if (r < 0) return r; - r = UNIT_VTABLE(u)->bus_set_property(u, name, message, for_real ? mode : UNIT_CHECK, error); + /* If not for real, then mask out the two target flags */ + f = for_real ? flags : (flags & ~(UNIT_RUNTIME|UNIT_PERSISTENT)); + + r = UNIT_VTABLE(u)->bus_set_property(u, name, message, f, error); if (r == 0 && u->transient && u->load_state == UNIT_STUB) - r = bus_unit_set_transient_property(u, name, message, for_real ? mode : UNIT_CHECK, error); + r = bus_unit_set_transient_property(u, name, message, f, error); if (r < 0) return r; if (r == 0) diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index b723453f37..d7066eefc8 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -34,7 +34,7 @@ int bus_unit_method_start_generic(sd_bus_message *message, Unit *u, JobType job_ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error); -int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitSetPropertiesMode mode, bool commit, sd_bus_error *error); +int bus_unit_set_properties(Unit *u, sd_bus_message *message, UnitWriteFlags flags, bool commit, sd_bus_error *error); int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error); int bus_unit_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error); diff --git a/src/core/unit.c b/src/core/unit.c index 856939853a..90a09ce659 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -55,6 +55,7 @@ #include "signal-util.h" #include "sparse-endian.h" #include "special.h" +#include "specifier.h" #include "stat-util.h" #include "stdio-util.h" #include "string-table.h" @@ -117,6 +118,8 @@ Unit *unit_new(Manager *m, size_t size) { u->ipv4_deny_map_fd = -1; u->ipv6_deny_map_fd = -1; + u->last_section_private = -1; + RATELIMIT_INIT(u->start_limit, m->default_start_limit_interval, m->default_start_limit_burst); RATELIMIT_INIT(u->auto_stop_ratelimit, 10 * USEC_PER_SEC, 16); @@ -4120,43 +4123,156 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { return *(ExecRuntime**) ((uint8_t*) u + offset); } -static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) { +static const char* unit_drop_in_dir(Unit *u, UnitWriteFlags flags) { assert(u); - if (!IN_SET(mode, UNIT_RUNTIME, UNIT_PERSISTENT)) + if (UNIT_WRITE_FLAGS_NOOP(flags)) return NULL; if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */ return u->manager->lookup_paths.transient; - if (mode == UNIT_RUNTIME) - return u->manager->lookup_paths.runtime_control; - - if (mode == UNIT_PERSISTENT) + if (flags & UNIT_PERSISTENT) return u->manager->lookup_paths.persistent_control; + if (flags & UNIT_RUNTIME) + return u->manager->lookup_paths.runtime_control; + return NULL; } -int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { - _cleanup_free_ char *p = NULL, *q = NULL; +char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf) { + char *ret = NULL; + + if (!s) + return NULL; + + /* Escapes the input string as requested. Returns the escaped string. If 'buf' is specified then the allocated + * return buffer pointer is also written to *buf, except if no escaping was necessary, in which case *buf is + * set to NULL, and the input pointer is returned as-is. This means the return value always contains a properly + * escaped version, but *buf when passed only contains a pointer if an allocation was necessary. If *buf is + * not specified, then the return value always needs to be freed. Callers can use this to optimize memory + * allocations. */ + + if (flags & UNIT_ESCAPE_SPECIFIERS) { + ret = specifier_escape(s); + if (!ret) + return NULL; + + s = ret; + } + + if (flags & UNIT_ESCAPE_C) { + char *a; + + a = cescape(s); + free(ret); + if (!a) + return NULL; + + ret = a; + } + + if (buf) { + *buf = ret; + return ret ?: (char*) s; + } + + return ret ?: strdup(s); +} + +char* unit_concat_strv(char **l, UnitWriteFlags flags) { + _cleanup_free_ char *result = NULL; + size_t n = 0, allocated = 0; + char **i, *ret; + + /* Takes a list of strings, escapes them, and concatenates them. This may be used to format command lines in a + * way suitable for ExecStart= stanzas */ + + STRV_FOREACH(i, l) { + _cleanup_free_ char *buf = NULL; + const char *p; + size_t a; + char *q; + + p = unit_escape_setting(*i, flags, &buf); + if (!p) + return NULL; + + a = (n > 0) + 1 + strlen(p) + 1; /* separating space + " + entry + " */ + if (!GREEDY_REALLOC(result, allocated, n + a + 1)) + return NULL; + + q = result + n; + if (n > 0) + *(q++) = ' '; + + *(q++) = '"'; + q = stpcpy(q, p); + *(q++) = '"'; + + n += a; + } + + if (!GREEDY_REALLOC(result, allocated, n + 1)) + return NULL; + + result[n] = 0; + + ret = result; + result = NULL; + + return ret; +} + +int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const char *data) { + _cleanup_free_ char *p = NULL, *q = NULL, *escaped = NULL; const char *dir, *wrapped; int r; assert(u); + assert(name); + assert(data); + + if (UNIT_WRITE_FLAGS_NOOP(flags)) + return 0; + + data = unit_escape_setting(data, flags, &escaped); + if (!data) + return -ENOMEM; + + /* Prefix the section header. If we are writing this out as transient file, then let's suppress this if the + * previous section header is the same */ + + if (flags & UNIT_PRIVATE) { + if (!UNIT_VTABLE(u)->private_section) + return -EINVAL; + + if (!u->transient_file || u->last_section_private < 0) + data = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data); + else if (u->last_section_private == 0) + data = strjoina("\n[", UNIT_VTABLE(u)->private_section, "]\n", data); + } else { + if (!u->transient_file || u->last_section_private < 0) + data = strjoina("[Unit]\n", data); + else if (u->last_section_private > 0) + data = strjoina("\n[Unit]\n", data); + } if (u->transient_file) { /* When this is a transient unit file in creation, then let's not create a new drop-in but instead * write to the transient unit file. */ fputs(data, u->transient_file); - fputc('\n', u->transient_file); - return 0; - } - if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + if (!endswith(data, "\n")) + fputc('\n', u->transient_file); + + /* Remember which section we wrote this entry to */ + u->last_section_private = !!(flags & UNIT_PRIVATE); return 0; + } - dir = unit_drop_in_dir(u, mode); + dir = unit_drop_in_dir(u, flags); if (!dir) return -EINVAL; @@ -4186,47 +4302,7 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co return 0; } -int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { - _cleanup_free_ char *p = NULL; - va_list ap; - int r; - - assert(u); - assert(name); - assert(format); - - if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) - return 0; - - va_start(ap, format); - r = vasprintf(&p, format, ap); - va_end(ap); - - if (r < 0) - return -ENOMEM; - - return unit_write_drop_in(u, mode, name, p); -} - -int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { - const char *ndata; - - assert(u); - assert(name); - assert(data); - - if (!UNIT_VTABLE(u)->private_section) - return -EINVAL; - - if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) - return 0; - - ndata = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data); - - return unit_write_drop_in(u, mode, name, ndata); -} - -int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) { +int unit_write_settingf(Unit *u, UnitWriteFlags flags, const char *name, const char *format, ...) { _cleanup_free_ char *p = NULL; va_list ap; int r; @@ -4235,7 +4311,7 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const assert(name); assert(format); - if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) + if (UNIT_WRITE_FLAGS_NOOP(flags)) return 0; va_start(ap, format); @@ -4245,7 +4321,7 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const if (r < 0) return -ENOMEM; - return unit_write_drop_in_private(u, mode, name, p); + return unit_write_setting(u, flags, name, p); } int unit_make_transient(Unit *u) { diff --git a/src/core/unit.h b/src/core/unit.h index cd7c08a20d..92bb4779a9 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -360,6 +360,10 @@ struct Unit { bool exported_invocation_id:1; bool exported_log_level_max:1; bool exported_log_extra_fields:1; + + /* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If + * == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */ + int last_section_private:2; }; struct UnitStatusMessageFormats { @@ -368,11 +372,26 @@ struct UnitStatusMessageFormats { const char *finished_stop_job[_JOB_RESULT_MAX]; }; -typedef enum UnitSetPropertiesMode { - UNIT_CHECK = 0, - UNIT_RUNTIME = 1, - UNIT_PERSISTENT = 2, -} UnitSetPropertiesMode; +/* Flags used when writing drop-in files or transient unit files */ +typedef enum UnitWriteFlags { + /* Write a runtime unit file or drop-in (i.e. one below /run) */ + UNIT_RUNTIME = 1 << 0, + + /* Write a persistent drop-in (i.e. one below /etc) */ + UNIT_PERSISTENT = 1 << 1, + + /* Place this item in the per-unit-type private section, instead of [Unit] */ + UNIT_PRIVATE = 1 << 2, + + /* Apply specifier escaping before writing */ + UNIT_ESCAPE_SPECIFIERS = 1 << 3, + + /* Apply C escaping before writing */ + UNIT_ESCAPE_C = 1 << 4, +} UnitWriteFlags; + +/* Returns true if neither persistent, nor runtime storage is requested, i.e. this is a check invocation only */ +#define UNIT_WRITE_FLAGS_NOOP(flags) (((flags) & (UNIT_RUNTIME|UNIT_PERSISTENT)) == 0) #include "automount.h" #include "device.h" @@ -490,7 +509,7 @@ struct UnitVTable { void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner); /* Called for each property that is being set */ - int (*bus_set_property)(Unit *u, const char *name, sd_bus_message *message, UnitSetPropertiesMode mode, sd_bus_error *error); + int (*bus_set_property)(Unit *u, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); /* Called after at least one property got changed to apply the necessary change */ int (*bus_commit_properties)(Unit *u); @@ -713,11 +732,11 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) _pure_; int unit_setup_exec_runtime(Unit *u); int unit_setup_dynamic_creds(Unit *u); -int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); -int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5); +char* unit_escape_setting(const char *s, UnitWriteFlags flags, char **buf); +char* unit_concat_strv(char **l, UnitWriteFlags flags); -int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data); -int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *format, ...) _printf_(4,5); +int unit_write_setting(Unit *u, UnitWriteFlags flags, const char *name, const char *data); +int unit_write_settingf(Unit *u, UnitWriteFlags mode, const char *name, const char *format, ...) _printf_(4,5); int unit_kill_context(Unit *u, KillContext *c, KillOperation k, pid_t main_pid, pid_t control_pid, bool main_pid_alien); |