2020-11-09 05:23:58 +01:00
|
|
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
2010-04-18 03:08:16 +02:00
|
|
|
|
2019-03-27 11:32:41 +01:00
|
|
|
#include <fcntl.h>
|
2017-12-11 19:50:30 +01:00
|
|
|
|
2015-10-27 03:01:06 +01:00
|
|
|
#include "alloc-util.h"
|
2015-10-07 23:07:39 +02:00
|
|
|
#include "async.h"
|
2020-06-28 16:43:29 +02:00
|
|
|
#include "bus-get-properties.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "dbus-cgroup.h"
|
2010-04-18 03:08:16 +02:00
|
|
|
#include "dbus-execute.h"
|
2012-07-19 23:47:10 +02:00
|
|
|
#include "dbus-kill.h"
|
2019-03-19 19:05:19 +01:00
|
|
|
#include "dbus-manager.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "dbus-service.h"
|
2018-01-01 17:40:06 +01:00
|
|
|
#include "dbus-util.h"
|
|
|
|
#include "exit-status.h"
|
2015-10-25 13:14:12 +01:00
|
|
|
#include "fd-util.h"
|
2015-10-26 18:05:03 +01:00
|
|
|
#include "fileio.h"
|
2018-01-01 17:40:06 +01:00
|
|
|
#include "parse-util.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "path-util.h"
|
|
|
|
#include "service.h"
|
2018-01-01 17:40:06 +01:00
|
|
|
#include "signal-util.h"
|
2015-10-24 22:58:24 +02:00
|
|
|
#include "string-util.h"
|
|
|
|
#include "strv.h"
|
|
|
|
#include "unit.h"
|
2013-11-19 21:12:59 +01:00
|
|
|
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType);
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
|
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess);
|
2016-10-20 15:27:37 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
|
2019-04-14 13:45:31 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET(property_get_timeout_abort_usec, "t", Service, service_timeout_abort_usec);
|
2020-05-26 15:35:18 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET(property_get_watchdog_usec, "t", Service, service_get_watchdog_usec);
|
2019-04-16 16:45:20 +02:00
|
|
|
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_timeout_failure_mode, service_timeout_failure_mode, ServiceTimeoutFailureMode);
|
2017-11-29 07:43:44 +01:00
|
|
|
|
2018-01-02 18:32:10 +01:00
|
|
|
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) {
|
|
|
|
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
const ExitStatusSet *status_set = userdata;
|
|
|
|
unsigned n;
|
2018-01-02 18:32:10 +01:00
|
|
|
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;
|
|
|
|
|
2020-09-08 11:58:29 +02:00
|
|
|
BITMAP_FOREACH(n, &status_set->status) {
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
assert(n < 256);
|
2018-01-02 18:32:10 +01:00
|
|
|
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
r = sd_bus_message_append_basic(reply, 'i', &n);
|
2018-01-02 18:32:10 +01:00
|
|
|
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;
|
|
|
|
|
2020-09-08 11:58:29 +02:00
|
|
|
BITMAP_FOREACH(n, &status_set->signal) {
|
2018-01-02 18:32:10 +01:00
|
|
|
const char *str;
|
|
|
|
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
str = signal_to_string(n);
|
2018-01-02 18:32:10 +01:00
|
|
|
if (!str)
|
|
|
|
continue;
|
|
|
|
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
r = sd_bus_message_append_basic(reply, 'i', &n);
|
2018-01-02 18:32:10 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = sd_bus_message_close_container(reply);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
return sd_bus_message_close_container(reply);
|
|
|
|
}
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
const sd_bus_vtable bus_service_vtable[] = {
|
|
|
|
SD_BUS_VTABLE_START(0),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
2017-11-29 07:43:44 +01:00
|
|
|
SD_BUS_PROPERTY("TimeoutAbortUSec", "t", property_get_timeout_abort_usec, 0, 0),
|
2019-04-16 16:45:20 +02:00
|
|
|
SD_BUS_PROPERTY("TimeoutStartFailureMode", "s", property_get_timeout_failure_mode, offsetof(Service, timeout_start_failure_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("TimeoutStopFailureMode", "s", property_get_timeout_failure_mode, offsetof(Service, timeout_stop_failure_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec, offsetof(Service, runtime_max_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
2020-05-26 15:35:18 +02:00
|
|
|
SD_BUS_PROPERTY("WatchdogUSec", "t", property_get_watchdog_usec, 0, 0),
|
2013-11-19 21:12:59 +01:00
|
|
|
BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service, watchdog_timestamp), 0),
|
2018-11-16 14:30:29 +01:00
|
|
|
SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool, offsetof(Service, permissions_start_only), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* 😷 deprecated */
|
2013-12-22 02:24:05 +01:00
|
|
|
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),
|
2018-01-02 18:32:10 +01:00
|
|
|
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),
|
2013-11-19 21:12:59 +01:00
|
|
|
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),
|
2013-12-22 02:24:05 +01:00
|
|
|
SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST),
|
2015-11-02 23:09:06 +01:00
|
|
|
SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("NFileDescriptorStore", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store), 0),
|
2013-11-19 21:12:59 +01:00
|
|
|
SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2018-05-10 16:02:57 +02:00
|
|
|
SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2013-11-19 21:12:59 +01:00
|
|
|
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2019-04-01 18:39:25 +02:00
|
|
|
SD_BUS_PROPERTY("ReloadResult", "s", property_get_result, offsetof(Service, reload_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2019-04-01 18:52:40 +02:00
|
|
|
SD_BUS_PROPERTY("CleanResult", "s", property_get_result, offsetof(Service, clean_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2018-11-27 20:08:03 +01:00
|
|
|
SD_BUS_PROPERTY("USBFunctionDescriptors", "s", NULL, offsetof(Service, usb_function_descriptors), SD_BUS_VTABLE_PROPERTY_CONST),
|
|
|
|
SD_BUS_PROPERTY("USBFunctionStrings", "s", NULL, offsetof(Service, usb_function_strings), SD_BUS_VTABLE_PROPERTY_CONST),
|
2018-05-10 16:02:57 +02:00
|
|
|
SD_BUS_PROPERTY("UID", "u", bus_property_get_uid, offsetof(Unit, ref_uid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
|
|
|
SD_BUS_PROPERTY("GID", "u", bus_property_get_gid, offsetof(Unit, ref_gid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2017-08-09 21:12:55 +02:00
|
|
|
SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned, offsetof(Service, n_restarts), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2019-03-19 19:05:19 +01:00
|
|
|
SD_BUS_PROPERTY("OOMPolicy", "s", bus_property_get_oom_policy, offsetof(Service, oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
|
2016-08-01 19:24:40 +02:00
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
2019-06-29 02:02:30 +02:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecCondition", offsetof(Service, exec_command[SERVICE_EXEC_CONDITION]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-08-21 02:39:38 +02:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecConditionEx", offsetof(Service, exec_command[SERVICE_EXEC_CONDITION]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-02-20 23:53:58 +01:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPreEx", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-02-20 23:53:58 +01:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartEx", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-02-20 23:53:58 +01:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPostEx", offsetof(Service, exec_command[SERVICE_EXEC_START_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-08-21 02:39:38 +02:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecReloadEx", offsetof(Service, exec_command[SERVICE_EXEC_RELOAD]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-08-21 02:39:38 +02:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopEx", offsetof(Service, exec_command[SERVICE_EXEC_STOP]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2013-12-22 02:24:05 +01:00
|
|
|
BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2019-08-21 02:39:38 +02:00
|
|
|
BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopPostEx", offsetof(Service, exec_command[SERVICE_EXEC_STOP_POST]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
|
2016-08-01 17:40:37 +02:00
|
|
|
|
|
|
|
/* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
|
2019-09-19 17:45:41 +02:00
|
|
|
SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
|
|
|
SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
2016-10-20 15:27:37 +02:00
|
|
|
SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
2017-11-16 15:02:56 +01:00
|
|
|
SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
2016-08-01 17:40:37 +02:00
|
|
|
SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
|
2013-11-19 21:12:59 +01:00
|
|
|
SD_BUS_VTABLE_END
|
2012-01-16 00:23:59 +01:00
|
|
|
};
|
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
static int bus_set_transient_exit_status(
|
|
|
|
Unit *u,
|
2013-06-28 04:12:58 +02:00
|
|
|
const char *name,
|
2018-01-01 17:40:06 +01:00
|
|
|
ExitStatusSet *status_set,
|
2013-11-19 21:12:59 +01:00
|
|
|
sd_bus_message *message,
|
2017-11-22 15:03:51 +01:00
|
|
|
UnitWriteFlags flags,
|
2013-11-19 21:12:59 +01:00
|
|
|
sd_bus_error *error) {
|
2013-06-28 04:12:58 +02:00
|
|
|
|
2019-03-02 16:35:58 +01:00
|
|
|
const int32_t *status, *signal;
|
2019-07-28 11:55:49 +02:00
|
|
|
size_t n_status, n_signal, i;
|
2013-06-28 04:12:58 +02:00
|
|
|
int r;
|
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
r = sd_bus_message_enter_container(message, 'r', "aiai");
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2013-06-28 04:12:58 +02:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
r = sd_bus_message_read_array(message, 'i', (const void **) &status, &n_status);
|
2018-01-01 17:40:06 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2017-11-22 15:03:51 +01:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
r = sd_bus_message_read_array(message, 'i', (const void **) &signal, &n_signal);
|
2018-01-01 17:40:06 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2013-07-26 16:09:25 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
r = sd_bus_message_exit_container(message);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2013-07-26 16:09:25 +02:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
n_status /= sizeof(int32_t);
|
|
|
|
n_signal /= sizeof(int32_t);
|
2019-03-02 16:35:58 +01:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
if (n_status == 0 && n_signal == 0 && !UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2018-01-01 17:40:06 +01:00
|
|
|
exit_status_set_free(status_set);
|
|
|
|
unit_write_settingf(u, flags, name, "%s=", name);
|
2013-07-26 16:09:25 +02:00
|
|
|
return 1;
|
2018-01-01 17:40:06 +01:00
|
|
|
}
|
2013-07-26 16:09:25 +02:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
for (i = 0; i < n_status; i++) {
|
2018-01-01 17:40:06 +01:00
|
|
|
if (status[i] < 0 || status[i] > 255)
|
2019-03-02 16:35:58 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid status code in %s: %"PRIi32, name, status[i]);
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
r = bitmap_set(&status_set->status, status[i]);
|
2018-01-01 17:40:06 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2019-03-02 16:35:58 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%"PRIi32, name, status[i]);
|
2014-02-05 02:02:00 +01:00
|
|
|
}
|
2018-01-01 17:40:06 +01:00
|
|
|
}
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2019-07-28 11:55:49 +02:00
|
|
|
for (i = 0; i < n_signal; i++) {
|
2018-01-01 17:40:06 +01:00
|
|
|
const char *str;
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
|
2019-03-02 16:35:58 +01:00
|
|
|
str = signal_to_string((int) signal[i]);
|
2018-01-01 17:40:06 +01:00
|
|
|
if (!str)
|
2019-03-02 16:35:58 +01:00
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal in %s: %"PRIi32, name, signal[i]);
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
shared/exit-status: use Bitmap instead of Sets
I opted to embed the Bitmap structure directly in the ExitStatusSet.
This means that memory usage is a bit higher for units which don't define
this setting:
Service changes:
/* size: 2720, cachelines: 43, members: 73 */
/* sum members: 2680, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
/* last cacheline: 32 bytes */
/* size: 2816, cachelines: 44, members: 73 */
/* sum members: 2776, holes: 9, sum holes: 39 */
/* sum bitfield members: 7 bits, bit holes: 1, sum bit holes: 1 bits */
But this way the code is simpler and we do less pointer chasing.
2019-07-28 11:14:46 +02:00
|
|
|
r = bitmap_set(&status_set->signal, signal[i]);
|
2018-01-01 17:40:06 +01:00
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
}
|
2018-01-01 17:40:06 +01:00
|
|
|
}
|
core: rework unit timeout handling, and add new setting RuntimeMaxSec=
This clean-ups timeout handling in PID 1. Specifically, instead of storing 0 in internal timeout variables as
indication for a disabled timeout, use USEC_INFINITY which is in-line with how we do this in the rest of our code
(following the logic that 0 means "no", and USEC_INFINITY means "never").
This also replace all usec_t additions with invocations to usec_add(), so that USEC_INFINITY is properly propagated,
and sd-event considers it has indication for turning off the event source.
This also alters the deserialization of the units to restart timeouts from the time they were originally started from.
Before this patch timeouts would be restarted beginning with the time of the deserialization, which could lead to
artificially prolonged timeouts if a daemon reload took place.
Finally, a new RuntimeMaxSec= setting is introduced for service units, that specifies a maximum runtime after which a
specific service is forcibly terminated. This is useful to put time limits on time-intensive processing jobs.
This also simplifies the various xyz_spawn() calls of the various types in that explicit distruction of the timers is
removed, as that is done anyway by the state change handlers, and a state change is always done when the xyz_spawn()
calls fail.
Fixes: #2249
2016-02-01 21:48:10 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
return 1;
|
|
|
|
}
|
2014-02-05 02:02:00 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
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) {
|
2016-11-24 00:44:57 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
int fd, r;
|
2016-11-24 00:44:57 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
assert(p);
|
|
|
|
assert(b);
|
2016-11-24 00:44:57 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
r = sd_bus_message_read(message, "h", &fd);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
2016-11-24 00:44:57 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
|
|
|
int copy;
|
2016-11-24 00:44:57 +01:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
copy = fcntl(fd, F_DUPFD_CLOEXEC, 3);
|
|
|
|
if (copy < 0)
|
|
|
|
return -errno;
|
2015-10-07 23:07:39 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
asynchronous_close(*p);
|
|
|
|
*p = copy;
|
|
|
|
*b = true;
|
|
|
|
}
|
2015-10-07 23:07:39 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
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);
|
2019-03-19 19:05:19 +01:00
|
|
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string);
|
2020-05-24 13:39:25 +02:00
|
|
|
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, sd_bus_service_name_is_valid);
|
2019-04-16 16:45:20 +02:00
|
|
|
static BUS_DEFINE_SET_TRANSIENT_PARSE(timeout_failure_mode, ServiceTimeoutFailureMode, service_timeout_failure_mode_from_string);
|
2015-10-07 23:07:39 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
static int bus_service_set_transient_property(
|
|
|
|
Service *s,
|
|
|
|
const char *name,
|
|
|
|
sd_bus_message *message,
|
|
|
|
UnitWriteFlags flags,
|
|
|
|
sd_bus_error *error) {
|
2015-10-07 23:07:39 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
Unit *u = UNIT(s);
|
|
|
|
ServiceExecCommand ci;
|
|
|
|
int r;
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
assert(s);
|
|
|
|
assert(name);
|
|
|
|
assert(message);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
flags |= UNIT_PRIVATE;
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "PermissionsStartOnly"))
|
|
|
|
return bus_set_transient_bool(u, name, &s->permissions_start_only, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "RootDirectoryStartOnly"))
|
|
|
|
return bus_set_transient_bool(u, name, &s->root_directory_start_only, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "RemainAfterExit"))
|
|
|
|
return bus_set_transient_bool(u, name, &s->remain_after_exit, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "GuessMainPID"))
|
|
|
|
return bus_set_transient_bool(u, name, &s->guess_main_pid, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "Type"))
|
|
|
|
return bus_set_transient_service_type(u, name, &s->type, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2019-03-19 19:05:19 +01:00
|
|
|
if (streq(name, "OOMPolicy"))
|
|
|
|
return bus_set_transient_oom_policy(u, name, &s->oom_policy, message, flags, error);
|
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "RestartUSec"))
|
|
|
|
return bus_set_transient_usec(u, name, &s->restart_usec, message, flags, error);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (streq(name, "TimeoutStopUSec"))
|
|
|
|
return bus_set_transient_usec(u, name, &s->timeout_stop_usec, message, flags, error);
|
|
|
|
|
2019-11-27 13:42:57 +01:00
|
|
|
if (streq(name, "TimeoutAbortUSec")) {
|
|
|
|
r = bus_set_transient_usec(u, name, &s->timeout_abort_usec, message, flags, error);
|
|
|
|
if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
|
|
|
|
s->timeout_abort_set = true;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2019-04-16 16:45:20 +02:00
|
|
|
if (streq(name, "TimeoutStartFailureMode"))
|
|
|
|
return bus_set_transient_timeout_failure_mode(u, name, &s->timeout_start_failure_mode, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "TimeoutStopFailureMode"))
|
|
|
|
return bus_set_transient_timeout_failure_mode(u, name, &s->timeout_stop_failure_mode, message, flags, error);
|
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "RuntimeMaxUSec"))
|
|
|
|
return bus_set_transient_usec(u, name, &s->runtime_max_usec, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "WatchdogUSec"))
|
|
|
|
return bus_set_transient_usec(u, name, &s->watchdog_usec, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "FileDescriptorStoreMax"))
|
|
|
|
return bus_set_transient_unsigned(u, name, &s->n_fd_store_max, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "NotifyAccess"))
|
|
|
|
return bus_set_transient_notify_access(u, name, &s->notify_access, message, flags, error);
|
|
|
|
|
2018-11-09 18:19:40 +01:00
|
|
|
if (streq(name, "PIDFile")) {
|
|
|
|
_cleanup_free_ char *n = NULL;
|
|
|
|
const char *v, *e;
|
|
|
|
|
|
|
|
r = sd_bus_message_read(message, "s", &v);
|
|
|
|
if (r < 0)
|
|
|
|
return r;
|
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
if (!isempty(v)) {
|
|
|
|
n = path_make_absolute(v, u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
|
|
|
|
if (!n)
|
|
|
|
return -ENOMEM;
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
path_simplify(n, true);
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
if (!path_is_normalized(n))
|
|
|
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "PIDFile= path '%s' is not valid", n);
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
e = path_startswith(n, "/var/run/");
|
|
|
|
if (e) {
|
|
|
|
char *z;
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-06-20 20:07:01 +02:00
|
|
|
z = path_join("/run", e);
|
2019-02-06 17:52:41 +01:00
|
|
|
if (!z)
|
|
|
|
return log_oom();
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags))
|
|
|
|
log_unit_notice(u, "Transient unit's PIDFile= property references path below legacy directory /var/run, updating %s → %s; please update client accordingly.", n, z);
|
2018-11-09 18:19:40 +01:00
|
|
|
|
2019-02-06 17:52:41 +01:00
|
|
|
free_and_replace(n, z);
|
|
|
|
}
|
2019-02-06 17:44:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
2018-11-09 18:19:40 +01:00
|
|
|
free_and_replace(s->pid_file, n);
|
2019-02-06 17:52:41 +01:00
|
|
|
unit_write_settingf(u, flags, name, "%s=%s", name, strempty(s->pid_file));
|
2019-02-06 17:44:59 +01:00
|
|
|
}
|
2018-11-09 18:19:40 +01:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2018-01-01 17:40:06 +01:00
|
|
|
|
|
|
|
if (streq(name, "USBFunctionDescriptors"))
|
|
|
|
return bus_set_transient_path(u, name, &s->usb_function_descriptors, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "USBFunctionStrings"))
|
|
|
|
return bus_set_transient_path(u, name, &s->usb_function_strings, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "BusName"))
|
|
|
|
return bus_set_transient_bus_name(u, name, &s->bus_name, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "Restart"))
|
|
|
|
return bus_set_transient_service_restart(u, name, &s->restart, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "RestartPreventExitStatus"))
|
|
|
|
return bus_set_transient_exit_status(u, name, &s->restart_prevent_status, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "RestartForceExitStatus"))
|
|
|
|
return bus_set_transient_exit_status(u, name, &s->restart_force_status, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "SuccessExitStatus"))
|
|
|
|
return bus_set_transient_exit_status(u, name, &s->success_status, message, flags, error);
|
|
|
|
|
2018-03-23 16:33:38 +01:00
|
|
|
ci = service_exec_command_from_string(name);
|
2019-02-20 23:53:58 +01:00
|
|
|
ci = (ci >= 0) ? ci : service_exec_ex_command_from_string(name);
|
2018-03-23 16:33:38 +01:00
|
|
|
if (ci >= 0)
|
2018-01-01 17:40:06 +01:00
|
|
|
return bus_set_transient_exec_command(u, name, &s->exec_command[ci], message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "StandardInputFileDescriptor"))
|
|
|
|
return bus_set_transient_std_fd(u, name, &s->stdin_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
|
|
|
|
|
|
|
if (streq(name, "StandardOutputFileDescriptor"))
|
|
|
|
return bus_set_transient_std_fd(u, name, &s->stdout_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
2017-06-21 19:17:38 +02:00
|
|
|
|
2018-01-01 17:40:06 +01:00
|
|
|
if (streq(name, "StandardErrorFileDescriptor"))
|
|
|
|
return bus_set_transient_std_fd(u, name, &s->stderr_fd, &s->exec_context.stdio_as_fds, message, flags, error);
|
2013-06-28 04:12:58 +02:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-27 23:21:21 +02:00
|
|
|
int bus_service_set_property(
|
|
|
|
Unit *u,
|
|
|
|
const char *name,
|
2013-11-19 21:12:59 +01:00
|
|
|
sd_bus_message *message,
|
2017-11-22 15:03:51 +01:00
|
|
|
UnitWriteFlags flags,
|
2013-11-19 21:12:59 +01:00
|
|
|
sd_bus_error *error) {
|
2013-06-27 23:21:21 +02:00
|
|
|
|
|
|
|
Service *s = SERVICE(u);
|
|
|
|
int r;
|
|
|
|
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(s);
|
2013-06-27 23:21:21 +02:00
|
|
|
assert(name);
|
2013-11-19 21:12:59 +01:00
|
|
|
assert(message);
|
2013-06-27 23:21:21 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = bus_cgroup_set_property(u, &s->cgroup_context, name, message, flags, error);
|
2013-06-27 23:21:21 +02:00
|
|
|
if (r != 0)
|
|
|
|
return r;
|
|
|
|
|
2013-06-28 04:12:58 +02:00
|
|
|
if (u->transient && u->load_state == UNIT_STUB) {
|
|
|
|
/* This is a transient unit, let's load a little more */
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = bus_service_set_transient_property(s, name, message, flags, error);
|
2013-06-28 04:12:58 +02:00
|
|
|
if (r != 0)
|
|
|
|
return r;
|
2013-07-30 02:28:22 +02:00
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = bus_exec_context_set_transient_property(u, &s->exec_context, name, message, flags, error);
|
2014-02-05 02:02:00 +01:00
|
|
|
if (r != 0)
|
|
|
|
return r;
|
|
|
|
|
2017-11-22 15:03:51 +01:00
|
|
|
r = bus_kill_context_set_transient_property(u, &s->kill_context, name, message, flags, error);
|
2013-07-30 02:28:22 +02:00
|
|
|
if (r != 0)
|
|
|
|
return r;
|
2013-06-28 04:12:58 +02:00
|
|
|
}
|
|
|
|
|
2013-06-27 23:21:21 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int bus_service_commit_properties(Unit *u) {
|
|
|
|
assert(u);
|
|
|
|
|
|
|
|
unit_realize_cgroup(u);
|
2014-02-14 19:11:07 +01:00
|
|
|
|
2013-06-27 23:21:21 +02:00
|
|
|
return 0;
|
|
|
|
}
|