Merge pull request #7759 from yuwata/dbus-api
DBus-API: add more options in transient units
This commit is contained in:
commit
fb92330ccc
|
@ -10,12 +10,12 @@ ones currently available in transient units are prefixed with `✓`.
|
|||
|
||||
## Generic Unit Settings
|
||||
|
||||
Only the most important generic unit settings are available for transient units.
|
||||
Most generic unit settings are available for transient units.
|
||||
|
||||
```
|
||||
✓ Description=
|
||||
Documentation=
|
||||
SourcePath=
|
||||
✓ Documentation=
|
||||
✓ SourcePath=
|
||||
✓ Requires=
|
||||
✓ Requisite=
|
||||
✓ Wants=
|
||||
|
@ -27,69 +27,70 @@ Only the most important generic unit settings are available for transient units.
|
|||
✓ PropagatesReloadTo=
|
||||
✓ ReloadPropagatedFrom=
|
||||
✓ PartOf=
|
||||
JoinsNamespaceOf=
|
||||
RequiresMountsFor=
|
||||
StopWhenUnneeded=
|
||||
RefuseManualStart=
|
||||
RefuseManualStop=
|
||||
AllowIsolate=
|
||||
✓ JoinsNamespaceOf=
|
||||
✓ RequiresMountsFor=
|
||||
✓ StopWhenUnneeded=
|
||||
✓ RefuseManualStart=
|
||||
✓ RefuseManualStop=
|
||||
✓ AllowIsolate=
|
||||
✓ DefaultDependencies=
|
||||
OnFailureJobMode=
|
||||
OnFailureIsolate=
|
||||
IgnoreOnIsolate=
|
||||
JobTimeoutSec=
|
||||
JobRunningTimeoutSec=
|
||||
JobTimeoutAction=
|
||||
JobTimeoutRebootArgument=
|
||||
StartLimitIntervalSec=SECONDS
|
||||
StartLimitBurst=UNSIGNED
|
||||
StartLimitAction=ACTION
|
||||
✓ OnFailureJobMode=
|
||||
✓ IgnoreOnIsolate=
|
||||
✓ JobTimeoutSec=
|
||||
✓ JobRunningTimeoutSec=
|
||||
✓ JobTimeoutAction=
|
||||
✓ JobTimeoutRebootArgument=
|
||||
✓ StartLimitIntervalSec=SECONDS
|
||||
✓ StartLimitBurst=UNSIGNED
|
||||
✓ StartLimitAction=ACTION
|
||||
✓ FailureAction=
|
||||
✓ SuccessAction=
|
||||
✓ AddRef=
|
||||
RebootArgument=STRING
|
||||
ConditionPathExists=
|
||||
ConditionPathExistsGlob=
|
||||
ConditionPathIsDirectory=
|
||||
ConditionPathIsSymbolicLink=
|
||||
ConditionPathIsMountPoint=
|
||||
ConditionPathIsReadWrite=
|
||||
ConditionDirectoryNotEmpty=
|
||||
ConditionFileNotEmpty=
|
||||
ConditionFileIsExecutable=
|
||||
ConditionNeedsUpdate=
|
||||
ConditionFirstBoot=
|
||||
ConditionKernelCommandLine=
|
||||
ConditionArchitecture=
|
||||
ConditionVirtualization=
|
||||
ConditionSecurity=
|
||||
ConditionCapability=
|
||||
ConditionHost=
|
||||
ConditionACPower=
|
||||
ConditionUser=
|
||||
ConditionGroup=
|
||||
ConditionControlGroupController=
|
||||
AssertPathExists=
|
||||
AssertPathExistsGlob=
|
||||
AssertPathIsDirectory=
|
||||
AssertPathIsSymbolicLink=
|
||||
AssertPathIsMountPoint=
|
||||
AssertPathIsReadWrite=
|
||||
AssertDirectoryNotEmpty=
|
||||
AssertFileNotEmpty=
|
||||
AssertFileIsExecutable=
|
||||
AssertNeedsUpdate=
|
||||
AssertFirstBoot=
|
||||
AssertKernelCommandLine=
|
||||
AssertArchitecture=
|
||||
AssertVirtualization=
|
||||
AssertSecurity=
|
||||
AssertCapability=
|
||||
AssertHost=
|
||||
AssertACPower=
|
||||
AssertUser=
|
||||
AssertGroup=
|
||||
AssertControlGroupController=
|
||||
✓ RebootArgument=STRING
|
||||
✓ ConditionPathExists=
|
||||
✓ ConditionPathExistsGlob=
|
||||
✓ ConditionPathIsDirectory=
|
||||
✓ ConditionPathIsSymbolicLink=
|
||||
✓ ConditionPathIsMountPoint=
|
||||
✓ ConditionPathIsReadWrite=
|
||||
✓ ConditionDirectoryNotEmpty=
|
||||
✓ ConditionFileNotEmpty=
|
||||
✓ ConditionFileIsExecutable=
|
||||
✓ ConditionNeedsUpdate=
|
||||
✓ ConditionFirstBoot=
|
||||
✓ ConditionKernelCommandLine=
|
||||
✓ ConditionKernelVersion=
|
||||
✓ ConditionArchitecture=
|
||||
✓ ConditionVirtualization=
|
||||
✓ ConditionSecurity=
|
||||
✓ ConditionCapability=
|
||||
✓ ConditionHost=
|
||||
✓ ConditionACPower=
|
||||
✓ ConditionUser=
|
||||
✓ ConditionGroup=
|
||||
✓ ConditionControlGroupController=
|
||||
✓ AssertPathExists=
|
||||
✓ AssertPathExistsGlob=
|
||||
✓ AssertPathIsDirectory=
|
||||
✓ AssertPathIsSymbolicLink=
|
||||
✓ AssertPathIsMountPoint=
|
||||
✓ AssertPathIsReadWrite=
|
||||
✓ AssertDirectoryNotEmpty=
|
||||
✓ AssertFileNotEmpty=
|
||||
✓ AssertFileIsExecutable=
|
||||
✓ AssertNeedsUpdate=
|
||||
✓ AssertFirstBoot=
|
||||
✓ AssertKernelCommandLine=
|
||||
✓ AssertKernelVersion=
|
||||
✓ AssertArchitecture=
|
||||
✓ AssertVirtualization=
|
||||
✓ AssertSecurity=
|
||||
✓ AssertCapability=
|
||||
✓ AssertHost=
|
||||
✓ AssertACPower=
|
||||
✓ AssertUser=
|
||||
✓ AssertGroup=
|
||||
✓ AssertControlGroupController=
|
||||
✓ CollectMode=
|
||||
```
|
||||
|
||||
|
@ -256,63 +257,63 @@ All process killing settings are available for transient units:
|
|||
|
||||
## Service Unit Settings
|
||||
|
||||
Only the most important service settings are available for transient units.
|
||||
Most service unit settings are available for transient units.
|
||||
|
||||
```
|
||||
PIDFile=
|
||||
✓ PIDFile=
|
||||
✓ ExecStartPre=
|
||||
✓ ExecStart=
|
||||
✓ ExecStartPost=
|
||||
✓ ExecReload=
|
||||
✓ ExecStop=
|
||||
✓ ExecStopPost=
|
||||
RestartSec=
|
||||
TimeoutStartSec=
|
||||
TimeoutStopSec=
|
||||
TimeoutSec=
|
||||
✓ RestartSec=
|
||||
✓ TimeoutStartSec=
|
||||
✓ TimeoutStopSec=
|
||||
✓ TimeoutSec=
|
||||
✓ RuntimeMaxSec=
|
||||
WatchdogSec=
|
||||
✓ WatchdogSec=
|
||||
✓ Type=
|
||||
✓ Restart=
|
||||
PermissionsStartOnly=
|
||||
RootDirectoryStartOnly=
|
||||
✓ PermissionsStartOnly=
|
||||
✓ RootDirectoryStartOnly=
|
||||
✓ RemainAfterExit=
|
||||
GuessMainPID=
|
||||
RestartPreventExitStatus=
|
||||
RestartForceExitStatus=
|
||||
SuccessExitStatus=
|
||||
✓ GuessMainPID=
|
||||
✓ RestartPreventExitStatus=
|
||||
✓ RestartForceExitStatus=
|
||||
✓ SuccessExitStatus=
|
||||
✓ NonBlocking=
|
||||
BusName=
|
||||
✓ BusName=
|
||||
✓ FileDescriptorStoreMax=
|
||||
✓ NotifyAccess=
|
||||
Sockets=
|
||||
USBFunctionDescriptors=
|
||||
USBFunctionStrings=
|
||||
✓ USBFunctionDescriptors=
|
||||
✓ USBFunctionStrings=
|
||||
```
|
||||
|
||||
## Mount Unit Settings
|
||||
|
||||
Only the most important mount unit settings are currently available to transient units:
|
||||
All mount unit settings are available to transient units:
|
||||
|
||||
```
|
||||
✓ What=
|
||||
Where=
|
||||
✓ Where=
|
||||
✓ Options=
|
||||
✓ Type=
|
||||
TimeoutSec=
|
||||
DirectoryMode=
|
||||
SloppyOptions=
|
||||
LazyUnmount=
|
||||
ForceUnmount=
|
||||
✓ TimeoutSec=
|
||||
✓ DirectoryMode=
|
||||
✓ SloppyOptions=
|
||||
✓ LazyUnmount=
|
||||
✓ ForceUnmount=
|
||||
```
|
||||
|
||||
## Automount Unit Settings
|
||||
|
||||
Only one automount unit setting is currently available to transient units:
|
||||
All automount unit setting is available to transient units:
|
||||
|
||||
```
|
||||
Where=
|
||||
DirectoryMode=
|
||||
✓ Where=
|
||||
✓ DirectoryMode=
|
||||
✓ TimeoutIdleSec=
|
||||
```
|
||||
|
||||
|
@ -343,8 +344,11 @@ of their own beyond the generic unit and resource control settings.
|
|||
## Scope Unit Settings
|
||||
|
||||
Scope units are fully supported as transient units (in fact they only exist as
|
||||
such), but they have no settings of their own beyond the generic unit,
|
||||
resource control, and process killing settings.
|
||||
such).
|
||||
|
||||
```
|
||||
✓ TimeoutStopSec=
|
||||
```
|
||||
|
||||
## Socket Unit Settings
|
||||
|
||||
|
|
|
@ -100,8 +100,6 @@
|
|||
late system shutdown should disable
|
||||
<varname>DefaultDependencies=</varname> option.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para></para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
/*
|
||||
* MAX_ERRNO is defined as 4095 in linux/err.h
|
||||
* We use the same value here.
|
||||
|
@ -28,3 +29,6 @@
|
|||
|
||||
const char *errno_to_name(int id);
|
||||
int errno_from_name(const char *name);
|
||||
static inline bool errno_is_valid(int n) {
|
||||
return n > 0 && n <= ERRNO_MAX;
|
||||
}
|
||||
|
|
|
@ -283,7 +283,8 @@ int parse_errno(const char *t) {
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (e < 0 || e > ERRNO_MAX)
|
||||
/* 0 is also allowed here */
|
||||
if (!errno_is_valid(e) && e != 0)
|
||||
return -ERANGE;
|
||||
|
||||
return e;
|
||||
|
|
|
@ -137,6 +137,13 @@ static inline bool pid_is_valid(pid_t p) {
|
|||
return p > 0;
|
||||
}
|
||||
|
||||
static inline int sched_policy_to_string_alloc_with_check(int n, char **s) {
|
||||
if (!sched_policy_is_valid(n))
|
||||
return -EINVAL;
|
||||
|
||||
return sched_policy_to_string_alloc(n, s);
|
||||
}
|
||||
|
||||
int ioprio_parse_priority(const char *s, int *ret);
|
||||
|
||||
pid_t getpid_cached(void);
|
||||
|
|
|
@ -24,6 +24,14 @@
|
|||
|
||||
int secure_bits_to_string_alloc(int i, char **s);
|
||||
int secure_bits_from_string(const char *s);
|
||||
|
||||
static inline bool secure_bits_is_valid(int i) {
|
||||
return ((SECURE_ALL_BITS | SECURE_ALL_LOCKS) & i) == i;
|
||||
}
|
||||
|
||||
static inline int secure_bits_to_string_alloc_with_check(int n, char **s) {
|
||||
if (!secure_bits_is_valid(n))
|
||||
return -EINVAL;
|
||||
|
||||
return secure_bits_to_string_alloc(n, s);
|
||||
}
|
||||
|
|
|
@ -55,3 +55,10 @@ static inline void block_signals_reset(sigset_t *ss) {
|
|||
static inline bool SIGNAL_VALID(int signo) {
|
||||
return signo > 0 && signo < _NSIG;
|
||||
}
|
||||
|
||||
static inline const char* signal_to_string_with_check(int n) {
|
||||
if (!SIGNAL_VALID(n))
|
||||
return NULL;
|
||||
|
||||
return signal_to_string(n);
|
||||
}
|
||||
|
|
|
@ -821,6 +821,18 @@ static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIN
|
|||
|
||||
DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
|
||||
|
||||
SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *n) {
|
||||
int r;
|
||||
|
||||
r = parse_boolean(n);
|
||||
if (r > 0)
|
||||
return SOCKET_ADDRESS_IPV6_ONLY;
|
||||
if (r == 0)
|
||||
return SOCKET_ADDRESS_BOTH;
|
||||
|
||||
return socket_address_bind_ipv6_only_from_string(n);
|
||||
}
|
||||
|
||||
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
|
||||
assert(a);
|
||||
assert(b);
|
||||
|
|
|
@ -120,6 +120,7 @@ int getnameinfo_pretty(int fd, char **ret);
|
|||
|
||||
const char* socket_address_bind_ipv6_only_to_string(SocketAddressBindIPv6Only b) _const_;
|
||||
SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *s) _pure_;
|
||||
SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *s);
|
||||
|
||||
int netlink_family_to_string_alloc(int b, char **s);
|
||||
int netlink_family_from_string(const char *s) _pure_;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "automount.h"
|
||||
#include "bus-util.h"
|
||||
#include "dbus-automount.h"
|
||||
#include "dbus-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, automount_result, AutomountResult);
|
||||
|
@ -41,7 +42,7 @@ static int bus_automount_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int r;
|
||||
Unit *u = UNIT(a);
|
||||
|
||||
assert(a);
|
||||
assert(name);
|
||||
|
@ -49,24 +50,16 @@ static int bus_automount_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "TimeoutIdleUSec")) {
|
||||
usec_t timeout_idle_usec;
|
||||
if (streq(name, "Where"))
|
||||
return bus_set_transient_path(u, name, &a->where, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &timeout_idle_usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "TimeoutIdleUSec"))
|
||||
return bus_set_transient_usec_fix_0(u, name, &a->timeout_idle_usec, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
char time[FORMAT_TIMESPAN_MAX];
|
||||
if (streq(name, "DirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &a->directory_mode, message, flags, error);
|
||||
|
||||
a->timeout_idle_usec = timeout_idle_usec;
|
||||
unit_write_settingf(UNIT(a), flags, name, "TimeoutIdleSec=%s\n",
|
||||
format_timespan(time, sizeof(time), timeout_idle_usec, USEC_PER_MSEC));
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_automount_set_property(
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "cgroup-util.h"
|
||||
#include "cgroup.h"
|
||||
#include "dbus-cgroup.h"
|
||||
#include "dbus-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "path-util.h"
|
||||
|
@ -413,6 +414,41 @@ static int bus_cgroup_set_transient_property(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bus_cgroup_set_boolean(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
bool *p,
|
||||
CGroupMask mask,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int b, r;
|
||||
|
||||
assert(p);
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
*p = b;
|
||||
unit_invalidate_cgroup(u, mask);
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight, CGROUP_MASK_CPU, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,);
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares, CGROUP_MASK_CPU, CGROUP_CPU_SHARES_IS_OK, CGROUP_CPU_SHARES_INVALID,);
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight, CGROUP_MASK_IO, CGROUP_WEIGHT_IS_OK, CGROUP_WEIGHT_INVALID,);
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight, CGROUP_MASK_BLKIO, CGROUP_BLKIO_WEIGHT_IS_OK, CGROUP_BLKIO_WEIGHT_INVALID,);
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(memory, CGROUP_MASK_MEMORY, , CGROUP_LIMIT_MAX, "infinity");
|
||||
static BUS_DEFINE_SET_CGROUP_WEIGHT(tasks_max, CGROUP_MASK_PIDS, , (uint64_t) -1, "infinity");
|
||||
static BUS_DEFINE_SET_CGROUP_SCALE(memory, CGROUP_MASK_MEMORY, physical_memory_scale);
|
||||
static BUS_DEFINE_SET_CGROUP_SCALE(tasks_max, CGROUP_MASK_PIDS, system_tasks_max_scale);
|
||||
|
||||
int bus_cgroup_set_property(
|
||||
Unit *u,
|
||||
CGroupContext *c,
|
||||
|
@ -431,74 +467,82 @@ int bus_cgroup_set_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "CPUAccounting")) {
|
||||
int b;
|
||||
if (streq(name, "CPUAccounting"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->cpu_accounting, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "CPUWeight"))
|
||||
return bus_cgroup_set_cpu_weight(u, name, &c->cpu_weight, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->cpu_accounting = b;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU);
|
||||
unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b));
|
||||
}
|
||||
if (streq(name, "StartupCPUWeight"))
|
||||
return bus_cgroup_set_cpu_weight(u, name, &c->startup_cpu_weight, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "CPUShares"))
|
||||
return bus_cgroup_set_cpu_shares(u, name, &c->cpu_shares, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "CPUWeight", "StartupCPUWeight")) {
|
||||
uint64_t weight;
|
||||
if (streq(name, "StartupCPUShares"))
|
||||
return bus_cgroup_set_cpu_shares(u, name, &c->startup_cpu_shares, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &weight);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "IOAccounting"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->io_accounting, CGROUP_MASK_IO, message, flags, error);
|
||||
|
||||
if (!CGROUP_WEIGHT_IS_OK(weight))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name);
|
||||
if (streq(name, "IOWeight"))
|
||||
return bus_cgroup_set_io_weight(u, name, &c->io_weight, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "CPUWeight"))
|
||||
c->cpu_weight = weight;
|
||||
else /* "StartupCPUWeight" */
|
||||
c->startup_cpu_weight = weight;
|
||||
if (streq(name, "StartupIOWeight"))
|
||||
return bus_cgroup_set_io_weight(u, name, &c->startup_io_weight, message, flags, error);
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
|
||||
if (streq(name, "BlockIOAccounting"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->blockio_accounting, CGROUP_MASK_BLKIO, message, flags, error);
|
||||
|
||||
if (weight == CGROUP_WEIGHT_INVALID)
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight);
|
||||
}
|
||||
if (streq(name, "BlockIOWeight"))
|
||||
return bus_cgroup_set_blockio_weight(u, name, &c->blockio_weight, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "StartupBlockIOWeight"))
|
||||
return bus_cgroup_set_blockio_weight(u, name, &c->startup_blockio_weight, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "CPUShares", "StartupCPUShares")) {
|
||||
uint64_t shares;
|
||||
if (streq(name, "MemoryAccounting"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->memory_accounting, CGROUP_MASK_MEMORY, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &shares);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "MemoryLow"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error);
|
||||
|
||||
if (!CGROUP_CPU_SHARES_IS_OK(shares))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name);
|
||||
if (streq(name, "MemoryHigh"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "CPUShares"))
|
||||
c->cpu_shares = shares;
|
||||
else /* "StartupCPUShares" */
|
||||
c->startup_cpu_shares = shares;
|
||||
if (streq(name, "MemorySwapMax"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_swap_max, message, flags, error);
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_CPU);
|
||||
if (streq(name, "MemoryMax"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_max, message, flags, error);
|
||||
|
||||
if (shares == CGROUP_CPU_SHARES_INVALID)
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, shares);
|
||||
}
|
||||
if (streq(name, "MemoryLimit"))
|
||||
return bus_cgroup_set_memory(u, name, &c->memory_limit, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "MemoryLowScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error);
|
||||
|
||||
} else if (streq(name, "CPUQuotaPerSecUSec")) {
|
||||
if (streq(name, "MemoryHighScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
|
||||
|
||||
if (streq(name, "MemorySwapMaxScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_swap_max, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryMaxScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_max, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryLimitScale"))
|
||||
return bus_cgroup_set_memory_scale(u, name, &c->memory_limit, message, flags, error);
|
||||
|
||||
if (streq(name, "TasksAccountingScale"))
|
||||
return bus_cgroup_set_boolean(u, name, &c->tasks_accounting, CGROUP_MASK_PIDS, message, flags, error);
|
||||
|
||||
if (streq(name, "TasksMax"))
|
||||
return bus_cgroup_set_tasks_max(u, name, &c->tasks_max, message, flags, error);
|
||||
|
||||
if (streq(name, "TasksMaxScale"))
|
||||
return bus_cgroup_set_tasks_max_scale(u, name, &c->tasks_max, message, flags, error);
|
||||
|
||||
if (streq(name, "CPUQuotaPerSecUSec")) {
|
||||
uint64_t u64;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u64);
|
||||
|
@ -524,47 +568,6 @@ int bus_cgroup_set_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IOAccounting")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->io_accounting = b;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_IO);
|
||||
unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "IOWeight", "StartupIOWeight")) {
|
||||
uint64_t weight;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &weight);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!CGROUP_WEIGHT_IS_OK(weight))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "IOWeight"))
|
||||
c->io_weight = weight;
|
||||
else /* "StartupIOWeight" */
|
||||
c->startup_io_weight = weight;
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_IO);
|
||||
|
||||
if (weight == CGROUP_WEIGHT_INVALID)
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if ((iol_type = cgroup_io_limit_type_from_string(name)) >= 0) {
|
||||
const char *path;
|
||||
unsigned n = 0;
|
||||
|
@ -691,7 +694,7 @@ int bus_cgroup_set_property(
|
|||
free(a);
|
||||
return -ENOMEM;
|
||||
}
|
||||
LIST_PREPEND(device_weights,c->io_device_weights, a);
|
||||
LIST_PREPEND(device_weights, c->io_device_weights, a);
|
||||
}
|
||||
|
||||
a->weight = weight;
|
||||
|
@ -735,47 +738,6 @@ int bus_cgroup_set_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "BlockIOAccounting")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->blockio_accounting = b;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
|
||||
unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight")) {
|
||||
uint64_t weight;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &weight);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= value out of range", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "BlockIOWeight"))
|
||||
c->blockio_weight = weight;
|
||||
else /* "StartupBlockIOWeight" */
|
||||
c->startup_blockio_weight = weight;
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO);
|
||||
|
||||
if (weight == CGROUP_BLKIO_WEIGHT_INVALID)
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, weight);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
|
||||
const char *path;
|
||||
bool read = true;
|
||||
|
@ -918,7 +880,7 @@ int bus_cgroup_set_property(
|
|||
free(a);
|
||||
return -ENOMEM;
|
||||
}
|
||||
LIST_PREPEND(device_weights,c->blockio_device_weights, a);
|
||||
LIST_PREPEND(device_weights, c->blockio_device_weights, a);
|
||||
}
|
||||
|
||||
a->weight = weight;
|
||||
|
@ -963,89 +925,6 @@ int bus_cgroup_set_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "MemoryAccounting")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->memory_accounting = b;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
|
||||
unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit")) {
|
||||
uint64_t v;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (v <= 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "MemoryLow"))
|
||||
c->memory_low = v;
|
||||
else if (streq(name, "MemoryHigh"))
|
||||
c->memory_high = v;
|
||||
else if (streq(name, "MemorySwapMax"))
|
||||
c->memory_swap_max = v;
|
||||
else if (streq(name, "MemoryMax"))
|
||||
c->memory_max = v;
|
||||
else /* "MemoryLimit" */
|
||||
c->memory_limit = v;
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
|
||||
|
||||
if (v == CGROUP_LIMIT_MAX)
|
||||
unit_write_settingf(u, flags, name, "%s=infinity", name);
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale", "MemorySwapMaxScale", "MemoryLimitScale")) {
|
||||
uint32_t raw;
|
||||
uint64_t v;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &raw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
v = physical_memory_scale(raw, UINT32_MAX);
|
||||
if (v <= 0 || v == UINT64_MAX)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
const char *e;
|
||||
|
||||
/* Chop off suffix */
|
||||
assert_se(e = endswith(name, "Scale"));
|
||||
name = strndupa(name, e - name);
|
||||
|
||||
if (streq(name, "MemoryLow"))
|
||||
c->memory_low = v;
|
||||
else if (streq(name, "MemoryHigh"))
|
||||
c->memory_high = v;
|
||||
else if (streq(name, "MemorySwapMax"))
|
||||
c->memory_swap_max = v;
|
||||
else if (streq(name, "MemoryMax"))
|
||||
c->memory_max = v;
|
||||
else /* "MemoryLimit" */
|
||||
c->memory_limit = v;
|
||||
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY);
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name,
|
||||
(uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "DevicePolicy")) {
|
||||
const char *policy;
|
||||
CGroupDevicePolicy p;
|
||||
|
@ -1156,63 +1035,6 @@ int bus_cgroup_set_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TasksAccounting")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->tasks_accounting = b;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
|
||||
unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TasksMax")) {
|
||||
uint64_t limit;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &limit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (limit <= 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->tasks_max = limit;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
|
||||
|
||||
if (limit == (uint64_t) -1)
|
||||
unit_write_setting(u, flags, name, "TasksMax=infinity");
|
||||
else
|
||||
unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TasksMaxScale")) {
|
||||
uint64_t limit;
|
||||
uint32_t raw;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &raw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
limit = system_tasks_max_scale(raw, UINT32_MAX);
|
||||
if (limit <= 0 || limit >= UINT64_MAX)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->tasks_max = limit;
|
||||
unit_invalidate_cgroup(u, CGROUP_MASK_PIDS);
|
||||
unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%",
|
||||
(uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX)));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IPAccounting")) {
|
||||
int b;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "capability-util.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "dbus-execute.h"
|
||||
#include "dbus-util.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-list.h"
|
||||
#include "escape.h"
|
||||
|
@ -1036,7 +1037,7 @@ int bus_property_get_exec_command_list(
|
|||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
int bus_exec_command_set_transient_property(
|
||||
int bus_set_transient_exec_command(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
ExecCommand **exec_command,
|
||||
|
@ -1151,6 +1152,45 @@ int bus_exec_command_set_transient_property(
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int parse_personality(const char *s, unsigned long *p) {
|
||||
unsigned long v;
|
||||
|
||||
assert(p);
|
||||
|
||||
v = personality_from_string(s);
|
||||
if (v == PERSONALITY_INVALID)
|
||||
return -EINVAL;
|
||||
|
||||
*p = v;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char* mount_propagation_flags_to_string_with_check(unsigned long n) {
|
||||
if (!IN_SET(n, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
|
||||
return NULL;
|
||||
|
||||
return mount_propagation_flags_to_string(n);
|
||||
}
|
||||
|
||||
static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
|
||||
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, errno_is_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(sched_priority, "i", int32_t, int, "%" PRIi32, sched_priority_is_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(nice, "i", int32_t, int, "%" PRIi32, nice_is_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, parse_protect_system_or_bool);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, parse_protect_home_or_bool);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(sched_policy, "i", int32_t, int, "%" PRIi32, sched_policy_to_string_alloc_with_check);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flag_to_string_many_with_check);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check);
|
||||
|
||||
int bus_exec_context_set_transient_property(
|
||||
Unit *u,
|
||||
ExecContext *c,
|
||||
|
@ -1169,31 +1209,172 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (STR_IN_SET(name, "User", "Group")) {
|
||||
const char *uu;
|
||||
if (streq(name, "User"))
|
||||
return bus_set_transient_user(u, name, &c->user, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &uu);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "Group"))
|
||||
return bus_set_transient_user(u, name, &c->group, message, flags, error);
|
||||
|
||||
if (!isempty(uu) && !valid_user_group_name_or_id(uu))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, uu);
|
||||
if (streq(name, "TTYPath"))
|
||||
return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "RootImage"))
|
||||
return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
|
||||
|
||||
if (streq(name, "User"))
|
||||
r = free_and_strdup(&c->user, empty_to_null(uu));
|
||||
else /* "Group" */
|
||||
r = free_and_strdup(&c->group, empty_to_null(uu));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "RootDirectory"))
|
||||
return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, uu);
|
||||
}
|
||||
if (streq(name, "SyslogIdentifier"))
|
||||
return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "LogLevelMax"))
|
||||
return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
|
||||
|
||||
} else if (streq(name, "SupplementaryGroups")) {
|
||||
if (streq(name, "CPUSchedulingPriority"))
|
||||
return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error);
|
||||
|
||||
if (streq(name, "Personality"))
|
||||
return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
|
||||
|
||||
if (streq(name, "Nice"))
|
||||
return bus_set_transient_nice(u, name, &c->nice, message, flags, error);
|
||||
|
||||
if (streq(name, "StandardInput"))
|
||||
return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
|
||||
|
||||
if (streq(name, "StandardOutput"))
|
||||
return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
|
||||
|
||||
if (streq(name, "StandardError"))
|
||||
return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
|
||||
|
||||
if (streq(name, "IgnoreSIGPIPE"))
|
||||
return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
|
||||
|
||||
if (streq(name, "TTYVHangup"))
|
||||
return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
|
||||
|
||||
if (streq(name, "TTYReset"))
|
||||
return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
|
||||
|
||||
if (streq(name, "TTYVTDisallocate"))
|
||||
return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
|
||||
|
||||
if (streq(name, "PrivateTmp"))
|
||||
return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error);
|
||||
|
||||
if (streq(name, "PrivateDevices"))
|
||||
return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
|
||||
|
||||
if (streq(name, "PrivateNetwork"))
|
||||
return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
|
||||
|
||||
if (streq(name, "PrivateUsers"))
|
||||
return bus_set_transient_bool(u, name, &c->private_users, message, flags, error);
|
||||
|
||||
if (streq(name, "NoNewPrivileges"))
|
||||
return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
|
||||
|
||||
if (streq(name, "SyslogLevelPrefix"))
|
||||
return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
|
||||
|
||||
if (streq(name, "MemoryDenyWriteExecute"))
|
||||
return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
|
||||
|
||||
if (streq(name, "RestrictRealtime"))
|
||||
return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
|
||||
|
||||
if (streq(name, "DynamicUser"))
|
||||
return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
|
||||
|
||||
if (streq(name, "RemoveIPC"))
|
||||
return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
|
||||
|
||||
if (streq(name, "ProtectKernelTunables"))
|
||||
return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
|
||||
|
||||
if (streq(name, "ProtectKernelModules"))
|
||||
return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
|
||||
|
||||
if (streq(name, "ProtectControlGroups"))
|
||||
return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
|
||||
|
||||
if (streq(name, "MountAPIVFS"))
|
||||
return bus_set_transient_bool(u, name, &c->mount_apivfs, message, flags, error);
|
||||
|
||||
if (streq(name, "CPUSchedulingResetOnFork"))
|
||||
return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
|
||||
|
||||
if (streq(name, "NonBlocking"))
|
||||
return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
|
||||
|
||||
if (streq(name, "LockPersonality"))
|
||||
return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
|
||||
|
||||
if (streq(name, "UtmpIdentifier"))
|
||||
return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
|
||||
|
||||
if (streq(name, "UtmpMode"))
|
||||
return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
|
||||
|
||||
if (streq(name, "PAMName"))
|
||||
return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
|
||||
|
||||
if (streq(name, "TimerSlackNSec"))
|
||||
return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
|
||||
|
||||
if (streq(name, "ProtectSystem"))
|
||||
return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
|
||||
|
||||
if (streq(name, "ProtectHome"))
|
||||
return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
|
||||
|
||||
if (streq(name, "KeyringMode"))
|
||||
return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
|
||||
|
||||
if (streq(name, "RuntimeDirectoryPreserve"))
|
||||
return bus_set_transient_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
|
||||
|
||||
if (streq(name, "UMask"))
|
||||
return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
|
||||
|
||||
if (streq(name, "RuntimeDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "StateDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "CacheDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "LogsDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "ConfigurationDirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
|
||||
|
||||
if (streq(name, "SELinuxContext"))
|
||||
return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
|
||||
|
||||
if (streq(name, "SecureBits"))
|
||||
return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
|
||||
|
||||
if (streq(name, "CapabilityBoundingSet"))
|
||||
return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
|
||||
|
||||
if (streq(name, "AmbientCapabilities"))
|
||||
return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
|
||||
|
||||
if (streq(name, "CPUSchedulingPolicy"))
|
||||
return bus_set_transient_sched_policy(u, name, &c->cpu_sched_policy, message, flags, error);
|
||||
|
||||
if (streq(name, "RestrictNamespaces"))
|
||||
return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
|
||||
|
||||
if (streq(name, "MountFlags"))
|
||||
return bus_set_transient_mount_flags(u, name, &c->mount_flags, message, flags, error);
|
||||
|
||||
if (streq(name, "SupplementaryGroups")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char **p;
|
||||
|
||||
|
@ -1227,23 +1408,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SyslogIdentifier")) {
|
||||
const char *id;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
r = free_and_strdup(&c->syslog_identifier, empty_to_null(id));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "SyslogIdentifier=%s", id);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (streq(name, "SyslogLevel")) {
|
||||
int32_t level;
|
||||
|
||||
|
@ -1260,6 +1424,7 @@ int bus_exec_context_set_transient_property(
|
|||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SyslogFacility")) {
|
||||
int32_t facility;
|
||||
|
||||
|
@ -1277,23 +1442,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "LogLevelMax")) {
|
||||
int32_t level;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &level);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
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 (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->log_level_max = level;
|
||||
unit_write_settingf(u, flags, name, "LogLevelMax=%i", level);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "LogExtraFields")) {
|
||||
size_t n = 0;
|
||||
|
||||
|
@ -1367,75 +1515,14 @@ int bus_exec_context_set_transient_property(
|
|||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SecureBits")) {
|
||||
int n;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!secure_bits_is_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid secure bits");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
|
||||
c->secure_bits = n;
|
||||
r = secure_bits_to_string_alloc(n, &str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags, name, "SecureBits=%s", str);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
|
||||
uint64_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
|
||||
if (streq(name, "CapabilityBoundingSet"))
|
||||
c->capability_bounding_set = n;
|
||||
else /* "AmbientCapabilities" */
|
||||
c->capability_ambient_set = n;
|
||||
|
||||
r = capability_set_to_string_alloc(n, &str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "Personality")) {
|
||||
const char *s;
|
||||
unsigned long p;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = personality_from_string(s);
|
||||
if (p == PERSONALITY_INVALID)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid personality");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->personality = p;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
|
||||
} else if (streq(name, "SystemCallFilter")) {
|
||||
if (streq(name, "SystemCallErrorNumber"))
|
||||
return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
|
||||
|
||||
if (streq(name, "SystemCallFilter")) {
|
||||
int whitelist;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
|
@ -1546,24 +1633,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SystemCallErrorNumber")) {
|
||||
int32_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (n <= 0 || n > ERRNO_MAX)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SystemCallErrorNumber");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->syscall_errno = n;
|
||||
|
||||
unit_write_settingf(u, flags, name, "SystemCallErrorNumber=%d", n);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "RestrictAddressFamilies")) {
|
||||
int whitelist;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
@ -1628,49 +1697,9 @@ int bus_exec_context_set_transient_property(
|
|||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
} else if (streq(name, "CPUSchedulingPolicy")) {
|
||||
int32_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!sched_policy_is_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
|
||||
c->cpu_sched_policy = n;
|
||||
r = sched_policy_to_string_alloc(n, &str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", str);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "CPUSchedulingPriority")) {
|
||||
int32_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!sched_priority_is_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->cpu_sched_priority = n;
|
||||
unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", n);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "CPUAffinity")) {
|
||||
if (streq(name, "CPUAffinity")) {
|
||||
const void *a;
|
||||
size_t n = 0;
|
||||
|
||||
|
@ -1735,22 +1764,6 @@ int bus_exec_context_set_transient_property(
|
|||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (streq(name, "Nice")) {
|
||||
int32_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!nice_is_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Nice value out of range");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->nice = n;
|
||||
unit_write_settingf(u, flags, name, "Nice=%i", n);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IOSchedulingClass")) {
|
||||
|
@ -1797,33 +1810,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "TTYPath", "RootDirectory", "RootImage")) {
|
||||
const char *s;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(s) && !path_is_absolute(s))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s takes an absolute path", name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "TTYPath"))
|
||||
r = free_and_strdup(&c->tty_path, empty_to_null(s));
|
||||
else if (streq(name, "RootImage"))
|
||||
r = free_and_strdup(&c->root_image, empty_to_null(s));
|
||||
else {
|
||||
assert(streq(name, "RootDirectory"));
|
||||
r = free_and_strdup(&c->root_directory, empty_to_null(s));
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "WorkingDirectory")) {
|
||||
const char *s;
|
||||
bool missing_ok;
|
||||
|
@ -1859,66 +1845,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "StandardInput")) {
|
||||
const char *s;
|
||||
ExecInput p;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = exec_input_from_string(s);
|
||||
if (p < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard input name");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->std_input = p;
|
||||
|
||||
unit_write_settingf(u, flags, name, "StandardInput=%s", exec_input_to_string(p));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "StandardOutput")) {
|
||||
const char *s;
|
||||
ExecOutput p;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = exec_output_from_string(s);
|
||||
if (p < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard output name");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->std_output = p;
|
||||
|
||||
unit_write_settingf(u, flags, name, "StandardOutput=%s", exec_output_to_string(p));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "StandardError")) {
|
||||
const char *s;
|
||||
ExecOutput p;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = exec_output_from_string(s);
|
||||
if (p < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid standard error name");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->std_error = p;
|
||||
|
||||
unit_write_settingf(u, flags, name, "StandardError=%s", exec_output_to_string(p));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name,
|
||||
"StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
|
||||
const char *s;
|
||||
|
@ -2051,124 +1977,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name,
|
||||
"IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "TTYVTDisallocate",
|
||||
"PrivateTmp", "PrivateDevices", "PrivateNetwork", "PrivateUsers",
|
||||
"NoNewPrivileges", "SyslogLevelPrefix", "MemoryDenyWriteExecute",
|
||||
"RestrictRealtime", "DynamicUser", "RemoveIPC", "ProtectKernelTunables",
|
||||
"ProtectKernelModules", "ProtectControlGroups", "MountAPIVFS",
|
||||
"CPUSchedulingResetOnFork", "NonBlocking", "LockPersonality")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "IgnoreSIGPIPE"))
|
||||
c->ignore_sigpipe = b;
|
||||
else if (streq(name, "TTYVHangup"))
|
||||
c->tty_vhangup = b;
|
||||
else if (streq(name, "TTYReset"))
|
||||
c->tty_reset = b;
|
||||
else if (streq(name, "TTYVTDisallocate"))
|
||||
c->tty_vt_disallocate = b;
|
||||
else if (streq(name, "PrivateTmp"))
|
||||
c->private_tmp = b;
|
||||
else if (streq(name, "PrivateDevices"))
|
||||
c->private_devices = b;
|
||||
else if (streq(name, "PrivateNetwork"))
|
||||
c->private_network = b;
|
||||
else if (streq(name, "PrivateUsers"))
|
||||
c->private_users = b;
|
||||
else if (streq(name, "NoNewPrivileges"))
|
||||
c->no_new_privileges = b;
|
||||
else if (streq(name, "SyslogLevelPrefix"))
|
||||
c->syslog_level_prefix = b;
|
||||
else if (streq(name, "MemoryDenyWriteExecute"))
|
||||
c->memory_deny_write_execute = b;
|
||||
else if (streq(name, "RestrictRealtime"))
|
||||
c->restrict_realtime = b;
|
||||
else if (streq(name, "DynamicUser"))
|
||||
c->dynamic_user = b;
|
||||
else if (streq(name, "RemoveIPC"))
|
||||
c->remove_ipc = b;
|
||||
else if (streq(name, "ProtectKernelTunables"))
|
||||
c->protect_kernel_tunables = b;
|
||||
else if (streq(name, "ProtectKernelModules"))
|
||||
c->protect_kernel_modules = b;
|
||||
else if (streq(name, "ProtectControlGroups"))
|
||||
c->protect_control_groups = b;
|
||||
else if (streq(name, "MountAPIVFS"))
|
||||
c->mount_apivfs = b;
|
||||
else if (streq(name, "CPUSchedulingResetOnFork"))
|
||||
c->cpu_sched_reset_on_fork = b;
|
||||
else if (streq(name, "NonBlocking"))
|
||||
c->non_blocking = b;
|
||||
else if (streq(name, "LockPersonality"))
|
||||
c->lock_personality = b;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "UtmpIdentifier")) {
|
||||
const char *id;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
r = free_and_strdup(&c->utmp_id, empty_to_null(id));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "UtmpIdentifier=%s", strempty(id));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "UtmpMode")) {
|
||||
const char *s;
|
||||
ExecUtmpMode m;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = exec_utmp_mode_from_string(s);
|
||||
if (m < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid utmp mode");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->utmp_mode = m;
|
||||
|
||||
unit_write_settingf(u, flags, name, "UtmpMode=%s", exec_utmp_mode_to_string(m));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "PAMName")) {
|
||||
const char *n;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
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;
|
||||
|
||||
} else if (streq(name, "Environment")) {
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
@ -2241,21 +2049,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TimerSlackNSec")) {
|
||||
|
||||
nsec_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->timer_slack_nsec = n;
|
||||
unit_write_settingf(u, flags, name, "TimerSlackNSec=" NSEC_FMT, n);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "OOMScoreAdjust")) {
|
||||
int oa;
|
||||
|
||||
|
@ -2413,9 +2206,6 @@ int bus_exec_context_set_transient_property(
|
|||
char *i = *p;
|
||||
size_t offset;
|
||||
|
||||
if (!utf8_is_valid(i))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
|
||||
|
||||
offset = i[0] == '-';
|
||||
offset += i[offset] == '+';
|
||||
if (!path_is_absolute(i + offset))
|
||||
|
@ -2452,123 +2242,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "ProtectSystem")) {
|
||||
const char *s;
|
||||
ProtectSystem ps;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = parse_boolean(s);
|
||||
if (r > 0)
|
||||
ps = PROTECT_SYSTEM_YES;
|
||||
else if (r == 0)
|
||||
ps = PROTECT_SYSTEM_NO;
|
||||
else {
|
||||
ps = protect_system_from_string(s);
|
||||
if (ps < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect system value");
|
||||
}
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->protect_system = ps;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "ProtectHome")) {
|
||||
const char *s;
|
||||
ProtectHome ph;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = parse_boolean(s);
|
||||
if (r > 0)
|
||||
ph = PROTECT_HOME_YES;
|
||||
else if (r == 0)
|
||||
ph = PROTECT_HOME_NO;
|
||||
else {
|
||||
ph = protect_home_from_string(s);
|
||||
if (ph < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to parse protect home value");
|
||||
}
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->protect_home = ph;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "KeyringMode")) {
|
||||
|
||||
const char *s;
|
||||
ExecKeyringMode m;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = exec_keyring_mode_from_string(s);
|
||||
if (m < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid keyring mode");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->keyring_mode = m;
|
||||
|
||||
unit_write_settingf(u, flags, name, "KeyringMode=%s", exec_keyring_mode_to_string(m));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "RuntimeDirectoryPreserve")) {
|
||||
const char *s;
|
||||
ExecPreserveMode m;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = exec_preserve_mode_from_string(s);
|
||||
if (m < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid preserve mode");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->runtime_directory_preserve_mode = m;
|
||||
|
||||
unit_write_settingf(u, flags, name, "RuntimeDirectoryPreserve=%s", exec_preserve_mode_to_string(m));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "RuntimeDirectoryMode", "StateDirectoryMode", "CacheDirectoryMode", "LogsDirectoryMode", "ConfigurationDirectoryMode", "UMask")) {
|
||||
mode_t m;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
ExecDirectoryType i;
|
||||
|
||||
if (streq(name, "UMask"))
|
||||
c->umask = m;
|
||||
else
|
||||
for (i = 0; i < _EXEC_DIRECTORY_TYPE_MAX; i++)
|
||||
if (startswith(name, exec_directory_type_to_string(i))) {
|
||||
c->directories[i].mode = m;
|
||||
break;
|
||||
}
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%040o", name, m);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char **p;
|
||||
|
@ -2614,24 +2287,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SELinuxContext")) {
|
||||
const char *s;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
r = free_and_strdup(&c->selinux_context, empty_to_null(s));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(s));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
|
||||
int ignore;
|
||||
const char *s;
|
||||
|
@ -2670,43 +2325,6 @@ int bus_exec_context_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "RestrictNamespaces")) {
|
||||
uint64_t rf;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &rf);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if ((rf & NAMESPACE_FLAGS_ALL) != rf)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown namespace types");
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
r = namespace_flag_to_string_many(rf, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->restrict_namespaces = rf;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, s);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (streq(name, "MountFlags")) {
|
||||
uint64_t fl;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &fl);
|
||||
if (r < 0)
|
||||
return r;
|
||||
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 (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->mount_flags = fl;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, mount_propagation_flags_to_string(fl));
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
|
||||
unsigned empty = true;
|
||||
|
||||
|
|
|
@ -44,4 +44,4 @@ int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *int
|
|||
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, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_exec_command_set_transient_property(Unit *u, const char *name, ExecCommand **exec_command, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_exec_command(Unit *u, const char *name, ExecCommand **exec_command, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "bus-util.h"
|
||||
#include "dbus-kill.h"
|
||||
#include "dbus-util.h"
|
||||
#include "kill.h"
|
||||
#include "signal-util.h"
|
||||
|
||||
|
@ -34,6 +35,9 @@ const sd_bus_vtable bus_kill_vtable[] = {
|
|||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(kill_mode, KillMode, kill_mode_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(kill_signal, "i", int32_t, int, "%" PRIi32, signal_to_string_with_check);
|
||||
|
||||
int bus_kill_context_set_transient_property(
|
||||
Unit *u,
|
||||
KillContext *c,
|
||||
|
@ -42,8 +46,6 @@ int bus_kill_context_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
assert(c);
|
||||
assert(name);
|
||||
|
@ -51,75 +53,17 @@ int bus_kill_context_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "KillMode")) {
|
||||
const char *m;
|
||||
KillMode k;
|
||||
if (streq(name, "KillMode"))
|
||||
return bus_set_transient_kill_mode(u, name, &c->kill_mode, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "SendSIGHUP"))
|
||||
return bus_set_transient_bool(u, name, &c->send_sighup, message, flags, error);
|
||||
|
||||
k = kill_mode_from_string(m);
|
||||
if (k < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m);
|
||||
if (streq(name, "SendSIGKILL"))
|
||||
return bus_set_transient_bool(u, name, &c->send_sigkill, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->kill_mode = k;
|
||||
|
||||
unit_write_settingf(u, flags, name, "KillMode=%s", kill_mode_to_string(k));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "KillSignal")) {
|
||||
int sig;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &sig);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!SIGNAL_VALID(sig))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->kill_signal = sig;
|
||||
|
||||
unit_write_settingf(u, flags, name, "KillSignal=%s", signal_to_string(sig));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SendSIGHUP")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->send_sighup = b;
|
||||
|
||||
unit_write_settingf(u, flags, name, "SendSIGHUP=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SendSIGKILL")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
c->send_sigkill = b;
|
||||
|
||||
unit_write_settingf(u, flags, name, "SendSIGKILL=%s", yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
if (streq(name, "KillSignal"))
|
||||
return bus_set_transient_kill_signal(u, name, &c->kill_signal, message, flags, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -2423,8 +2423,10 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
|||
SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */
|
||||
SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
/* The following two items are obsolete alias */
|
||||
SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "dbus-execute.h"
|
||||
#include "dbus-kill.h"
|
||||
#include "dbus-mount.h"
|
||||
#include "dbus-util.h"
|
||||
#include "mount.h"
|
||||
#include "string-util.h"
|
||||
#include "unit.h"
|
||||
|
@ -129,9 +130,7 @@ static int bus_mount_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
const char *new_property;
|
||||
char **property;
|
||||
int r;
|
||||
Unit *u = UNIT(m);
|
||||
|
||||
assert(m);
|
||||
assert(name);
|
||||
|
@ -139,29 +138,34 @@ static int bus_mount_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "Where"))
|
||||
return bus_set_transient_path(u, name, &m->where, message, flags, error);
|
||||
|
||||
if (streq(name, "What"))
|
||||
property = &m->parameters_fragment.what;
|
||||
else if (streq(name, "Options"))
|
||||
property = &m->parameters_fragment.options;
|
||||
else if (streq(name, "Type"))
|
||||
property = &m->parameters_fragment.fstype;
|
||||
else
|
||||
return 0;
|
||||
return bus_set_transient_string(u, name, &m->parameters_fragment.what, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &new_property);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "Options"))
|
||||
return bus_set_transient_string(u, name, &m->parameters_fragment.options, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "Type"))
|
||||
return bus_set_transient_string(u, name, &m->parameters_fragment.fstype, message, flags, error);
|
||||
|
||||
r = free_and_strdup(property, new_property);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "TimeoutUSec"))
|
||||
return bus_set_transient_usec_fix_0(u, name, &m->timeout_usec, message, flags, error);
|
||||
|
||||
unit_write_settingf(UNIT(m), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, new_property);
|
||||
}
|
||||
if (streq(name, "DirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &m->directory_mode, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "SloppyOptions"))
|
||||
return bus_set_transient_bool(u, name, &m->sloppy_options, message, flags, error);
|
||||
|
||||
if (streq(name, "LazyUnmount"))
|
||||
return bus_set_transient_bool(u, name, &m->lazy_unmount, message, flags, error);
|
||||
|
||||
if (streq(name, "ForceUnmount"))
|
||||
return bus_set_transient_bool(u, name, &m->force_unmount, message, flags, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_mount_set_property(
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "alloc-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "dbus-path.h"
|
||||
#include "dbus-util.h"
|
||||
#include "list.h"
|
||||
#include "path.h"
|
||||
#include "path-util.h"
|
||||
|
@ -105,30 +106,38 @@ static int bus_path_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (STR_IN_SET(name, "PathExists", "PathExistsGlob", "PathChanged", "PathModified", "DirectoryNotEmpty")) {
|
||||
const char *str;
|
||||
PathType b;
|
||||
if (streq(name, "MakeDirectory"))
|
||||
return bus_set_transient_bool(u, name, &p->make_directory, message, flags, error);
|
||||
|
||||
b = path_type_from_string(name);
|
||||
if (b < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type");
|
||||
if (streq(name, "DirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &p->directory_mode, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &str);
|
||||
if (streq(name, "Paths")) {
|
||||
const char *type_name, *path;
|
||||
bool empty = true;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "(ss)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(str) && !path_is_absolute(str))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path is not absolute");
|
||||
while ((r = sd_bus_message_read(message, "(ss)", &type_name, &path)) > 0) {
|
||||
PathType t;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (isempty(str)) {
|
||||
path_free_specs(p);
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
} else {
|
||||
t = path_type_from_string(type_name);
|
||||
if (t < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown path type: %s", type_name);
|
||||
|
||||
if (isempty(path))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is empty", type_name);
|
||||
|
||||
if (!path_is_absolute(path))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in %s is not absolute: %s", type_name, path);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
_cleanup_free_ char *k;
|
||||
PathSpec *s;
|
||||
|
||||
k = strdup(str);
|
||||
k = strdup(path);
|
||||
if (!k)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -139,48 +148,29 @@ static int bus_path_set_transient_property(
|
|||
s->unit = u;
|
||||
s->path = path_kill_slashes(k);
|
||||
k = NULL;
|
||||
s->type = b;
|
||||
s->type = t;
|
||||
s->inotify_fd = -1;
|
||||
|
||||
LIST_PREPEND(spec, p->specs, s);
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str);
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", type_name, path);
|
||||
}
|
||||
|
||||
empty = false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "MakeDirectory")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
p->make_directory = b;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "DirectoryMode")) {
|
||||
mode_t m;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &m);
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
p->directory_mode = m;
|
||||
unit_write_settingf(u, flags, name, "%s=%040o", name, m);
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
path_free_specs(p);
|
||||
unit_write_settingf(u, flags, name, "PathExists=");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "Unit")) {
|
||||
/* not implemented yet */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "dbus-kill.h"
|
||||
#include "dbus-scope.h"
|
||||
#include "dbus-unit.h"
|
||||
#include "dbus-util.h"
|
||||
#include "dbus.h"
|
||||
#include "scope.h"
|
||||
#include "selinux-access.h"
|
||||
|
@ -84,6 +85,9 @@ static int bus_scope_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "TimeoutStopUSec"))
|
||||
return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error);
|
||||
|
||||
if (streq(name, "PIDs")) {
|
||||
unsigned n = 0;
|
||||
uint32_t pid;
|
||||
|
@ -138,21 +142,6 @@ static int bus_scope_set_transient_property(
|
|||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TimeoutStopUSec")) {
|
||||
uint64_t t;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &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;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,15 +22,20 @@
|
|||
|
||||
#include "alloc-util.h"
|
||||
#include "async.h"
|
||||
#include "bus-internal.h"
|
||||
#include "bus-util.h"
|
||||
#include "dbus-cgroup.h"
|
||||
#include "dbus-execute.h"
|
||||
#include "dbus-kill.h"
|
||||
#include "dbus-service.h"
|
||||
#include "dbus-util.h"
|
||||
#include "exit-status.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "service.h"
|
||||
#include "signal-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit.h"
|
||||
|
@ -41,6 +46,71 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, Servi
|
|||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
|
||||
|
||||
static int property_get_exit_status_set(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
ExitStatusSet *status_set = userdata;
|
||||
Iterator i;
|
||||
void *id;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(status_set);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'r', "aiai");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "i");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(id, status_set->status, i) {
|
||||
int val = PTR_TO_INT(id);
|
||||
|
||||
if (val < 0 || val > 255)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append_basic(reply, 'i', &val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "i");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(id, status_set->signal, i) {
|
||||
int val = PTR_TO_INT(id);
|
||||
const char *str;
|
||||
|
||||
str = signal_to_string(val);
|
||||
if (!str)
|
||||
continue;
|
||||
|
||||
r = sd_bus_message_append_basic(reply, 'i', &val);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_bus_message_close_container(reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
const sd_bus_vtable bus_service_vtable[] = {
|
||||
SD_BUS_VTABLE_START(0),
|
||||
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
@ -57,6 +127,9 @@ const sd_bus_vtable bus_service_vtable[] = {
|
|||
SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool, offsetof(Service, root_directory_start_only), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool, offsetof(Service, remain_after_exit), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool, offsetof(Service, guess_main_pid), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RestartPreventExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, restart_prevent_status), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RestartForceExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, restart_force_status), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("SuccessExitStatus", "(aiai)", property_get_exit_status_set, offsetof(Service, success_status), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid, offsetof(Service, main_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
@ -88,6 +161,117 @@ const sd_bus_vtable bus_service_vtable[] = {
|
|||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static int bus_set_transient_exit_status(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
ExitStatusSet *status_set,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
const int *status, *signal;
|
||||
size_t sz_status, sz_signal, i;
|
||||
int r;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'r', "aiai");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read_array(message, 'i', (const void **) &status, &sz_status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read_array(message, 'i', (const void **) &signal, &sz_signal);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (sz_status == 0 && sz_signal == 0 && !UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
exit_status_set_free(status_set);
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sz_status; i++) {
|
||||
if (status[i] < 0 || status[i] > 255)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid status code in %s: %i", name, status[i]);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
r = set_ensure_allocated(&status_set->status, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_put(status_set->status, INT_TO_PTR(status[i]));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%i", name, status[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < sz_signal; i++) {
|
||||
const char *str;
|
||||
|
||||
str = signal_to_string(signal[i]);
|
||||
if (!str)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal in %s: %i", name, signal[i]);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
r = set_ensure_allocated(&status_set->signal, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_put(status_set->signal, INT_TO_PTR(signal[i]));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_set_transient_std_fd(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
int *p,
|
||||
bool *b,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int fd, r;
|
||||
|
||||
assert(p);
|
||||
assert(b);
|
||||
|
||||
r = sd_bus_message_read(message, "h", &fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
int copy;
|
||||
|
||||
copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
||||
if (copy < 0)
|
||||
return -errno;
|
||||
|
||||
asynchronous_close(*p);
|
||||
*p = copy;
|
||||
*b = true;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access, NotifyAccess, notify_access_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type, ServiceType, service_type_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_restart_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, service_name_is_valid);
|
||||
|
||||
static int bus_service_set_transient_property(
|
||||
Service *s,
|
||||
const char *name,
|
||||
|
@ -95,6 +279,7 @@ static int bus_service_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Unit *u = UNIT(s);
|
||||
ServiceExecCommand ci;
|
||||
int r;
|
||||
|
||||
|
@ -104,143 +289,82 @@ static int bus_service_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (streq(name, "RemainAfterExit")) {
|
||||
int b;
|
||||
if (streq(name, "PermissionsStartOnly"))
|
||||
return bus_set_transient_bool(u, name, &s->permissions_start_only, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "RootDirectoryStartOnly"))
|
||||
return bus_set_transient_bool(u, name, &s->root_directory_start_only, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->remain_after_exit = b;
|
||||
unit_write_settingf(UNIT(s), flags, name, "RemainAfterExit=%s", yes_no(b));
|
||||
}
|
||||
if (streq(name, "RemainAfterExit"))
|
||||
return bus_set_transient_bool(u, name, &s->remain_after_exit, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "GuessMainPID"))
|
||||
return bus_set_transient_bool(u, name, &s->guess_main_pid, message, flags, error);
|
||||
|
||||
} else if (streq(name, "Type")) {
|
||||
const char *t;
|
||||
ServiceType k;
|
||||
if (streq(name, "Type"))
|
||||
return bus_set_transient_service_type(u, name, &s->type, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "RestartUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->restart_usec, message, flags, error);
|
||||
|
||||
k = service_type_from_string(t);
|
||||
if (k < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service type %s", t);
|
||||
if (streq(name, "TimeoutStartUSec")) {
|
||||
r = bus_set_transient_usec(u, name, &s->timeout_start_usec, message, flags, error);
|
||||
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
|
||||
s->start_timeout_defined = true;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->type = k;
|
||||
unit_write_settingf(UNIT(s), flags, name, "Type=%s", service_type_to_string(s->type));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (streq(name, "RuntimeMaxUSec")) {
|
||||
usec_t u;
|
||||
if (streq(name, "TimeoutStopUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->timeout_stop_usec, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "RuntimeMaxUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->runtime_max_usec, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->runtime_max_usec = u;
|
||||
unit_write_settingf(UNIT(s), flags, name, "RuntimeMaxSec=" USEC_FMT "us", u);
|
||||
}
|
||||
if (streq(name, "WatchdogUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->watchdog_usec, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "FileDescriptorStoreMax"))
|
||||
return bus_set_transient_unsigned(u, name, &s->n_fd_store_max, message, flags, error);
|
||||
|
||||
} else if (streq(name, "Restart")) {
|
||||
ServiceRestart sr;
|
||||
const char *v;
|
||||
if (streq(name, "NotifyAccess"))
|
||||
return bus_set_transient_notify_access(u, name, &s->notify_access, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "PIDFile"))
|
||||
return bus_set_transient_path(u, name, &s->pid_file, message, flags, error);
|
||||
|
||||
if (isempty(v))
|
||||
sr = SERVICE_RESTART_NO;
|
||||
else {
|
||||
sr = service_restart_from_string(v);
|
||||
if (sr < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid restart setting: %s", v);
|
||||
}
|
||||
if (streq(name, "USBFunctionDescriptors"))
|
||||
return bus_set_transient_path(u, name, &s->usb_function_descriptors, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->restart = sr;
|
||||
unit_write_settingf(UNIT(s), flags, name, "Restart=%s", service_restart_to_string(sr));
|
||||
}
|
||||
if (streq(name, "USBFunctionStrings"))
|
||||
return bus_set_transient_path(u, name, &s->usb_function_strings, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "BusName"))
|
||||
return bus_set_transient_bus_name(u, name, &s->bus_name, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name,
|
||||
"StandardInputFileDescriptor",
|
||||
"StandardOutputFileDescriptor",
|
||||
"StandardErrorFileDescriptor")) {
|
||||
int fd;
|
||||
if (streq(name, "Restart"))
|
||||
return bus_set_transient_service_restart(u, name, &s->restart, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "h", &fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "RestartPreventExitStatus"))
|
||||
return bus_set_transient_exit_status(u, name, &s->restart_prevent_status, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
int copy;
|
||||
if (streq(name, "RestartForceExitStatus"))
|
||||
return bus_set_transient_exit_status(u, name, &s->restart_force_status, message, flags, error);
|
||||
|
||||
copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
||||
if (copy < 0)
|
||||
return -errno;
|
||||
if (streq(name, "SuccessExitStatus"))
|
||||
return bus_set_transient_exit_status(u, name, &s->success_status, message, flags, error);
|
||||
|
||||
if (streq(name, "StandardInputFileDescriptor")) {
|
||||
asynchronous_close(s->stdin_fd);
|
||||
s->stdin_fd = copy;
|
||||
} else if (streq(name, "StandardOutputFileDescriptor")) {
|
||||
asynchronous_close(s->stdout_fd);
|
||||
s->stdout_fd = copy;
|
||||
} else {
|
||||
asynchronous_close(s->stderr_fd);
|
||||
s->stderr_fd = copy;
|
||||
}
|
||||
if ((ci = service_exec_command_from_string(name)) >= 0)
|
||||
return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error);
|
||||
|
||||
s->exec_context.stdio_as_fds = true;
|
||||
}
|
||||
if (streq(name, "StandardInputFileDescriptor"))
|
||||
return bus_set_transient_std_fd(u, name, &s->stdin_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "StandardOutputFileDescriptor"))
|
||||
return bus_set_transient_std_fd(u, name, &s->stdout_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
||||
|
||||
} else if (streq(name, "FileDescriptorStoreMax")) {
|
||||
uint32_t u;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->n_fd_store_max = (unsigned) u;
|
||||
unit_write_settingf(UNIT(s), flags, name, "FileDescriptorStoreMax=%" PRIu32, u);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "NotifyAccess")) {
|
||||
const char *t;
|
||||
NotifyAccess k;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
k = notify_access_from_string(t);
|
||||
if (k < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid notify access setting %s", t);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->notify_access = k;
|
||||
unit_write_settingf(UNIT(s), flags, name, "NotifyAccess=%s", notify_access_to_string(s->notify_access));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if ((ci = service_exec_command_from_string(name)) >= 0)
|
||||
return bus_exec_command_set_transient_property(UNIT(s), name, &s->exec_command[ci], message, flags, error);
|
||||
if (streq(name, "StandardErrorFileDescriptor"))
|
||||
return bus_set_transient_std_fd(u, name, &s->stderr_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "dbus-execute.h"
|
||||
#include "dbus-kill.h"
|
||||
#include "dbus-socket.h"
|
||||
#include "dbus-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
|
@ -32,8 +33,6 @@
|
|||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "unit.h"
|
||||
#include "user-util.h"
|
||||
#include "utf8.h"
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, socket_result, SocketResult);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_bind_ipv6_only, socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
|
||||
|
@ -171,6 +170,26 @@ const sd_bus_vtable bus_socket_vtable[] = {
|
|||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
static inline bool check_size_t_truncation(uint64_t t) {
|
||||
return (size_t) t == t;
|
||||
}
|
||||
|
||||
static inline const char* socket_protocol_to_name_supported(int32_t i) {
|
||||
if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP))
|
||||
return NULL;
|
||||
|
||||
return socket_protocol_to_name(i);
|
||||
}
|
||||
|
||||
static BUS_DEFINE_SET_TRANSIENT(int, "i", int32_t, int, "%" PRIi32);
|
||||
static BUS_DEFINE_SET_TRANSIENT(message_queue, "x", int64_t, long, "%" PRIi64);
|
||||
static BUS_DEFINE_SET_TRANSIENT_IS_VALID(size_t_check_truncation, "t", uint64_t, size_t, "%" PRIu64, check_size_t_truncation);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(bind_ipv6_only, SocketAddressBindIPv6Only, parse_socket_address_bind_ipv6_only_or_bool);
|
||||
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(fdname, fdname_is_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(ifname, ifname_valid);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(ip_tos, "i", int32_t, int, "%" PRIi32, ip_tos_to_string_alloc);
|
||||
static BUS_DEFINE_SET_TRANSIENT_TO_STRING(socket_protocol, "i", int32_t, int, "%" PRIi32, socket_protocol_to_name_supported);
|
||||
|
||||
static int bus_socket_set_transient_property(
|
||||
Socket *s,
|
||||
const char *name,
|
||||
|
@ -188,333 +207,139 @@ static int bus_socket_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (STR_IN_SET(name,
|
||||
"Accept", "Writable", "KeepAlive", "NoDelay", "FreeBind", "Transparent", "Broadcast",
|
||||
"PassCredentials", "PassSecurity", "ReusePort", "RemoveOnStop", "SELinuxContextFromNet")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "Accept"))
|
||||
s->accept = b;
|
||||
else if (streq(name, "Writable"))
|
||||
s->writable = b;
|
||||
else if (streq(name, "KeepAlive"))
|
||||
s->keep_alive = b;
|
||||
else if (streq(name, "NoDelay"))
|
||||
s->no_delay = b;
|
||||
else if (streq(name, "FreeBind"))
|
||||
s->free_bind = b;
|
||||
else if (streq(name, "Transparent"))
|
||||
s->transparent = b;
|
||||
else if (streq(name, "Broadcast"))
|
||||
s->broadcast = b;
|
||||
else if (streq(name, "PassCredentials"))
|
||||
s->pass_cred = b;
|
||||
else if (streq(name, "PassSecurity"))
|
||||
s->pass_sec = b;
|
||||
else if (streq(name, "ReusePort"))
|
||||
s->reuse_port = b;
|
||||
else if (streq(name, "RemoveOnStop"))
|
||||
s->remove_on_stop = b;
|
||||
else /* "SELinuxContextFromNet" */
|
||||
s->selinux_context_from_net = b;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "Priority", "IPTTL", "Mark")) {
|
||||
int32_t i;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "Priority"))
|
||||
s->priority = i;
|
||||
else if (streq(name, "IPTTL"))
|
||||
s->ip_ttl = i;
|
||||
else /* "Mark" */
|
||||
s->mark = i;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%i", name, i);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "IPTOS")) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
int32_t i;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ip_tos_to_string_alloc(i, &str);
|
||||
if (r < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->ip_tos = i;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "SocketProtocol")) {
|
||||
const char *p;
|
||||
int32_t i;
|
||||
|
||||
r = sd_bus_message_read(message, "i", &i);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
p = socket_protocol_to_name(i);
|
||||
if (!p)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %i", name, i);
|
||||
|
||||
if (!IN_SET(i, IPPROTO_UDPLITE, IPPROTO_SCTP))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unsupported socket protocol: %s", p);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->socket_protocol = i;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, p);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "Backlog", "MaxConnections", "MaxConnectionsPerSource", "KeepAliveProbes", "TriggerLimitBurst")) {
|
||||
uint32_t n;
|
||||
|
||||
r = sd_bus_message_read(message, "u", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "Backlog"))
|
||||
s->backlog = n;
|
||||
else if (streq(name, "MaxConnections"))
|
||||
s->max_connections = n;
|
||||
else if (streq(name, "MaxConnectionsPerSource"))
|
||||
s->max_connections_per_source = n;
|
||||
else if (streq(name, "KeepAliveProbes"))
|
||||
s->keep_alive_cnt = n;
|
||||
else /* "TriggerLimitBurst" */
|
||||
s->trigger_limit.burst = n;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%u", name, n);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "SocketMode", "DirectoryMode")) {
|
||||
mode_t m;
|
||||
if (streq(name, "Accept"))
|
||||
return bus_set_transient_bool(u, name, &s->accept, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "u", &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "Writable"))
|
||||
return bus_set_transient_bool(u, name, &s->writable, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "SocketMode"))
|
||||
s->socket_mode = m;
|
||||
else /* "DirectoryMode" */
|
||||
s->directory_mode = m;
|
||||
if (streq(name, "KeepAlive"))
|
||||
return bus_set_transient_bool(u, name, &s->keep_alive, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%040o", name, m);
|
||||
}
|
||||
if (streq(name, "NoDelay"))
|
||||
return bus_set_transient_bool(u, name, &s->no_delay, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "FreeBind"))
|
||||
return bus_set_transient_bool(u, name, &s->free_bind, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "MessageQueueMaxMessages", "MessageQueueMessageSize")) {
|
||||
int64_t n;
|
||||
if (streq(name, "Transparent"))
|
||||
return bus_set_transient_bool(u, name, &s->transparent, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "x", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "Broadcast"))
|
||||
return bus_set_transient_bool(u, name, &s->broadcast, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "MessageQueueMaxMessages"))
|
||||
s->mq_maxmsg = (long) n;
|
||||
else /* "MessageQueueMessageSize" */
|
||||
s->mq_msgsize = (long) n;
|
||||
if (streq(name, "PassCredentials"))
|
||||
return bus_set_transient_bool(u, name, &s->pass_cred, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIi64, name, n);
|
||||
}
|
||||
if (streq(name, "PassSecurity"))
|
||||
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "ReusePort"))
|
||||
return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "TimeoutUSec", "KeepAliveTimeUSec", "KeepAliveIntervalUSec", "DeferAcceptUSec", "TriggerLimitIntervalUSec")) {
|
||||
usec_t t;
|
||||
if (streq(name, "RemoveOnStop"))
|
||||
return bus_set_transient_bool(u, name, &s->remove_on_stop, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "SELinuxContextFromNet"))
|
||||
return bus_set_transient_bool(u, name, &s->selinux_context_from_net, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "TimeoutUSec"))
|
||||
s->timeout_usec = t ?: USEC_INFINITY;
|
||||
else if (streq(name, "KeepAliveTimeUSec"))
|
||||
s->keep_alive_time = t;
|
||||
else if (streq(name, "KeepAliveIntervalUSec"))
|
||||
s->keep_alive_interval = t;
|
||||
else if (streq(name, "DeferAcceptUSec"))
|
||||
s->defer_accept = t;
|
||||
else /* "TriggerLimitIntervalUSec" */
|
||||
s->trigger_limit.interval = t;
|
||||
if (streq(name, "Priority"))
|
||||
return bus_set_transient_int(u, name, &s->priority, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=" USEC_FMT, name, t);
|
||||
}
|
||||
if (streq(name, "IPTTL"))
|
||||
return bus_set_transient_int(u, name, &s->ip_ttl, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "Mark"))
|
||||
return bus_set_transient_int(u, name, &s->mark, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "ReceiveBuffer", "SendBuffer", "PipeSize")) {
|
||||
uint64_t t;
|
||||
if (streq(name, "Backlog"))
|
||||
return bus_set_transient_unsigned(u, name, &s->backlog, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "t", &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "MaxConnections"))
|
||||
return bus_set_transient_unsigned(u, name, &s->max_connections, message, flags, error);
|
||||
|
||||
if ((uint64_t) (size_t) t != t)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %" PRIu64, name, t);
|
||||
if (streq(name, "MaxConnectionsPerSource"))
|
||||
return bus_set_transient_unsigned(u, name, &s->max_connections_per_source, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "ReceiveBuffer"))
|
||||
s->receive_buffer = t;
|
||||
else if (streq(name, "SendBuffer"))
|
||||
s->send_buffer = t;
|
||||
else /* "PipeSize" */
|
||||
s->pipe_size = t;
|
||||
if (streq(name, "KeepAliveProbes"))
|
||||
return bus_set_transient_unsigned(u, name, &s->keep_alive_cnt, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, t);
|
||||
}
|
||||
if (streq(name, "TriggerLimitBurst"))
|
||||
return bus_set_transient_unsigned(u, name, &s->trigger_limit.burst, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "SocketMode"))
|
||||
return bus_set_transient_mode_t(u, name, &s->socket_mode, message, flags, error);
|
||||
|
||||
} else if (STR_IN_SET(name, "SmackLabel", "SmackLabelIPIn", "SmackLabelIPOut", "TCPCongestion")) {
|
||||
const char *n;
|
||||
if (streq(name, "DirectoryMode"))
|
||||
return bus_set_transient_mode_t(u, name, &s->directory_mode, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "MessageQueueMaxMessages"))
|
||||
return bus_set_transient_message_queue(u, name, &s->mq_maxmsg, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "MessageQueueMessageSize"))
|
||||
return bus_set_transient_message_queue(u, name, &s->mq_msgsize, message, flags, error);
|
||||
|
||||
if (streq(name, "SmackLabel"))
|
||||
r = free_and_strdup(&s->smack, empty_to_null(n));
|
||||
else if (streq(name, "SmackLabelIPin"))
|
||||
r = free_and_strdup(&s->smack_ip_in, empty_to_null(n));
|
||||
else if (streq(name, "SmackLabelIPOut"))
|
||||
r = free_and_strdup(&s->smack_ip_out, empty_to_null(n));
|
||||
else /* "TCPCongestion" */
|
||||
r = free_and_strdup(&s->tcp_congestion, empty_to_null(n));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "TimeoutUSec"))
|
||||
return bus_set_transient_usec_fix_0(u, name, &s->timeout_usec, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n));
|
||||
}
|
||||
if (streq(name, "KeepAliveTimeUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->keep_alive_time, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "KeepAliveIntervalUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->keep_alive_interval, message, flags, error);
|
||||
|
||||
} else if (streq(name, "BindToDevice")) {
|
||||
const char *n;
|
||||
if (streq(name, "DeferAcceptUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->defer_accept, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "TriggerLimitIntervalUSec"))
|
||||
return bus_set_transient_usec(u, name, &s->trigger_limit.interval, message, flags, error);
|
||||
|
||||
if (n[0] && !streq(n, "*")) {
|
||||
if (!ifname_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface name for %s: %s", name, n);
|
||||
} else
|
||||
n = NULL;
|
||||
if (streq(name, "SmackLabel"))
|
||||
return bus_set_transient_string(u, name, &s->smack, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "SmackLabelIPin"))
|
||||
return bus_set_transient_string(u, name, &s->smack_ip_in, message, flags, error);
|
||||
|
||||
r = free_and_strdup(&s->bind_to_device, empty_to_null(n));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "SmackLabelIPOut"))
|
||||
return bus_set_transient_string(u, name, &s->smack_ip_out, message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n));
|
||||
}
|
||||
if (streq(name, "TCPCongestion"))
|
||||
return bus_set_transient_string(u, name, &s->tcp_congestion, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "FileDescriptorName"))
|
||||
return bus_set_transient_fdname(u, name, &s->fdname, message, flags, error);
|
||||
|
||||
} else if (streq(name, "BindIPv6Only")) {
|
||||
SocketAddressBindIPv6Only b;
|
||||
const char *n;
|
||||
if (streq(name, "SocketUser"))
|
||||
return bus_set_transient_user(u, name, &s->user, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "SocketGroup"))
|
||||
return bus_set_transient_user(u, name, &s->group, message, flags, error);
|
||||
|
||||
b = socket_address_bind_ipv6_only_from_string(n);
|
||||
if (b < 0) {
|
||||
r = parse_boolean(n);
|
||||
if (r < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n);
|
||||
if (streq(name, "BindIPv6Only"))
|
||||
return bus_set_transient_bind_ipv6_only(u, name, &s->bind_ipv6_only, message, flags, error);
|
||||
|
||||
b = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
|
||||
}
|
||||
if (streq(name, "ReceiveBuffer"))
|
||||
return bus_set_transient_size_t_check_truncation(u, name, &s->receive_buffer, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
s->bind_ipv6_only = b;
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, n);
|
||||
}
|
||||
if (streq(name, "SendBuffer"))
|
||||
return bus_set_transient_size_t_check_truncation(u, name, &s->send_buffer, message, flags, error);
|
||||
|
||||
return 1;
|
||||
if (streq(name, "PipeSize"))
|
||||
return bus_set_transient_size_t_check_truncation(u, name, &s->pipe_size, message, flags, error);
|
||||
|
||||
} else if (streq(name, "FileDescriptorName")) {
|
||||
const char *n;
|
||||
if (streq(name, "BindToDevice"))
|
||||
return bus_set_transient_ifname(u, name, &s->bind_to_device, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (streq(name, "IPTOS"))
|
||||
return bus_set_transient_ip_tos(u, name, &s->ip_tos, message, flags, error);
|
||||
|
||||
if (!isempty(n) && !fdname_is_valid(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n);
|
||||
if (streq(name, "SocketProtocol"))
|
||||
return bus_set_transient_socket_protocol(u, name, &s->socket_protocol, message, flags, error);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
r = free_and_strdup(&s->fdname, empty_to_null(n));
|
||||
if (r < 0)
|
||||
return r;
|
||||
if ((ci = socket_exec_command_from_string(name)) >= 0)
|
||||
return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error);
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "SocketUser", "SocketGroup")) {
|
||||
const char *n;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!isempty(n) && !valid_user_group_name_or_id(n))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s: %s", name, n);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
if (streq(name, "SocketUser"))
|
||||
r = free_and_strdup(&s->user, empty_to_null(n));
|
||||
else /* "SocketGroup" */
|
||||
r = free_and_strdup(&s->user, empty_to_null(n));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, strempty(n));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "Symlinks")) {
|
||||
if (streq(name, "Symlinks")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char **p;
|
||||
|
||||
|
@ -523,9 +348,6 @@ static int bus_socket_set_transient_property(
|
|||
return r;
|
||||
|
||||
STRV_FOREACH(p, l) {
|
||||
if (!utf8_is_valid(*p))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "String is not UTF-8 clean, ignoring assignment: %s", *p);
|
||||
|
||||
if (!path_is_absolute(*p))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Symlink path is not absolute: %s", *p);
|
||||
}
|
||||
|
@ -623,9 +445,7 @@ static int bus_socket_set_transient_property(
|
|||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if ((ci = socket_exec_command_from_string(name)) >= 0)
|
||||
return bus_exec_command_set_transient_property(UNIT(s), name, &s->exec_command[ci], message, flags, error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "alloc-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "dbus-timer.h"
|
||||
#include "dbus-util.h"
|
||||
#include "strv.h"
|
||||
#include "timer.h"
|
||||
#include "unit.h"
|
||||
|
@ -179,6 +180,7 @@ static int bus_timer_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Unit *u = UNIT(t);
|
||||
int r;
|
||||
|
||||
assert(t);
|
||||
|
@ -187,7 +189,130 @@ static int bus_timer_set_transient_property(
|
|||
|
||||
flags |= UNIT_PRIVATE;
|
||||
|
||||
if (STR_IN_SET(name,
|
||||
if (streq(name, "AccuracyUSec"))
|
||||
return bus_set_transient_usec(u, name, &t->accuracy_usec, message, flags, error);
|
||||
|
||||
if (streq(name, "AccuracySec")) {
|
||||
log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead.");
|
||||
return bus_set_transient_usec(u, "AccuracyUSec", &t->accuracy_usec, message, flags, error);
|
||||
}
|
||||
|
||||
if (streq(name, "RandomizedDelayUSec"))
|
||||
return bus_set_transient_usec(u, name, &t->random_usec, message, flags, error);
|
||||
|
||||
if (streq(name, "WakeSystem"))
|
||||
return bus_set_transient_bool(u, name, &t->wake_system, message, flags, error);
|
||||
|
||||
if (streq(name, "Persistent"))
|
||||
return bus_set_transient_bool(u, name, &t->persistent, message, flags, error);
|
||||
|
||||
if (streq(name, "RemainAfterElapse"))
|
||||
return bus_set_transient_bool(u, name, &t->remain_after_elapse, message, flags, error);
|
||||
|
||||
if (streq(name, "TimersMonotonic")) {
|
||||
const char *base_name;
|
||||
usec_t usec = 0;
|
||||
bool empty = true;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "(st)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_read(message, "(st)", &base_name, &usec)) > 0) {
|
||||
TimerBase b;
|
||||
|
||||
b = timer_base_from_string(base_name);
|
||||
if (b < 0 || b == TIMER_CALENDAR)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid timer base: %s", base_name);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
char ts[FORMAT_TIMESPAN_MAX];
|
||||
TimerValue *v;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", base_name,
|
||||
format_timespan(ts, sizeof(ts), usec, USEC_PER_MSEC));
|
||||
|
||||
v = new0(TimerValue, 1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
v->base = b;
|
||||
v->value = usec;
|
||||
|
||||
LIST_PREPEND(value, t->values, v);
|
||||
}
|
||||
|
||||
empty = false;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
timer_free_values(t);
|
||||
unit_write_setting(u, flags, name, "OnActiveSec=");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "TimersCalendar")) {
|
||||
const char *base_name, *str;
|
||||
bool empty = true;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "(ss)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_read(message, "(ss)", &base_name, &str)) > 0) {
|
||||
_cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
|
||||
TimerBase b;
|
||||
|
||||
b = timer_base_from_string(base_name);
|
||||
if (b != TIMER_CALENDAR)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid timer base: %s", base_name);
|
||||
|
||||
r = calendar_spec_from_string(str, &c);
|
||||
if (r == -EINVAL)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid calendar spec: %s", str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
TimerValue *v;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", base_name, str);
|
||||
|
||||
v = new0(TimerValue, 1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
v->base = b;
|
||||
v->calendar_spec = c;
|
||||
c = NULL;
|
||||
|
||||
LIST_PREPEND(value, t->values, v);
|
||||
}
|
||||
|
||||
empty = false;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
timer_free_values(t);
|
||||
unit_write_setting(u, flags, name, "OnCalendar=");
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name,
|
||||
"OnActiveSec",
|
||||
"OnBootSec",
|
||||
"OnStartupSec",
|
||||
|
@ -196,27 +321,30 @@ static int bus_timer_set_transient_property(
|
|||
|
||||
TimerValue *v;
|
||||
TimerBase b = _TIMER_BASE_INVALID;
|
||||
usec_t u = 0;
|
||||
usec_t usec = 0;
|
||||
|
||||
log_notice("Client is using obsolete %s= transient property, please use TimersMonotonic= instead.", name);
|
||||
|
||||
b = timer_base_from_string(name);
|
||||
if (b < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown timer base");
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u);
|
||||
r = sd_bus_message_read(message, "t", &usec);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
char time[FORMAT_TIMESPAN_MAX];
|
||||
|
||||
unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, format_timespan(time, sizeof(time), u, USEC_PER_MSEC));
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name,
|
||||
format_timespan(time, sizeof(time), usec, USEC_PER_MSEC));
|
||||
|
||||
v = new0(TimerValue, 1);
|
||||
if (!v)
|
||||
return -ENOMEM;
|
||||
|
||||
v->base = b;
|
||||
v->value = u;
|
||||
v->value = usec;
|
||||
|
||||
LIST_PREPEND(value, t->values, v);
|
||||
}
|
||||
|
@ -226,9 +354,11 @@ static int bus_timer_set_transient_property(
|
|||
} else if (streq(name, "OnCalendar")) {
|
||||
|
||||
TimerValue *v;
|
||||
CalendarSpec *c = NULL;
|
||||
_cleanup_(calendar_spec_freep) CalendarSpec *c = NULL;
|
||||
const char *str;
|
||||
|
||||
log_notice("Client is using obsolete %s= transient property, please use TimersCalendar= instead.", name);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -240,7 +370,7 @@ static int bus_timer_set_transient_property(
|
|||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(UNIT(t), flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str);
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, str);
|
||||
|
||||
v = new0(TimerValue, 1);
|
||||
if (!v) {
|
||||
|
@ -250,61 +380,11 @@ static int bus_timer_set_transient_property(
|
|||
|
||||
v->base = TIMER_CALENDAR;
|
||||
v->calendar_spec = c;
|
||||
c = NULL;
|
||||
|
||||
LIST_PREPEND(value, t->values, v);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "AccuracyUSec", "AccuracySec")) {
|
||||
usec_t u = 0;
|
||||
|
||||
if (streq(name, "AccuracySec"))
|
||||
log_notice("Client is using obsolete AccuracySec= transient property, please use AccuracyUSec= instead.");
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
t->accuracy_usec = u;
|
||||
unit_write_settingf(UNIT(t), flags, name, "AccuracySec=" USEC_FMT "us", u);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "RandomizedDelayUSec")) {
|
||||
usec_t u = 0;
|
||||
|
||||
r = sd_bus_message_read(message, "t", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
t->random_usec = u;
|
||||
unit_write_settingf(UNIT(t), flags, name, "RandomizedDelaySec=" USEC_FMT "us", u);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "WakeSystem", "Persistent", "RemainAfterElapse")) {
|
||||
int b;
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (streq(name, "WakeSystem"))
|
||||
t->wake_system = b;
|
||||
else if (streq(name, "Persistent"))
|
||||
t->persistent = b;
|
||||
else /* RemainAfterElapse */
|
||||
t->remain_after_elapse = b;
|
||||
|
||||
unit_write_settingf(UNIT(t), flags, name, "%s=%s", name, yes_no(b));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,15 @@
|
|||
#include "bpf-firewall.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "condition.h"
|
||||
#include "dbus-job.h"
|
||||
#include "dbus-unit.h"
|
||||
#include "dbus-util.h"
|
||||
#include "dbus.h"
|
||||
#include "fd-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-access.h"
|
||||
#include "signal-util.h"
|
||||
|
@ -37,6 +40,7 @@
|
|||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "user-util.h"
|
||||
#include "web-util.h"
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
|
||||
|
@ -795,7 +799,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
|||
SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
@ -823,6 +827,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
|||
SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_obsolete_dependencies, 0, SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
||||
SD_BUS_VTABLE_END
|
||||
};
|
||||
|
||||
|
@ -1352,6 +1357,81 @@ static int bus_unit_set_live_property(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string);
|
||||
static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string);
|
||||
|
||||
static int bus_set_transient_conditions(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
Condition **list,
|
||||
bool is_condition,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
const char *type_name, *param;
|
||||
int trigger, negate, r;
|
||||
bool empty = true;
|
||||
|
||||
assert(list);
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "(sbbs)");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
while ((r = sd_bus_message_read(message, "(sbbs)", &type_name, &trigger, &negate, ¶m)) > 0) {
|
||||
ConditionType t;
|
||||
|
||||
t = is_condition ? condition_type_from_string(type_name) : assert_type_from_string(type_name);
|
||||
if (t < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name);
|
||||
|
||||
if (t != CONDITION_NULL) {
|
||||
if (isempty(param))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
|
||||
|
||||
if (condition_takes_path(t) && !path_is_absolute(param))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
|
||||
} else
|
||||
param = NULL;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
Condition *c;
|
||||
|
||||
c = condition_new(t, param, trigger, negate);
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
LIST_PREPEND(conditions, *list, c);
|
||||
|
||||
if (t != CONDITION_NULL)
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
|
||||
"%s=%s%s%s", type_name,
|
||||
trigger ? "|" : "", negate ? "!" : "", param);
|
||||
else
|
||||
unit_write_settingf(u, flags, name,
|
||||
"%s=%s%s", type_name,
|
||||
trigger ? "|" : "", yes_no(!negate));
|
||||
}
|
||||
|
||||
empty = false;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_exit_container(message);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
|
||||
*list = condition_free_list(*list);
|
||||
unit_write_settingf(u, flags, name, "%sNull=", is_condition ? "Condition" : "Assert");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int bus_unit_set_transient_property(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
|
@ -1359,6 +1439,7 @@ static int bus_unit_set_transient_property(
|
|||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
UnitDependency d = _UNIT_DEPENDENCY_INVALID;
|
||||
int r;
|
||||
|
||||
assert(u);
|
||||
|
@ -1368,35 +1449,100 @@ static int bus_unit_set_transient_property(
|
|||
/* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
|
||||
* has been created. */
|
||||
|
||||
if (streq(name, "DefaultDependencies")) {
|
||||
int b;
|
||||
if (streq(name, "SourcePath"))
|
||||
return bus_set_transient_path(u, name, &u->source_path, message, flags, error);
|
||||
|
||||
r = sd_bus_message_read(message, "b", &b);
|
||||
if (streq(name, "StopWhenUnneeded"))
|
||||
return bus_set_transient_bool(u, name, &u->stop_when_unneeded, message, flags, error);
|
||||
|
||||
if (streq(name, "RefuseManualStart"))
|
||||
return bus_set_transient_bool(u, name, &u->refuse_manual_start, message, flags, error);
|
||||
|
||||
if (streq(name, "RefuseManualStop"))
|
||||
return bus_set_transient_bool(u, name, &u->refuse_manual_stop, message, flags, error);
|
||||
|
||||
if (streq(name, "AllowIsolate"))
|
||||
return bus_set_transient_bool(u, name, &u->allow_isolate, message, flags, error);
|
||||
|
||||
if (streq(name, "DefaultDependencies"))
|
||||
return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error);
|
||||
|
||||
if (streq(name, "OnFailureJobMode"))
|
||||
return bus_set_transient_job_mode(u, name, &u->on_failure_job_mode, message, flags, error);
|
||||
|
||||
if (streq(name, "IgnoreOnIsolate"))
|
||||
return bus_set_transient_bool(u, name, &u->ignore_on_isolate, message, flags, error);
|
||||
|
||||
if (streq(name, "JobTimeoutUSec")) {
|
||||
r = bus_set_transient_usec_fix_0(u, name, &u->job_timeout, message, flags, error);
|
||||
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags) && !u->job_running_timeout_set)
|
||||
u->job_running_timeout = u->job_timeout;
|
||||
}
|
||||
|
||||
if (streq(name, "JobRunningTimeoutUSec")) {
|
||||
r = bus_set_transient_usec_fix_0(u, name, &u->job_running_timeout, message, flags, error);
|
||||
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
|
||||
u->job_running_timeout_set = true;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
if (streq(name, "JobTimeoutAction"))
|
||||
return bus_set_transient_emergency_action(u, name, &u->job_timeout_action, message, flags, error);
|
||||
|
||||
if (streq(name, "JobTimeoutRebootArgument"))
|
||||
return bus_set_transient_string(u, name, &u->job_timeout_reboot_arg, message, flags, error);
|
||||
|
||||
if (streq(name, "StartLimitIntervalUSec"))
|
||||
return bus_set_transient_usec(u, name, &u->start_limit.interval, message, flags, error);
|
||||
|
||||
if (streq(name, "StartLimitBurst"))
|
||||
return bus_set_transient_unsigned(u, name, &u->start_limit.burst, message, flags, error);
|
||||
|
||||
if (streq(name, "StartLimitAction"))
|
||||
return bus_set_transient_emergency_action(u, name, &u->start_limit_action, message, flags, error);
|
||||
|
||||
if (streq(name, "FailureAction"))
|
||||
return bus_set_transient_emergency_action(u, name, &u->failure_action, message, flags, error);
|
||||
|
||||
if (streq(name, "SuccessAction"))
|
||||
return bus_set_transient_emergency_action(u, name, &u->success_action, message, flags, error);
|
||||
|
||||
if (streq(name, "RebootArgument"))
|
||||
return bus_set_transient_string(u, name, &u->reboot_arg, message, flags, error);
|
||||
|
||||
if (streq(name, "CollectMode"))
|
||||
return bus_set_transient_collect_mode(u, name, &u->collect_mode, message, flags, error);
|
||||
|
||||
if (streq(name, "Conditions"))
|
||||
return bus_set_transient_conditions(u, name, &u->conditions, true, message, flags, error);
|
||||
|
||||
if (streq(name, "Asserts"))
|
||||
return bus_set_transient_conditions(u, name, &u->asserts, false, message, flags, error);
|
||||
|
||||
if (streq(name, "Documentation")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char **p;
|
||||
|
||||
r = sd_bus_message_read_strv(message, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
u->default_dependencies = b;
|
||||
unit_write_settingf(u, flags, name, "DefaultDependencies=%s", yes_no(b));
|
||||
STRV_FOREACH(p, l) {
|
||||
if (!documentation_url_is_valid(*p))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid URL in %s: %s", name, *p);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "CollectMode")) {
|
||||
const char *s;
|
||||
CollectMode m;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m = collect_mode_from_string(s);
|
||||
if (m < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown garbage collection mode: %s", s);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
u->collect_mode = m;
|
||||
unit_write_settingf(u, flags, name, "CollectMode=%s", collect_mode_to_string(m));
|
||||
if (strv_isempty(l)) {
|
||||
u->documentation = strv_free(u->documentation);
|
||||
unit_write_settingf(u, flags, name, "%s=", name);
|
||||
} else {
|
||||
strv_extend_strv(&u->documentation, l, false);
|
||||
|
||||
STRV_FOREACH(p, l)
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1439,30 +1585,40 @@ static int bus_unit_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name,
|
||||
"Requires", "RequiresOverridable",
|
||||
"Requisite", "RequisiteOverridable",
|
||||
"Wants",
|
||||
"BindsTo",
|
||||
"Conflicts",
|
||||
"Before", "After",
|
||||
"OnFailure",
|
||||
"PropagatesReloadTo", "ReloadPropagatedFrom",
|
||||
"PartOf")) {
|
||||
} else if (streq(name, "RequiresMountsFor")) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
char **p;
|
||||
|
||||
UnitDependency d;
|
||||
const char *other;
|
||||
r = sd_bus_message_read_strv(message, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (streq(name, "RequiresOverridable"))
|
||||
d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
|
||||
else if (streq(name, "RequisiteOverridable"))
|
||||
d = UNIT_REQUISITE; /* same here */
|
||||
else {
|
||||
d = unit_dependency_from_string(name);
|
||||
if (d < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit dependency: %s", name);
|
||||
STRV_FOREACH(p, l) {
|
||||
if (!path_is_absolute(*p))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
|
||||
if (r < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p);
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, *p);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (streq(name, "RequiresOverridable"))
|
||||
d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
|
||||
else if (streq(name, "RequisiteOverridable"))
|
||||
d = UNIT_REQUISITE; /* same here */
|
||||
else
|
||||
d = unit_dependency_from_string(name);
|
||||
|
||||
if (d >= 0) {
|
||||
const char *other;
|
||||
|
||||
r = sd_bus_message_enter_container(message, 'a', "s");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -1482,7 +1638,7 @@ static int bus_unit_set_transient_property(
|
|||
if (!label)
|
||||
return -ENOMEM;
|
||||
|
||||
unit_write_settingf(u, flags, label, "%s=%s", name, other);
|
||||
unit_write_settingf(u, flags, label, "%s=%s", unit_dependency_to_string(d), other);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1495,30 +1651,6 @@ static int bus_unit_set_transient_property(
|
|||
|
||||
return 1;
|
||||
|
||||
} else if (STR_IN_SET(name, "FailureAction", "SuccessAction")) {
|
||||
EmergencyAction action;
|
||||
const char *s;
|
||||
|
||||
r = sd_bus_message_read(message, "s", &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
action = emergency_action_from_string(s);
|
||||
if (action < 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid emergency action: %s", s);
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
|
||||
if (streq(name, "FailureAction"))
|
||||
u->failure_action = action;
|
||||
else
|
||||
u->success_action = action;
|
||||
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, emergency_action_to_string(action));
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
} else if (streq(name, "AddRef")) {
|
||||
|
||||
int b;
|
||||
|
|
119
src/core/dbus-util.c
Normal file
119
src/core/dbus-util.c
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "bus-util.h"
|
||||
#include "dbus-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "unit-printf.h"
|
||||
#include "user-util.h"
|
||||
#include "unit.h"
|
||||
|
||||
BUS_DEFINE_SET_TRANSIENT(mode_t, "u", uint32_t, mode_t, "%040o");
|
||||
BUS_DEFINE_SET_TRANSIENT(unsigned, "u", uint32_t, unsigned, "%" PRIu32);
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(user, valid_user_group_name_or_id);
|
||||
BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(path, path_is_absolute);
|
||||
|
||||
int bus_set_transient_string(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
char **p,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
const char *v;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
|
||||
r = sd_bus_message_read(message, "s", &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
r = free_and_strdup(p, empty_to_null(v));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
|
||||
"%s=%s", name, strempty(v));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bus_set_transient_bool(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
bool *p,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
int v, r;
|
||||
|
||||
assert(p);
|
||||
|
||||
r = sd_bus_message_read(message, "b", &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
*p = v;
|
||||
unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bus_set_transient_usec_internal(
|
||||
Unit *u,
|
||||
const char *name,
|
||||
usec_t *p,
|
||||
bool fix_0,
|
||||
sd_bus_message *message,
|
||||
UnitWriteFlags flags,
|
||||
sd_bus_error *error) {
|
||||
|
||||
usec_t v;
|
||||
int r;
|
||||
|
||||
assert(p);
|
||||
|
||||
r = sd_bus_message_read(message, "u", &v);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
char *n, ts[FORMAT_TIMESPAN_MAX];
|
||||
|
||||
if (fix_0)
|
||||
*p = v ?: USEC_INFINITY;
|
||||
else
|
||||
*p = v;
|
||||
|
||||
n = strndupa(name, strlen(name) - 4);
|
||||
unit_write_settingf(u, flags, name, "%sSec=%s", n,
|
||||
format_timespan(ts, sizeof(ts), v, USEC_PER_MSEC));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
351
src/core/dbus-util.h
Normal file
351
src/core/dbus-util.h
Normal file
|
@ -0,0 +1,351 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2010 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "unit.h"
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT(function, bus_type, type, cast_type, fmt) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
cast_type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, bus_type, &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = (cast_type) v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=" fmt, name, v); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_IS_VALID(function, bus_type, type, cast_type, fmt, check) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
cast_type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, bus_type, &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
if (!check(v)) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: " fmt, name, v); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = (cast_type) v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=" fmt, name, v); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_TO_STRING(function, bus_type, type, cast_type, fmt, to_string) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
cast_type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
const char *s; \
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, bus_type, &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
s = to_string(v); \
|
||||
if (!s) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: " fmt, name, v); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = (cast_type) v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=%s", name, s); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(function, bus_type, type, cast_type, fmt, to_string) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
cast_type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
_cleanup_free_ char *s = NULL; \
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, bus_type, &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
r = to_string(v, &s); \
|
||||
if (r == -EINVAL) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: " fmt, name, v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = (cast_type) v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=%s", name, s); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_PARSE(function, type, parse) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
const char *s; \
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, "s", &s); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
v = parse(s); \
|
||||
if (v < 0) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: %s", name, s); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=%s", name, s); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(function, type, parse) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
type *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
const char *s; \
|
||||
type v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, "s", &s); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
r = parse(s, &v); \
|
||||
if (r < 0) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: %s", name, s); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = v; \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=%s", name, strempty(s)); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(function, check) \
|
||||
int bus_set_transient_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
char **p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
const char *v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, "s", &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
if (!isempty(v) && !check(v)) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Invalid %s setting: %s", name, v); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
r = free_and_strdup(p, empty_to_null(v)); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, \
|
||||
"%s=%s", name, strempty(v)); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val, str) \
|
||||
int bus_cgroup_set_##function( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
uint64_t *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
uint64_t v; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, "t", &v); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
if (!check(v)) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Value specified in %s is out of range", name); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
*p = v; \
|
||||
unit_invalidate_cgroup(u, (mask)); \
|
||||
\
|
||||
if (v == (val)) \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=" str, name); \
|
||||
else \
|
||||
unit_write_settingf(u, flags, name, \
|
||||
"%s=%" PRIu64, name, v); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define BUS_DEFINE_SET_CGROUP_SCALE(function, mask, scale) \
|
||||
int bus_cgroup_set_##function##_scale( \
|
||||
Unit *u, \
|
||||
const char *name, \
|
||||
uint64_t *p, \
|
||||
sd_bus_message *message, \
|
||||
UnitWriteFlags flags, \
|
||||
sd_bus_error *error) { \
|
||||
\
|
||||
uint64_t v; \
|
||||
uint32_t raw; \
|
||||
int r; \
|
||||
\
|
||||
assert(p); \
|
||||
\
|
||||
r = sd_bus_message_read(message, "u", &raw); \
|
||||
if (r < 0) \
|
||||
return r; \
|
||||
\
|
||||
v = scale(raw, UINT32_MAX); \
|
||||
if (v <= 0 || v >= UINT64_MAX) \
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
|
||||
"Value specified in %s is out of range", name); \
|
||||
\
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
|
||||
const char *e; \
|
||||
\
|
||||
*p = v; \
|
||||
unit_invalidate_cgroup(u, (mask)); \
|
||||
\
|
||||
/* Chop off suffix */ \
|
||||
assert_se(e = endswith(name, "Scale")); \
|
||||
name = strndupa(name, e - name); \
|
||||
\
|
||||
unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \
|
||||
(uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
|
||||
} \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
int bus_set_transient_mode_t(Unit *u, const char *name, mode_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_unsigned(Unit *u, const char *name, unsigned *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_user(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_path(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_string(Unit *u, const char *name, char **p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_bool(Unit *u, const char *name, bool *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
int bus_set_transient_usec_internal(Unit *u, const char *name, usec_t *p, bool fix_0, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error);
|
||||
static inline int bus_set_transient_usec(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
|
||||
return bus_set_transient_usec_internal(u, name, p, false, message, flags, error);
|
||||
}
|
||||
static inline int bus_set_transient_usec_fix_0(Unit *u, const char *name, usec_t *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) {
|
||||
return bus_set_transient_usec_internal(u, name, p, true, message, flags, error);
|
||||
}
|
|
@ -214,6 +214,7 @@ Unit.RefuseManualStop, config_parse_bool, 0,
|
|||
Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate)
|
||||
Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies)
|
||||
Unit.OnFailureJobMode, config_parse_job_mode, 0, offsetof(Unit, on_failure_job_mode)
|
||||
m4_dnl The following is a legacy alias name for compatibility
|
||||
Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0, offsetof(Unit, on_failure_job_mode)
|
||||
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
|
||||
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
|
|
|
@ -497,19 +497,13 @@ int config_parse_socket_bind(const char *unit,
|
|||
|
||||
s = SOCKET(data);
|
||||
|
||||
b = socket_address_bind_ipv6_only_from_string(rvalue);
|
||||
b = parse_socket_address_bind_ipv6_only_or_bool(rvalue);
|
||||
if (b < 0) {
|
||||
int r;
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse bind IPv6 only value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
s->bind_ipv6_only = r ? SOCKET_ADDRESS_IPV6_ONLY : SOCKET_ADDRESS_BOTH;
|
||||
} else
|
||||
s->bind_ipv6_only = b;
|
||||
s->bind_ipv6_only = b;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -3955,6 +3949,8 @@ int config_parse_job_mode_isolate(
|
|||
return 0;
|
||||
}
|
||||
|
||||
log_notice("%s is deprecated. Please use OnFailureJobMode= instead", lvalue);
|
||||
|
||||
*m = r ? JOB_ISOLATE : JOB_REPLACE;
|
||||
return 0;
|
||||
}
|
||||
|
@ -4365,7 +4361,7 @@ int config_parse_protect_home(
|
|||
void *userdata) {
|
||||
|
||||
ExecContext *c = data;
|
||||
int k;
|
||||
ProtectHome h;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
|
@ -4375,23 +4371,14 @@ int config_parse_protect_home(
|
|||
/* Our enum shall be a superset of booleans, hence first try
|
||||
* to parse as boolean, and then as enum */
|
||||
|
||||
k = parse_boolean(rvalue);
|
||||
if (k > 0)
|
||||
c->protect_home = PROTECT_HOME_YES;
|
||||
else if (k == 0)
|
||||
c->protect_home = PROTECT_HOME_NO;
|
||||
else {
|
||||
ProtectHome h;
|
||||
|
||||
h = protect_home_from_string(rvalue);
|
||||
if (h < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->protect_home = h;
|
||||
h = parse_protect_home_or_bool(rvalue);
|
||||
if (h < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect home value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->protect_home = h;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4408,7 +4395,7 @@ int config_parse_protect_system(
|
|||
void *userdata) {
|
||||
|
||||
ExecContext *c = data;
|
||||
int k;
|
||||
ProtectSystem s;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
|
@ -4418,23 +4405,14 @@ int config_parse_protect_system(
|
|||
/* Our enum shall be a superset of booleans, hence first try
|
||||
* to parse as boolean, and then as enum */
|
||||
|
||||
k = parse_boolean(rvalue);
|
||||
if (k > 0)
|
||||
c->protect_system = PROTECT_SYSTEM_YES;
|
||||
else if (k == 0)
|
||||
c->protect_system = PROTECT_SYSTEM_NO;
|
||||
else {
|
||||
ProtectSystem s;
|
||||
|
||||
s = protect_system_from_string(rvalue);
|
||||
if (s < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->protect_system = s;
|
||||
s = parse_protect_system_or_bool(rvalue);
|
||||
if (s < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Failed to parse protect system value, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c->protect_system = s;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,8 @@ libcore_la_sources = '''
|
|||
dbus-timer.h
|
||||
dbus-unit.c
|
||||
dbus-unit.h
|
||||
dbus-util.c
|
||||
dbus-util.h
|
||||
dbus.c
|
||||
dbus.h
|
||||
device.c
|
||||
|
|
|
@ -1450,6 +1450,18 @@ static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
|
|||
|
||||
DEFINE_STRING_TABLE_LOOKUP(protect_home, ProtectHome);
|
||||
|
||||
ProtectHome parse_protect_home_or_bool(const char *s) {
|
||||
int r;
|
||||
|
||||
r = parse_boolean(s);
|
||||
if (r > 0)
|
||||
return PROTECT_HOME_YES;
|
||||
if (r == 0)
|
||||
return PROTECT_HOME_NO;
|
||||
|
||||
return protect_home_from_string(s);
|
||||
}
|
||||
|
||||
static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
|
||||
[PROTECT_SYSTEM_NO] = "no",
|
||||
[PROTECT_SYSTEM_YES] = "yes",
|
||||
|
@ -1459,6 +1471,18 @@ static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
|
|||
|
||||
DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
|
||||
|
||||
ProtectSystem parse_protect_system_or_bool(const char *s) {
|
||||
int r;
|
||||
|
||||
r = parse_boolean(s);
|
||||
if (r > 0)
|
||||
return PROTECT_SYSTEM_YES;
|
||||
if (r == 0)
|
||||
return PROTECT_SYSTEM_NO;
|
||||
|
||||
return protect_system_from_string(s);
|
||||
}
|
||||
|
||||
static const char* const namespace_type_table[] = {
|
||||
[NAMESPACE_MOUNT] = "mnt",
|
||||
[NAMESPACE_CGROUP] = "cgroup",
|
||||
|
|
|
@ -101,9 +101,11 @@ int setup_netns(int netns_storage_socket[2]);
|
|||
|
||||
const char* protect_home_to_string(ProtectHome p) _const_;
|
||||
ProtectHome protect_home_from_string(const char *s) _pure_;
|
||||
ProtectHome parse_protect_home_or_bool(const char *s);
|
||||
|
||||
const char* protect_system_to_string(ProtectSystem p) _const_;
|
||||
ProtectSystem protect_system_from_string(const char *s) _pure_;
|
||||
ProtectSystem parse_protect_system_or_bool(const char *s);
|
||||
|
||||
void bind_mount_free_many(BindMount *b, unsigned n);
|
||||
int bind_mount_add(BindMount **b, unsigned *n, const BindMount *item);
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "bus-util.h"
|
||||
#include "cap-list.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "condition.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "env-util.h"
|
||||
#include "errno-list.h"
|
||||
|
@ -72,62 +73,71 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
|
|||
&u->job_path);
|
||||
}
|
||||
|
||||
#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func) \
|
||||
static int bus_append_##parse_func(sd_bus_message *m, const char *field, const char *eq) { \
|
||||
type val; \
|
||||
int r; \
|
||||
\
|
||||
r = parse_func(eq, &val); \
|
||||
if (r < 0) \
|
||||
return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); \
|
||||
\
|
||||
r = sd_bus_message_append(m, "(sv)", field, bus_type, (cast_type) val); \
|
||||
if (r < 0) \
|
||||
return bus_log_create_error(r); \
|
||||
\
|
||||
return 1; \
|
||||
}
|
||||
#define DEFINE_BUS_APPEND_PARSE_PTR(bus_type, cast_type, type, parse_func) \
|
||||
static int bus_append_##parse_func( \
|
||||
sd_bus_message *m, \
|
||||
const char *field, \
|
||||
const char *eq) { \
|
||||
type val; \
|
||||
int r; \
|
||||
\
|
||||
r = parse_func(eq, &val); \
|
||||
if (r < 0) \
|
||||
return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq); \
|
||||
\
|
||||
r = sd_bus_message_append(m, "(sv)", field, \
|
||||
bus_type, (cast_type) val); \
|
||||
if (r < 0) \
|
||||
return bus_log_create_error(r); \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func) \
|
||||
static int bus_append_##parse_func(sd_bus_message *m, const char *field, const char *eq) { \
|
||||
int r; \
|
||||
\
|
||||
r = parse_func(eq); \
|
||||
if (r < 0) { \
|
||||
log_error("Failed to parse %s: %s", field, eq); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
\
|
||||
r = sd_bus_message_append(m, "(sv)", field, bus_type, (int32_t) r); \
|
||||
if (r < 0) \
|
||||
return bus_log_create_error(r); \
|
||||
\
|
||||
return 1; \
|
||||
}
|
||||
#define DEFINE_BUS_APPEND_PARSE(bus_type, parse_func) \
|
||||
static int bus_append_##parse_func( \
|
||||
sd_bus_message *m, \
|
||||
const char *field, \
|
||||
const char *eq) { \
|
||||
int r; \
|
||||
\
|
||||
r = parse_func(eq); \
|
||||
if (r < 0) { \
|
||||
log_error("Failed to parse %s: %s", field, eq); \
|
||||
return -EINVAL; \
|
||||
} \
|
||||
\
|
||||
r = sd_bus_message_append(m, "(sv)", field, \
|
||||
bus_type, (int32_t) r); \
|
||||
if (r < 0) \
|
||||
return bus_log_create_error(r); \
|
||||
\
|
||||
return 1; \
|
||||
} \
|
||||
struct __useless_struct_to_allow_trailing_semicolon__
|
||||
|
||||
DEFINE_BUS_APPEND_PARSE("b", parse_boolean)
|
||||
DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", log_level_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", parse_errno)
|
||||
DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder)
|
||||
DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, usec_t, parse_sec)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou)
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64)
|
||||
DEFINE_BUS_APPEND_PARSE("b", parse_boolean);
|
||||
DEFINE_BUS_APPEND_PARSE("i", ioprio_class_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", ip_tos_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", log_facility_unshifted_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", log_level_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", parse_errno);
|
||||
DEFINE_BUS_APPEND_PARSE("i", sched_policy_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", secure_bits_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE("i", signal_from_string_try_harder);
|
||||
DEFINE_BUS_APPEND_PARSE("i", socket_protocol_from_name);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, ioprio_parse_priority);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, parse_nice);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("i", int32_t, int, safe_atoi);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, nsec_t, parse_nsec);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_blkio_weight_parse);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_cpu_shares_parse);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, cg_weight_parse);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, unsigned long, mount_propagation_flags_from_string);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("t", uint64_t, uint64_t, safe_atou64);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, mode_t, parse_mode);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("u", uint32_t, unsigned, safe_atou);
|
||||
DEFINE_BUS_APPEND_PARSE_PTR("x", int64_t, int64_t, safe_atoi64);
|
||||
|
||||
static inline int bus_append_string(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r;
|
||||
|
@ -672,6 +682,23 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_automount_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
|
||||
if (streq(field, "Where"))
|
||||
|
||||
return bus_append_string(m, field, eq);
|
||||
|
||||
if (streq(field, "DirectoryMode"))
|
||||
|
||||
return bus_append_parse_mode(m, field, eq);
|
||||
|
||||
if (streq(field, "TimeoutIdleSec"))
|
||||
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_execute_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r, rl;
|
||||
|
||||
|
@ -1128,14 +1155,30 @@ static int bus_append_kill_property(sd_bus_message *m, const char *field, const
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
static int bus_append_mount_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
|
||||
if (STR_IN_SET(field,
|
||||
"PathExists", "PathExistsGlob", "PathChanged",
|
||||
"PathModified", "DirectoryNotEmpty"))
|
||||
if (STR_IN_SET(field, "What", "Where", "Options", "Type"))
|
||||
|
||||
return bus_append_string(m, field, eq);
|
||||
|
||||
if (streq(field, "TimeoutSec"))
|
||||
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
if (streq(field, "DirectoryMode"))
|
||||
|
||||
return bus_append_parse_mode(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field, "SloppyOptions", "LazyUnmount", "ForceUnmount"))
|
||||
|
||||
return bus_append_parse_boolean(m, field, eq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_path_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r;
|
||||
|
||||
if (streq(field, "MakeDirectory"))
|
||||
|
||||
return bus_append_parse_boolean(m, field, eq);
|
||||
|
@ -1144,23 +1187,49 @@ static int bus_append_path_property(sd_bus_message *m, const char *field, const
|
|||
|
||||
return bus_append_parse_mode(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field,
|
||||
"PathExists", "PathExistsGlob", "PathChanged",
|
||||
"PathModified", "DirectoryNotEmpty")) {
|
||||
|
||||
if (isempty(eq))
|
||||
r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 0);
|
||||
else
|
||||
r = sd_bus_message_append(m, "(sv)", "Paths", "a(ss)", 1, field, eq);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_service_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
int r;
|
||||
|
||||
if (STR_IN_SET(field, "Type", "Restart", "NotifyAccess"))
|
||||
if (STR_IN_SET(field,
|
||||
"PIDFile", "Type", "Restart", "BusName", "NotifyAccess",
|
||||
"USBFunctionDescriptors", "USBFunctionStrings"))
|
||||
|
||||
return bus_append_string(m, field, eq);
|
||||
|
||||
if (streq(field, "RemainAfterExit"))
|
||||
if (STR_IN_SET(field, "PermissionsStartOnly", "RootDirectoryStartOnly", "RemainAfterExit", "GuessMainPID"))
|
||||
|
||||
return bus_append_parse_boolean(m, field, eq);
|
||||
|
||||
if (streq(field, "RuntimeMaxSec"))
|
||||
if (STR_IN_SET(field, "RestartSec", "TimeoutStartSec", "TimeoutStopSec", "RuntimeMaxSec", "WatchdogSec"))
|
||||
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
if (streq(field, "TimeoutSec")) {
|
||||
|
||||
r = bus_append_parse_sec_rename(m, "TimeoutStartSec", eq);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return bus_append_parse_sec_rename(m, "TimeoutStopSec", eq);
|
||||
}
|
||||
|
||||
if (streq(field, "FileDescriptorStoreMax"))
|
||||
|
||||
return bus_append_safe_atou(m, field, eq);
|
||||
|
@ -1171,6 +1240,82 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con
|
|||
|
||||
return bus_append_exec_command(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field, "RestartPreventExitStatus", "RestartForceExitStatus", "SuccessExitStatus")) {
|
||||
_cleanup_free_ int *status = NULL, *signal = NULL;
|
||||
size_t sz_status = 0, sz_signal = 0;
|
||||
const char *p;
|
||||
|
||||
for (p = eq;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
int val;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
|
||||
if (r == 0)
|
||||
break;
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Invalid syntax in %s: %s", field, eq);
|
||||
|
||||
r = safe_atoi(word, &val);
|
||||
if (r < 0) {
|
||||
val = signal_from_string_try_harder(word);
|
||||
if (val < 0)
|
||||
return log_error_errno(r, "Invalid status or signal %s in %s: %m", word, field);
|
||||
|
||||
signal = realloc_multiply(signal, sizeof(int), sz_signal + 1);
|
||||
if (!signal)
|
||||
return log_oom();
|
||||
|
||||
signal[sz_signal++] = val;
|
||||
} else {
|
||||
status = realloc_multiply(status, sizeof(int), sz_status + 1);
|
||||
if (!status)
|
||||
return log_oom();
|
||||
|
||||
status[sz_status++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_open_container(m, 'v', "(aiai)");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_open_container(m, 'r', "aiai");
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append_array(m, 'i', status, sz_status);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_append_array(m, 'i', signal, sz_signal);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
r = sd_bus_message_close_container(m);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1234,7 +1379,10 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
|
|||
"ListenStream", "ListenDatagram", "ListenSequentialPacket", "ListenNetlink",
|
||||
"ListenSpecial", "ListenMessageQueue", "ListenFIFO", "ListenUSBFunction")) {
|
||||
|
||||
r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + strlen("Listen"), eq);
|
||||
if (isempty(eq))
|
||||
r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 0);
|
||||
else
|
||||
r = sd_bus_message_append(m, "(sv)", "Listen", "a(ss)", 1, field + strlen("Listen"), eq);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
|
@ -1244,42 +1392,112 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
|
|||
return 0;
|
||||
}
|
||||
static int bus_append_timer_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
|
||||
if (streq(field, "OnCalendar"))
|
||||
|
||||
return bus_append_string(m, field, eq);
|
||||
int r;
|
||||
|
||||
if (STR_IN_SET(field, "WakeSystem", "RemainAfterElapse", "Persistent"))
|
||||
|
||||
return bus_append_parse_boolean(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field,
|
||||
"OnActiveSec", "OnBootSec", "OnStartupSec",
|
||||
"OnUnitActiveSec","OnUnitInactiveSec"))
|
||||
|
||||
return bus_append_parse_sec(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec"))
|
||||
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
if (STR_IN_SET(field,
|
||||
"OnActiveSec", "OnBootSec", "OnStartupSec",
|
||||
"OnUnitActiveSec","OnUnitInactiveSec")) {
|
||||
|
||||
if (isempty(eq))
|
||||
r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 0);
|
||||
else {
|
||||
usec_t t;
|
||||
r = parse_sec(eq, &t);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse %s=%s: %m", field, eq);
|
||||
|
||||
r = sd_bus_message_append(m, "(sv)", "TimersMonotonic", "a(st)", 1, field, t);
|
||||
}
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (streq(field, "OnCalendar")) {
|
||||
|
||||
if (isempty(eq))
|
||||
r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 0);
|
||||
else
|
||||
r = sd_bus_message_append(m, "(sv)", "TimersCalendar", "a(ss)", 1, field, eq);
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_append_unit_property(sd_bus_message *m, const char *field, const char *eq) {
|
||||
ConditionType t = _CONDITION_TYPE_INVALID;
|
||||
bool is_condition = false;
|
||||
int r;
|
||||
|
||||
if (STR_IN_SET(field, "Description", "CollectMode", "FailureAction", "SuccessAction"))
|
||||
if (STR_IN_SET(field,
|
||||
"Description", "SourcePath", "OnFailureJobMode",
|
||||
"JobTimeoutAction", "JobTimeoutRebootArgument",
|
||||
"StartLimitAction", "FailureAction", "SuccessAction",
|
||||
"RebootArgument", "CollectMode"))
|
||||
|
||||
return bus_append_string(m, field, eq);
|
||||
|
||||
if (streq(field, "DefaultDependencies"))
|
||||
if (STR_IN_SET(field,
|
||||
"StopWhenUnneeded", "RefuseManualStart", "RefuseManualStop",
|
||||
"AllowIsolate", "IgnoreOnIsolate", "DefaultDependencies"))
|
||||
|
||||
return bus_append_parse_boolean(m, field, eq);
|
||||
|
||||
if (unit_dependency_from_string(field) >= 0)
|
||||
if (STR_IN_SET(field, "JobTimeoutSec", "JobRunningTimeoutSec", "StartLimitIntervalSec"))
|
||||
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
if (streq(field, "StartLimitBurst"))
|
||||
|
||||
return bus_append_safe_atou(m, field, eq);
|
||||
|
||||
if (unit_dependency_from_string(field) >= 0 ||
|
||||
STR_IN_SET(field, "Documentation", "RequiresMountsFor"))
|
||||
|
||||
return bus_append_strv(m, field, eq, EXTRACT_QUOTES);
|
||||
|
||||
t = condition_type_from_string(field);
|
||||
if (t >= 0)
|
||||
is_condition = true;
|
||||
else
|
||||
t = assert_type_from_string(field);
|
||||
if (t >= 0) {
|
||||
if (isempty(eq))
|
||||
r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 0);
|
||||
else {
|
||||
const char *p = eq;
|
||||
int trigger, negate;
|
||||
|
||||
trigger = *p == '|';
|
||||
if (trigger)
|
||||
p++;
|
||||
|
||||
negate = *p == '!';
|
||||
if (negate)
|
||||
p++;
|
||||
|
||||
r = sd_bus_message_append(m, "(sv)", is_condition ? "Conditions" : "Asserts", "a(sbbs)", 1,
|
||||
field, trigger, negate, p);
|
||||
}
|
||||
if (r < 0)
|
||||
return bus_log_create_error(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1573,10 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
|
|||
break;
|
||||
|
||||
case UNIT_SCOPE:
|
||||
|
||||
if (streq(field, "TimeoutStopSec"))
|
||||
return bus_append_parse_sec_rename(m, field, eq);
|
||||
|
||||
r = bus_append_cgroup_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
@ -1365,7 +1587,29 @@ int bus_append_unit_property_assignment(sd_bus_message *m, UnitType t, const cha
|
|||
break;
|
||||
|
||||
case UNIT_MOUNT:
|
||||
r = bus_append_cgroup_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = bus_append_execute_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = bus_append_kill_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = bus_append_mount_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case UNIT_AUTOMOUNT:
|
||||
r = bus_append_automount_property(m, field, eq);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case UNIT_TARGET:
|
||||
|
|
|
@ -99,3 +99,17 @@ ConditionType assert_type_from_string(const char *s) _pure_;
|
|||
|
||||
const char* condition_result_to_string(ConditionResult r) _const_;
|
||||
ConditionResult condition_result_from_string(const char *s) _pure_;
|
||||
|
||||
static inline bool condition_takes_path(ConditionType t) {
|
||||
return IN_SET(t,
|
||||
CONDITION_PATH_EXISTS,
|
||||
CONDITION_PATH_EXISTS_GLOB,
|
||||
CONDITION_PATH_IS_DIRECTORY,
|
||||
CONDITION_PATH_IS_SYMBOLIC_LINK,
|
||||
CONDITION_PATH_IS_MOUNT_POINT,
|
||||
CONDITION_PATH_IS_READ_WRITE,
|
||||
CONDITION_DIRECTORY_NOT_EMPTY,
|
||||
CONDITION_FILE_NOT_EMPTY,
|
||||
CONDITION_FILE_IS_EXECUTABLE,
|
||||
CONDITION_NEEDS_UPDATE);
|
||||
}
|
||||
|
|
|
@ -42,6 +42,13 @@ unsigned long namespace_flag_from_string(const char *name);
|
|||
int namespace_flag_from_string_many(const char *name, unsigned long *ret);
|
||||
int namespace_flag_to_string_many(unsigned long flags, char **ret);
|
||||
|
||||
static inline int namespace_flag_to_string_many_with_check(unsigned long n, char **s) {
|
||||
if ((n & NAMESPACE_FLAGS_ALL) != n)
|
||||
return -EINVAL;
|
||||
|
||||
return namespace_flag_to_string_many(n, s);
|
||||
}
|
||||
|
||||
struct namespace_flag_map {
|
||||
unsigned long flag;
|
||||
const char *name;
|
||||
|
|
Loading…
Reference in a new issue