1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
7 #include "bus-get-properties.h"
8 #include "dbus-cgroup.h"
9 #include "dbus-execute.h"
10 #include "dbus-kill.h"
11 #include "dbus-manager.h"
12 #include "dbus-service.h"
13 #include "dbus-util.h"
15 #include "exit-status.h"
18 #include "locale-util.h"
19 #include "mount-util.h"
20 #include "open-file.h"
21 #include "parse-util.h"
22 #include "path-util.h"
23 #include "selinux-access.h"
25 #include "signal-util.h"
26 #include "string-util.h"
30 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type
, service_type
, ServiceType
);
31 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exit_type
, service_exit_type
, ServiceExitType
);
32 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result
, service_result
, ServiceResult
);
33 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart
, service_restart
, ServiceRestart
);
34 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action
, emergency_action
, EmergencyAction
);
35 static BUS_DEFINE_PROPERTY_GET2(property_get_notify_access
, "s", Service
, service_get_notify_access
, notify_access_to_string
);
36 static BUS_DEFINE_PROPERTY_GET(property_get_restart_usec_current
, "t", Service
, service_restart_usec
);
37 static BUS_DEFINE_PROPERTY_GET(property_get_timeout_abort_usec
, "t", Service
, service_timeout_abort_usec
);
38 static BUS_DEFINE_PROPERTY_GET(property_get_watchdog_usec
, "t", Service
, service_get_watchdog_usec
);
39 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_timeout_failure_mode
, service_timeout_failure_mode
, ServiceTimeoutFailureMode
);
41 static int property_get_open_files(
44 const char *interface
,
46 sd_bus_message
*reply
,
48 sd_bus_error
*error
) {
50 OpenFile
**open_files
= ASSERT_PTR(userdata
);
56 r
= sd_bus_message_open_container(reply
, 'a', "(sst)");
60 LIST_FOREACH(open_files
, of
, *open_files
) {
61 r
= sd_bus_message_append(reply
, "(sst)", of
->path
, of
->fdname
, of
->flags
);
66 return sd_bus_message_close_container(reply
);
69 static int property_get_exit_status_set(
72 const char *interface
,
74 sd_bus_message
*reply
,
76 sd_bus_error
*error
) {
78 const ExitStatusSet
*status_set
= ASSERT_PTR(userdata
);
85 r
= sd_bus_message_open_container(reply
, 'r', "aiai");
89 r
= sd_bus_message_open_container(reply
, 'a', "i");
93 BITMAP_FOREACH(n
, &status_set
->status
) {
96 r
= sd_bus_message_append_basic(reply
, 'i', &n
);
101 r
= sd_bus_message_close_container(reply
);
105 r
= sd_bus_message_open_container(reply
, 'a', "i");
109 BITMAP_FOREACH(n
, &status_set
->signal
) {
112 str
= signal_to_string(n
);
116 r
= sd_bus_message_append_basic(reply
, 'i', &n
);
121 r
= sd_bus_message_close_container(reply
);
125 return sd_bus_message_close_container(reply
);
128 static int bus_service_method_mount(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
, bool is_image
) {
129 _cleanup_(mount_options_free_allp
) MountOptions
*options
= NULL
;
130 const char *dest
, *src
, *propagate_directory
;
131 int read_only
, make_file_or_directory
;
132 Unit
*u
= ASSERT_PTR(userdata
);
139 if (!MANAGER_IS_SYSTEM(u
->manager
))
140 return sd_bus_error_set(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Adding bind mounts at runtime is only supported for system managers.");
142 r
= mac_selinux_unit_access_check(u
, message
, "start", error
);
146 r
= sd_bus_message_read(message
, "ssbb", &src
, &dest
, &read_only
, &make_file_or_directory
);
150 if (!path_is_absolute(src
) || !path_is_normalized(src
))
151 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Source path must be absolute and normalized.");
153 if (!is_image
&& isempty(dest
))
155 else if (!path_is_absolute(dest
) || !path_is_normalized(dest
))
156 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Destination path must be absolute and normalized.");
159 r
= bus_read_mount_options(message
, error
, &options
, NULL
, "");
164 r
= bus_verify_manage_units_async_full(
166 is_image
? "mount-image" : "bind-mount",
168 N_("Authentication is required to mount on '$(unit)'."),
175 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
177 if (u
->type
!= UNIT_SERVICE
)
178 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit is not of type .service");
180 /* If it would be dropped at startup time, return an error. The context should always be available, but
181 * there's an assert in exec_needs_mount_namespace, so double-check just in case. */
182 c
= unit_get_exec_context(u
);
184 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Cannot access unit execution context");
185 if (path_startswith_strv(dest
, c
->inaccessible_paths
))
186 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s is not accessible to this unit", dest
);
188 /* Ensure that the unit was started in a private mount namespace */
189 if (!exec_needs_mount_namespace(c
, NULL
, unit_get_exec_runtime(u
)))
190 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit not running in private mount namespace, cannot activate bind mount");
192 unit_pid
= unit_main_pid(u
);
193 if (unit_pid
== 0 || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u
)))
194 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit is not running");
196 propagate_directory
= strjoina("/run/systemd/propagate/", u
->id
);
198 r
= mount_image_in_namespace(unit_pid
,
200 "/run/systemd/incoming/",
201 src
, dest
, read_only
, make_file_or_directory
, options
);
203 r
= bind_mount_in_namespace(unit_pid
,
205 "/run/systemd/incoming/",
206 src
, dest
, read_only
, make_file_or_directory
);
208 return sd_bus_error_set_errnof(error
, r
, "Failed to mount %s on %s in unit's namespace: %m", src
, dest
);
210 return sd_bus_reply_method_return(message
, NULL
);
213 int bus_service_method_bind_mount(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
214 return bus_service_method_mount(message
, userdata
, error
, false);
217 int bus_service_method_mount_image(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
218 return bus_service_method_mount(message
, userdata
, error
, true);
221 const sd_bus_vtable bus_service_vtable
[] = {
222 SD_BUS_VTABLE_START(0),
223 SD_BUS_PROPERTY("Type", "s", property_get_type
, offsetof(Service
, type
), SD_BUS_VTABLE_PROPERTY_CONST
),
224 SD_BUS_PROPERTY("ExitType", "s", property_get_exit_type
, offsetof(Service
, exit_type
), SD_BUS_VTABLE_PROPERTY_CONST
),
225 SD_BUS_PROPERTY("Restart", "s", property_get_restart
, offsetof(Service
, restart
), SD_BUS_VTABLE_PROPERTY_CONST
),
226 SD_BUS_PROPERTY("PIDFile", "s", NULL
, offsetof(Service
, pid_file
), SD_BUS_VTABLE_PROPERTY_CONST
),
227 SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
228 SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec
, offsetof(Service
, restart_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
229 SD_BUS_PROPERTY("RestartSteps", "u", bus_property_get_unsigned
, offsetof(Service
, restart_steps
), SD_BUS_VTABLE_PROPERTY_CONST
),
230 SD_BUS_PROPERTY("RestartUSecMax", "t", bus_property_get_usec
, offsetof(Service
, restart_usec_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
231 SD_BUS_PROPERTY("RestartUSecCurrent", "t", property_get_restart_usec_current
, 0, 0),
232 SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec
, offsetof(Service
, timeout_start_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
233 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec
, offsetof(Service
, timeout_stop_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
234 SD_BUS_PROPERTY("TimeoutAbortUSec", "t", property_get_timeout_abort_usec
, 0, 0),
235 SD_BUS_PROPERTY("TimeoutStartFailureMode", "s", property_get_timeout_failure_mode
, offsetof(Service
, timeout_start_failure_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
236 SD_BUS_PROPERTY("TimeoutStopFailureMode", "s", property_get_timeout_failure_mode
, offsetof(Service
, timeout_stop_failure_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
237 SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec
, offsetof(Service
, runtime_max_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
238 SD_BUS_PROPERTY("RuntimeRandomizedExtraUSec", "t", bus_property_get_usec
, offsetof(Service
, runtime_rand_extra_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
239 SD_BUS_PROPERTY("WatchdogUSec", "t", property_get_watchdog_usec
, 0, 0),
240 BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service
, watchdog_timestamp
), 0),
241 SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool
, offsetof(Service
, permissions_start_only
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
), /* 😷 deprecated */
242 SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool
, offsetof(Service
, root_directory_start_only
), SD_BUS_VTABLE_PROPERTY_CONST
),
243 SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool
, offsetof(Service
, remain_after_exit
), SD_BUS_VTABLE_PROPERTY_CONST
),
244 SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool
, offsetof(Service
, guess_main_pid
), SD_BUS_VTABLE_PROPERTY_CONST
),
245 SD_BUS_PROPERTY("RestartPreventExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, restart_prevent_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
246 SD_BUS_PROPERTY("RestartForceExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, restart_force_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
247 SD_BUS_PROPERTY("SuccessExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, success_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
248 SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid
, offsetof(Service
, main_pid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
249 SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid
, offsetof(Service
, control_pid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
250 SD_BUS_PROPERTY("BusName", "s", NULL
, offsetof(Service
, bus_name
), SD_BUS_VTABLE_PROPERTY_CONST
),
251 SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned
, offsetof(Service
, n_fd_store_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
252 SD_BUS_PROPERTY("NFileDescriptorStore", "u", bus_property_get_unsigned
, offsetof(Service
, n_fd_store
), 0),
253 SD_BUS_PROPERTY("StatusText", "s", NULL
, offsetof(Service
, status_text
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
254 SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int
, offsetof(Service
, status_errno
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
255 SD_BUS_PROPERTY("Result", "s", property_get_result
, offsetof(Service
, result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
256 SD_BUS_PROPERTY("ReloadResult", "s", property_get_result
, offsetof(Service
, reload_result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
257 SD_BUS_PROPERTY("CleanResult", "s", property_get_result
, offsetof(Service
, clean_result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
258 SD_BUS_PROPERTY("USBFunctionDescriptors", "s", NULL
, offsetof(Service
, usb_function_descriptors
), SD_BUS_VTABLE_PROPERTY_CONST
),
259 SD_BUS_PROPERTY("USBFunctionStrings", "s", NULL
, offsetof(Service
, usb_function_strings
), SD_BUS_VTABLE_PROPERTY_CONST
),
260 SD_BUS_PROPERTY("UID", "u", bus_property_get_uid
, offsetof(Unit
, ref_uid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
261 SD_BUS_PROPERTY("GID", "u", bus_property_get_gid
, offsetof(Unit
, ref_gid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
262 SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned
, offsetof(Service
, n_restarts
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
263 SD_BUS_PROPERTY("OOMPolicy", "s", bus_property_get_oom_policy
, offsetof(Service
, oom_policy
), SD_BUS_VTABLE_PROPERTY_CONST
),
264 SD_BUS_PROPERTY("OpenFile", "a(sst)", property_get_open_files
, offsetof(Service
, open_files
), SD_BUS_VTABLE_PROPERTY_CONST
),
265 SD_BUS_PROPERTY("ReloadSignal", "i", bus_property_get_int
, offsetof(Service
, reload_signal
), SD_BUS_VTABLE_PROPERTY_CONST
),
267 BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service
, main_exec_status
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
268 BUS_EXEC_COMMAND_LIST_VTABLE("ExecCondition", offsetof(Service
, exec_command
[SERVICE_EXEC_CONDITION
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
269 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecConditionEx", offsetof(Service
, exec_command
[SERVICE_EXEC_CONDITION
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
270 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service
, exec_command
[SERVICE_EXEC_START_PRE
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
271 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPreEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START_PRE
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
272 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service
, exec_command
[SERVICE_EXEC_START
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
273 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
274 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service
, exec_command
[SERVICE_EXEC_START_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
275 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPostEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
276 BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service
, exec_command
[SERVICE_EXEC_RELOAD
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
277 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecReloadEx", offsetof(Service
, exec_command
[SERVICE_EXEC_RELOAD
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
278 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
279 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopEx", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
280 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
281 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopPostEx", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
283 SD_BUS_METHOD_WITH_ARGS("BindMount",
284 SD_BUS_ARGS("s", source
, "s", destination
, "b", read_only
, "b", mkdir
),
286 bus_service_method_bind_mount
,
287 SD_BUS_VTABLE_UNPRIVILEGED
),
289 SD_BUS_METHOD_WITH_ARGS("MountImage",
290 SD_BUS_ARGS("s", source
, "s", destination
, "b", read_only
, "b", mkdir
, "a(ss)", options
),
292 bus_service_method_mount_image
,
293 SD_BUS_VTABLE_UNPRIVILEGED
),
295 /* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
296 SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec
, offsetof(Unit
, start_ratelimit
.interval
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
297 SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned
, offsetof(Unit
, start_ratelimit
.burst
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
298 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action
, offsetof(Unit
, start_limit_action
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
299 SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action
, offsetof(Unit
, failure_action
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
300 SD_BUS_PROPERTY("RebootArgument", "s", NULL
, offsetof(Unit
, reboot_arg
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
304 static int bus_set_transient_exit_status(
307 ExitStatusSet
*status_set
,
308 sd_bus_message
*message
,
309 UnitWriteFlags flags
,
310 sd_bus_error
*error
) {
312 const int32_t *status
, *signal
;
313 size_t n_status
, n_signal
, i
;
316 r
= sd_bus_message_enter_container(message
, 'r', "aiai");
320 r
= sd_bus_message_read_array(message
, 'i', (const void **) &status
, &n_status
);
324 r
= sd_bus_message_read_array(message
, 'i', (const void **) &signal
, &n_signal
);
328 r
= sd_bus_message_exit_container(message
);
332 n_status
/= sizeof(int32_t);
333 n_signal
/= sizeof(int32_t);
335 if (n_status
== 0 && n_signal
== 0 && !UNIT_WRITE_FLAGS_NOOP(flags
)) {
336 exit_status_set_free(status_set
);
337 unit_write_settingf(u
, flags
, name
, "%s=", name
);
341 for (i
= 0; i
< n_status
; i
++) {
342 if (status
[i
] < 0 || status
[i
] > 255)
343 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid status code in %s: %"PRIi32
, name
, status
[i
]);
345 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
346 r
= bitmap_set(&status_set
->status
, status
[i
]);
350 unit_write_settingf(u
, flags
, name
, "%s=%"PRIi32
, name
, status
[i
]);
354 for (i
= 0; i
< n_signal
; i
++) {
357 str
= signal_to_string((int) signal
[i
]);
359 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid signal in %s: %"PRIi32
, name
, signal
[i
]);
361 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
362 r
= bitmap_set(&status_set
->signal
, signal
[i
]);
366 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, str
);
373 static int bus_set_transient_std_fd(
378 sd_bus_message
*message
,
379 UnitWriteFlags flags
,
380 sd_bus_error
*error
) {
387 r
= sd_bus_message_read(message
, "h", &fd
);
391 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
394 copy
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
398 asynchronous_close(*p
);
405 static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access
, NotifyAccess
, notify_access_from_string
);
406 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type
, ServiceType
, service_type_from_string
);
407 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_exit_type
, ServiceExitType
, service_exit_type_from_string
);
408 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart
, ServiceRestart
, service_restart_from_string
);
409 static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy
, OOMPolicy
, oom_policy_from_string
);
410 static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name
, sd_bus_service_name_is_valid
);
411 static BUS_DEFINE_SET_TRANSIENT_PARSE(timeout_failure_mode
, ServiceTimeoutFailureMode
, service_timeout_failure_mode_from_string
);
412 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(reload_signal
, "i", int32_t, int, "%" PRIi32
, signal_to_string_with_check
);
414 static int bus_service_set_transient_property(
417 sd_bus_message
*message
,
418 UnitWriteFlags flags
,
419 sd_bus_error
*error
) {
422 ServiceExecCommand ci
;
429 flags
|= UNIT_PRIVATE
;
431 if (streq(name
, "PermissionsStartOnly"))
432 return bus_set_transient_bool(u
, name
, &s
->permissions_start_only
, message
, flags
, error
);
434 if (streq(name
, "RootDirectoryStartOnly"))
435 return bus_set_transient_bool(u
, name
, &s
->root_directory_start_only
, message
, flags
, error
);
437 if (streq(name
, "RemainAfterExit"))
438 return bus_set_transient_bool(u
, name
, &s
->remain_after_exit
, message
, flags
, error
);
440 if (streq(name
, "GuessMainPID"))
441 return bus_set_transient_bool(u
, name
, &s
->guess_main_pid
, message
, flags
, error
);
443 if (streq(name
, "Type"))
444 return bus_set_transient_service_type(u
, name
, &s
->type
, message
, flags
, error
);
446 if (streq(name
, "ExitType"))
447 return bus_set_transient_service_exit_type(u
, name
, &s
->exit_type
, message
, flags
, error
);
449 if (streq(name
, "OOMPolicy"))
450 return bus_set_transient_oom_policy(u
, name
, &s
->oom_policy
, message
, flags
, error
);
452 if (streq(name
, "RestartUSec"))
453 return bus_set_transient_usec(u
, name
, &s
->restart_usec
, message
, flags
, error
);
455 if (streq(name
, "RestartSteps"))
456 return bus_set_transient_unsigned(u
, name
, &s
->restart_steps
, message
, flags
, error
);
458 if (streq(name
, "RestartUSecMax"))
459 return bus_set_transient_usec(u
, name
, &s
->restart_usec_max
, message
, flags
, error
);
461 if (streq(name
, "TimeoutStartUSec")) {
462 r
= bus_set_transient_usec(u
, name
, &s
->timeout_start_usec
, message
, flags
, error
);
463 if (r
>= 0 && !UNIT_WRITE_FLAGS_NOOP(flags
))
464 s
->start_timeout_defined
= true;
469 if (streq(name
, "TimeoutStopUSec"))
470 return bus_set_transient_usec(u
, name
, &s
->timeout_stop_usec
, message
, flags
, error
);
472 if (streq(name
, "TimeoutAbortUSec")) {
473 r
= bus_set_transient_usec(u
, name
, &s
->timeout_abort_usec
, message
, flags
, error
);
474 if (r
>= 0 && !UNIT_WRITE_FLAGS_NOOP(flags
))
475 s
->timeout_abort_set
= true;
479 if (streq(name
, "TimeoutStartFailureMode"))
480 return bus_set_transient_timeout_failure_mode(u
, name
, &s
->timeout_start_failure_mode
, message
, flags
, error
);
482 if (streq(name
, "TimeoutStopFailureMode"))
483 return bus_set_transient_timeout_failure_mode(u
, name
, &s
->timeout_stop_failure_mode
, message
, flags
, error
);
485 if (streq(name
, "RuntimeMaxUSec"))
486 return bus_set_transient_usec(u
, name
, &s
->runtime_max_usec
, message
, flags
, error
);
488 if (streq(name
, "RuntimeRandomizedExtraUSec"))
489 return bus_set_transient_usec(u
, name
, &s
->runtime_rand_extra_usec
, message
, flags
, error
);
491 if (streq(name
, "WatchdogUSec"))
492 return bus_set_transient_usec(u
, name
, &s
->watchdog_usec
, message
, flags
, error
);
494 if (streq(name
, "FileDescriptorStoreMax"))
495 return bus_set_transient_unsigned(u
, name
, &s
->n_fd_store_max
, message
, flags
, error
);
497 if (streq(name
, "NotifyAccess"))
498 return bus_set_transient_notify_access(u
, name
, &s
->notify_access
, message
, flags
, error
);
500 if (streq(name
, "PIDFile")) {
501 _cleanup_free_
char *n
= NULL
;
504 r
= sd_bus_message_read(message
, "s", &v
);
509 n
= path_make_absolute(v
, u
->manager
->prefix
[EXEC_DIRECTORY_RUNTIME
]);
515 if (!path_is_normalized(n
))
516 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "PIDFile= path '%s' is not valid", n
);
518 e
= path_startswith(n
, "/var/run/");
522 z
= path_join("/run", e
);
526 if (!UNIT_WRITE_FLAGS_NOOP(flags
))
527 log_unit_notice(u
, "Transient unit's PIDFile= property references path below legacy directory /var/run, updating %s %s %s; please update client accordingly.",
528 n
, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT
), z
);
530 free_and_replace(n
, z
);
534 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
535 free_and_replace(s
->pid_file
, n
);
536 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, strempty(s
->pid_file
));
542 if (streq(name
, "USBFunctionDescriptors"))
543 return bus_set_transient_path(u
, name
, &s
->usb_function_descriptors
, message
, flags
, error
);
545 if (streq(name
, "USBFunctionStrings"))
546 return bus_set_transient_path(u
, name
, &s
->usb_function_strings
, message
, flags
, error
);
548 if (streq(name
, "BusName"))
549 return bus_set_transient_bus_name(u
, name
, &s
->bus_name
, message
, flags
, error
);
551 if (streq(name
, "Restart"))
552 return bus_set_transient_service_restart(u
, name
, &s
->restart
, message
, flags
, error
);
554 if (streq(name
, "RestartPreventExitStatus"))
555 return bus_set_transient_exit_status(u
, name
, &s
->restart_prevent_status
, message
, flags
, error
);
557 if (streq(name
, "RestartForceExitStatus"))
558 return bus_set_transient_exit_status(u
, name
, &s
->restart_force_status
, message
, flags
, error
);
560 if (streq(name
, "SuccessExitStatus"))
561 return bus_set_transient_exit_status(u
, name
, &s
->success_status
, message
, flags
, error
);
563 ci
= service_exec_command_from_string(name
);
564 ci
= (ci
>= 0) ? ci
: service_exec_ex_command_from_string(name
);
566 return bus_set_transient_exec_command(u
, name
, &s
->exec_command
[ci
], message
, flags
, error
);
568 if (streq(name
, "StandardInputFileDescriptor"))
569 return bus_set_transient_std_fd(u
, name
, &s
->stdin_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
571 if (streq(name
, "StandardOutputFileDescriptor"))
572 return bus_set_transient_std_fd(u
, name
, &s
->stdout_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
574 if (streq(name
, "StandardErrorFileDescriptor"))
575 return bus_set_transient_std_fd(u
, name
, &s
->stderr_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
577 if (streq(name
, "OpenFile")) {
578 const char *path
, *fdname
;
581 r
= sd_bus_message_enter_container(message
, 'a', "(sst)");
585 while ((r
= sd_bus_message_read(message
, "(sst)", &path
, &fdname
, &offlags
)) > 0) {
586 _cleanup_(open_file_freep
) OpenFile
*of
= NULL
;
587 _cleanup_free_
char *ofs
= NULL
;
589 of
= new(OpenFile
, 1);
594 .path
= strdup(path
),
595 .fdname
= strdup(fdname
),
599 if (!of
->path
|| !of
->fdname
)
602 r
= open_file_validate(of
);
606 if (UNIT_WRITE_FLAGS_NOOP(flags
))
609 r
= open_file_to_string(of
, &ofs
);
611 return sd_bus_error_set_errnof(
612 error
, r
, "Failed to convert OpenFile= value to string: %m");
614 LIST_APPEND(open_files
, s
->open_files
, TAKE_PTR(of
));
615 unit_write_settingf(u
, flags
| UNIT_ESCAPE_SPECIFIERS
, name
, "OpenFile=%s", ofs
);
620 r
= sd_bus_message_exit_container(message
);
627 if (streq(name
, "ReloadSignal"))
628 return bus_set_transient_reload_signal(u
, name
, &s
->reload_signal
, message
, flags
, error
);
633 int bus_service_set_property(
636 sd_bus_message
*message
,
637 UnitWriteFlags flags
,
638 sd_bus_error
*error
) {
640 Service
*s
= SERVICE(u
);
647 r
= bus_cgroup_set_property(u
, &s
->cgroup_context
, name
, message
, flags
, error
);
651 if (u
->transient
&& u
->load_state
== UNIT_STUB
) {
652 /* This is a transient unit, let's load a little more */
654 r
= bus_service_set_transient_property(s
, name
, message
, flags
, error
);
658 r
= bus_exec_context_set_transient_property(u
, &s
->exec_context
, name
, message
, flags
, error
);
662 r
= bus_kill_context_set_transient_property(u
, &s
->kill_context
, name
, message
, flags
, error
);
670 int bus_service_commit_properties(Unit
*u
) {
673 unit_realize_cgroup(u
);