1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include <sys/sysmacros.h>
7 #include "alloc-util.h"
9 #include "bus-common-errors.h"
10 #include "bus-get-properties.h"
11 #include "constants.h"
12 #include "dbus-cgroup.h"
13 #include "dbus-execute.h"
14 #include "dbus-kill.h"
15 #include "dbus-manager.h"
16 #include "dbus-service.h"
17 #include "dbus-util.h"
18 #include "dissect-image.h"
20 #include "exit-status.h"
22 #include "glyph-util.h"
23 #include "locale-util.h"
25 #include "mount-util.h"
26 #include "open-file.h"
27 #include "path-util.h"
28 #include "selinux-access.h"
30 #include "signal-util.h"
31 #include "string-util.h"
34 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type
, service_type
, ServiceType
);
35 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exit_type
, service_exit_type
, ServiceExitType
);
36 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result
, service_result
, ServiceResult
);
37 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart
, service_restart
, ServiceRestart
);
38 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart_mode
, service_restart_mode
, ServiceRestartMode
);
39 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action
, emergency_action
, EmergencyAction
);
40 static BUS_DEFINE_PROPERTY_GET2(property_get_notify_access
, "s", Service
, service_get_notify_access
, notify_access_to_string
);
41 static BUS_DEFINE_PROPERTY_GET(property_get_restart_usec_next
, "t", Service
, service_restart_usec_next
);
42 static BUS_DEFINE_PROPERTY_GET(property_get_timeout_abort_usec
, "t", Service
, service_timeout_abort_usec
);
43 static BUS_DEFINE_PROPERTY_GET(property_get_watchdog_usec
, "t", Service
, service_get_watchdog_usec
);
44 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_timeout_failure_mode
, service_timeout_failure_mode
, ServiceTimeoutFailureMode
);
46 static int property_get_open_files(
49 const char *interface
,
51 sd_bus_message
*reply
,
53 sd_bus_error
*error
) {
55 OpenFile
**open_files
= ASSERT_PTR(userdata
);
61 r
= sd_bus_message_open_container(reply
, 'a', "(sst)");
65 LIST_FOREACH(open_files
, of
, *open_files
) {
66 r
= sd_bus_message_append(reply
, "(sst)", of
->path
, of
->fdname
, (uint64_t) of
->flags
);
71 return sd_bus_message_close_container(reply
);
74 static int property_get_extra_file_descriptors(
77 const char *interface
,
79 sd_bus_message
*reply
,
81 sd_bus_error
*error
) {
83 Service
*s
= ASSERT_PTR(userdata
);
89 r
= sd_bus_message_open_container(reply
, 'a', "s");
93 FOREACH_ARRAY(i
, s
->extra_fds
, s
->n_extra_fds
) {
94 r
= sd_bus_message_append_basic(reply
, 's', i
->fdname
);
99 return sd_bus_message_close_container(reply
);
102 static int property_get_exit_status_set(
105 const char *interface
,
106 const char *property
,
107 sd_bus_message
*reply
,
109 sd_bus_error
*error
) {
111 const ExitStatusSet
*status_set
= ASSERT_PTR(userdata
);
118 r
= sd_bus_message_open_container(reply
, 'r', "aiai");
122 r
= sd_bus_message_open_container(reply
, 'a', "i");
126 BITMAP_FOREACH(n
, &status_set
->status
) {
129 r
= sd_bus_message_append_basic(reply
, 'i', &n
);
134 r
= sd_bus_message_close_container(reply
);
138 r
= sd_bus_message_open_container(reply
, 'a', "i");
142 BITMAP_FOREACH(n
, &status_set
->signal
) {
145 str
= signal_to_string(n
);
149 r
= sd_bus_message_append_basic(reply
, 'i', &n
);
154 r
= sd_bus_message_close_container(reply
);
158 return sd_bus_message_close_container(reply
);
161 static int bus_service_method_mount(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
, bool is_image
) {
162 MountInNamespaceFlags flags
= 0;
163 Unit
*u
= ASSERT_PTR(userdata
);
168 if (!MANAGER_IS_SYSTEM(u
->manager
))
169 return sd_bus_error_set(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Adding bind mounts at runtime is only supported by system manager");
171 r
= unit_can_live_mount(u
, error
);
173 return log_unit_debug_errno(u
, r
, "Cannot schedule live mount operation: %s", bus_error_message(error
, r
));
175 r
= mac_selinux_unit_access_check(u
, message
, "start", error
);
179 _cleanup_(mount_options_free_allp
) MountOptions
*options
= NULL
;
180 const char *src
, *dest
;
181 int read_only
, make_file_or_directory
;
183 r
= sd_bus_message_read(message
, "ssbb", &src
, &dest
, &read_only
, &make_file_or_directory
);
187 if (!path_is_absolute(src
) || !path_is_normalized(src
))
188 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Source path must be absolute and normalized");
190 if (!is_image
&& isempty(dest
))
192 else if (!path_is_absolute(dest
) || !path_is_normalized(dest
))
193 return sd_bus_error_set(error
, SD_BUS_ERROR_INVALID_ARGS
, "Destination path must be absolute and normalized");
196 r
= bus_read_mount_options(message
, error
, &options
, NULL
, "");
201 r
= bus_verify_manage_units_async_full(
203 is_image
? "mount-image" : "bind-mount",
204 N_("Authentication is required to mount on '$(unit)'."),
210 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
213 flags
|= MOUNT_IN_NAMESPACE_IS_IMAGE
;
215 flags
|= MOUNT_IN_NAMESPACE_READ_ONLY
;
216 if (make_file_or_directory
)
217 flags
|= MOUNT_IN_NAMESPACE_MAKE_FILE_OR_DIRECTORY
;
219 r
= unit_live_mount(u
, src
, dest
, message
, flags
, options
, error
);
226 int bus_service_method_bind_mount(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
227 return bus_service_method_mount(message
, userdata
, error
, false);
230 int bus_service_method_mount_image(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
231 return bus_service_method_mount(message
, userdata
, error
, true);
234 int bus_service_method_dump_file_descriptor_store(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
235 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
236 Service
*s
= ASSERT_PTR(userdata
);
241 r
= mac_selinux_unit_access_check(UNIT(s
), message
, "status", error
);
245 if (s
->n_fd_store_max
== 0 && s
->n_fd_store
== 0)
246 return sd_bus_error_setf(error
, BUS_ERROR_FILE_DESCRIPTOR_STORE_DISABLED
, "File descriptor store not enabled for %s.", UNIT(s
)->id
);
248 r
= sd_bus_message_new_method_return(message
, &reply
);
252 r
= sd_bus_message_open_container(reply
, 'a', "(suuutuusu)");
256 LIST_FOREACH(fd_store
, i
, s
->fd_store
) {
257 _cleanup_free_
char *path
= NULL
;
261 if (fstat(i
->fd
, &st
) < 0) {
262 log_debug_errno(errno
, "Failed to stat() file descriptor entry '%s', skipping.", strna(i
->fdname
));
266 flags
= fcntl(i
->fd
, F_GETFL
);
268 log_debug_errno(errno
, "Failed to issue F_GETFL on file descriptor entry '%s', skipping.", strna(i
->fdname
));
272 /* glibc implies O_LARGEFILE everywhere on 64-bit off_t builds, but forgets to hide it away on
273 * F_GETFL, but provides no definition to check for that. Let's mask the flag away manually,
274 * to not confuse clients. */
275 flags
&= ~RAW_O_LARGEFILE
;
277 (void) fd_get_path(i
->fd
, &path
);
279 r
= sd_bus_message_append(
283 (uint32_t) st
.st_mode
,
284 (uint32_t) major(st
.st_dev
), (uint32_t) minor(st
.st_dev
),
285 (uint64_t) st
.st_ino
,
286 (uint32_t) major(st
.st_rdev
), (uint32_t) minor(st
.st_rdev
),
293 r
= sd_bus_message_close_container(reply
);
297 return sd_bus_message_send(reply
);
300 #if __SIZEOF_SIZE_T__ == 8
301 static int property_get_size_as_uint32(
304 const char *interface
,
305 const char *property
,
306 sd_bus_message
*reply
,
308 sd_bus_error
*error
) {
310 size_t *value
= ASSERT_PTR(userdata
);
311 uint32_t sz
= *value
>= UINT32_MAX
? UINT32_MAX
: (uint32_t) *value
;
313 /* Returns a size_t as a D-Bus "u" type, i.e. as 32-bit value, even if size_t is 64-bit. We'll saturate if it doesn't fit. */
315 return sd_bus_message_append_basic(reply
, 'u', &sz
);
317 #elif __SIZEOF_SIZE_T__ == 4
318 #define property_get_size_as_uint32 ((sd_bus_property_get_t) NULL)
320 #error "Unexpected size of size_t"
323 const sd_bus_vtable bus_service_vtable
[] = {
324 SD_BUS_VTABLE_START(0),
325 SD_BUS_PROPERTY("Type", "s", property_get_type
, offsetof(Service
, type
), SD_BUS_VTABLE_PROPERTY_CONST
),
326 SD_BUS_PROPERTY("ExitType", "s", property_get_exit_type
, offsetof(Service
, exit_type
), SD_BUS_VTABLE_PROPERTY_CONST
),
327 SD_BUS_PROPERTY("Restart", "s", property_get_restart
, offsetof(Service
, restart
), SD_BUS_VTABLE_PROPERTY_CONST
),
328 SD_BUS_PROPERTY("RestartMode", "s", property_get_restart_mode
, offsetof(Service
, restart_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
329 SD_BUS_PROPERTY("PIDFile", "s", NULL
, offsetof(Service
, pid_file
), SD_BUS_VTABLE_PROPERTY_CONST
),
330 SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
331 SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec
, offsetof(Service
, restart_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
332 SD_BUS_PROPERTY("RestartSteps", "u", bus_property_get_unsigned
, offsetof(Service
, restart_steps
), SD_BUS_VTABLE_PROPERTY_CONST
),
333 SD_BUS_PROPERTY("RestartMaxDelayUSec", "t", bus_property_get_usec
, offsetof(Service
, restart_max_delay_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
334 SD_BUS_PROPERTY("RestartUSecNext", "t", property_get_restart_usec_next
, 0, 0),
335 SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec
, offsetof(Service
, timeout_start_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
336 SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec
, offsetof(Service
, timeout_stop_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
337 SD_BUS_PROPERTY("TimeoutAbortUSec", "t", property_get_timeout_abort_usec
, 0, 0),
338 SD_BUS_PROPERTY("TimeoutStartFailureMode", "s", property_get_timeout_failure_mode
, offsetof(Service
, timeout_start_failure_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
339 SD_BUS_PROPERTY("TimeoutStopFailureMode", "s", property_get_timeout_failure_mode
, offsetof(Service
, timeout_stop_failure_mode
), SD_BUS_VTABLE_PROPERTY_CONST
),
340 SD_BUS_PROPERTY("RuntimeMaxUSec", "t", bus_property_get_usec
, offsetof(Service
, runtime_max_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
341 SD_BUS_PROPERTY("RuntimeRandomizedExtraUSec", "t", bus_property_get_usec
, offsetof(Service
, runtime_rand_extra_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
342 SD_BUS_PROPERTY("WatchdogUSec", "t", property_get_watchdog_usec
, 0, 0),
343 BUS_PROPERTY_DUAL_TIMESTAMP("WatchdogTimestamp", offsetof(Service
, watchdog_timestamp
), 0),
344 SD_BUS_PROPERTY("PermissionsStartOnly", "b", bus_property_get_bool
, offsetof(Service
, permissions_start_only
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
), /* 😷 deprecated */
345 SD_BUS_PROPERTY("RootDirectoryStartOnly", "b", bus_property_get_bool
, offsetof(Service
, root_directory_start_only
), SD_BUS_VTABLE_PROPERTY_CONST
),
346 SD_BUS_PROPERTY("RemainAfterExit", "b", bus_property_get_bool
, offsetof(Service
, remain_after_exit
), SD_BUS_VTABLE_PROPERTY_CONST
),
347 SD_BUS_PROPERTY("GuessMainPID", "b", bus_property_get_bool
, offsetof(Service
, guess_main_pid
), SD_BUS_VTABLE_PROPERTY_CONST
),
348 SD_BUS_PROPERTY("RestartPreventExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, restart_prevent_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
349 SD_BUS_PROPERTY("RestartForceExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, restart_force_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
350 SD_BUS_PROPERTY("SuccessExitStatus", "(aiai)", property_get_exit_status_set
, offsetof(Service
, success_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
351 SD_BUS_PROPERTY("MainPID", "u", bus_property_get_pid
, offsetof(Service
, main_pid
.pid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
352 SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid
, offsetof(Service
, control_pid
.pid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
353 SD_BUS_PROPERTY("BusName", "s", NULL
, offsetof(Service
, bus_name
), SD_BUS_VTABLE_PROPERTY_CONST
),
354 SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned
, offsetof(Service
, n_fd_store_max
), SD_BUS_VTABLE_PROPERTY_CONST
),
355 SD_BUS_PROPERTY("NFileDescriptorStore", "u", property_get_size_as_uint32
, offsetof(Service
, n_fd_store
), 0),
356 SD_BUS_PROPERTY("FileDescriptorStorePreserve", "s", bus_property_get_exec_preserve_mode
, offsetof(Service
, fd_store_preserve_mode
), 0),
357 SD_BUS_PROPERTY("StatusText", "s", NULL
, offsetof(Service
, status_text
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
358 SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int
, offsetof(Service
, status_errno
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
359 SD_BUS_PROPERTY("StatusBusError", "s", NULL
, offsetof(Service
, status_bus_error
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
360 SD_BUS_PROPERTY("StatusVarlinkError", "s", NULL
, offsetof(Service
, status_varlink_error
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
361 SD_BUS_PROPERTY("Result", "s", property_get_result
, offsetof(Service
, result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
362 SD_BUS_PROPERTY("ReloadResult", "s", property_get_result
, offsetof(Service
, reload_result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
363 SD_BUS_PROPERTY("CleanResult", "s", property_get_result
, offsetof(Service
, clean_result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
364 SD_BUS_PROPERTY("LiveMountResult", "s", property_get_result
, offsetof(Service
, live_mount_result
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
365 SD_BUS_PROPERTY("USBFunctionDescriptors", "s", NULL
, offsetof(Service
, usb_function_descriptors
), SD_BUS_VTABLE_PROPERTY_CONST
),
366 SD_BUS_PROPERTY("USBFunctionStrings", "s", NULL
, offsetof(Service
, usb_function_strings
), SD_BUS_VTABLE_PROPERTY_CONST
),
367 SD_BUS_PROPERTY("UID", "u", bus_property_get_uid
, offsetof(Unit
, ref_uid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
368 SD_BUS_PROPERTY("GID", "u", bus_property_get_gid
, offsetof(Unit
, ref_gid
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
369 SD_BUS_PROPERTY("NRestarts", "u", bus_property_get_unsigned
, offsetof(Service
, n_restarts
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
370 SD_BUS_PROPERTY("OOMPolicy", "s", bus_property_get_oom_policy
, offsetof(Service
, oom_policy
), SD_BUS_VTABLE_PROPERTY_CONST
),
371 SD_BUS_PROPERTY("OpenFile", "a(sst)", property_get_open_files
, offsetof(Service
, open_files
), SD_BUS_VTABLE_PROPERTY_CONST
),
372 SD_BUS_PROPERTY("ExtraFileDescriptorNames", "as", property_get_extra_file_descriptors
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
373 SD_BUS_PROPERTY("ReloadSignal", "i", bus_property_get_int
, offsetof(Service
, reload_signal
), SD_BUS_VTABLE_PROPERTY_CONST
),
375 BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service
, main_exec_status
), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
376 BUS_EXEC_COMMAND_LIST_VTABLE("ExecCondition", offsetof(Service
, exec_command
[SERVICE_EXEC_CONDITION
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
377 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecConditionEx", offsetof(Service
, exec_command
[SERVICE_EXEC_CONDITION
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
378 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service
, exec_command
[SERVICE_EXEC_START_PRE
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
379 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPreEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START_PRE
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
380 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service
, exec_command
[SERVICE_EXEC_START
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
381 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
382 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPost", offsetof(Service
, exec_command
[SERVICE_EXEC_START_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
383 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStartPostEx", offsetof(Service
, exec_command
[SERVICE_EXEC_START_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
384 BUS_EXEC_COMMAND_LIST_VTABLE("ExecReload", offsetof(Service
, exec_command
[SERVICE_EXEC_RELOAD
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
385 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecReloadEx", offsetof(Service
, exec_command
[SERVICE_EXEC_RELOAD
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
386 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStop", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
387 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopEx", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
388 BUS_EXEC_COMMAND_LIST_VTABLE("ExecStopPost", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
389 BUS_EXEC_EX_COMMAND_LIST_VTABLE("ExecStopPostEx", offsetof(Service
, exec_command
[SERVICE_EXEC_STOP_POST
]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION
),
391 SD_BUS_METHOD_WITH_ARGS("BindMount",
392 SD_BUS_ARGS("s", source
, "s", destination
, "b", read_only
, "b", mkdir
),
394 bus_service_method_bind_mount
,
395 SD_BUS_VTABLE_UNPRIVILEGED
),
397 SD_BUS_METHOD_WITH_ARGS("MountImage",
398 SD_BUS_ARGS("s", source
, "s", destination
, "b", read_only
, "b", mkdir
, "a(ss)", options
),
400 bus_service_method_mount_image
,
401 SD_BUS_VTABLE_UNPRIVILEGED
),
403 SD_BUS_METHOD_WITH_ARGS("DumpFileDescriptorStore",
405 SD_BUS_ARGS("a(suuutuusu)", entries
),
406 bus_service_method_dump_file_descriptor_store
,
407 SD_BUS_VTABLE_UNPRIVILEGED
),
409 /* The following four are obsolete, and thus marked hidden here. They moved into the Unit interface */
410 SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec
, offsetof(Unit
, start_ratelimit
.interval
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
411 SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned
, offsetof(Unit
, start_ratelimit
.burst
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
412 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action
, offsetof(Unit
, start_limit_action
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
413 SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action
, offsetof(Unit
, failure_action
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
414 SD_BUS_PROPERTY("RebootArgument", "s", NULL
, offsetof(Unit
, reboot_arg
), SD_BUS_VTABLE_PROPERTY_CONST
|SD_BUS_VTABLE_HIDDEN
),
418 static int bus_set_transient_exit_status(
421 ExitStatusSet
*status_set
,
422 sd_bus_message
*message
,
423 UnitWriteFlags flags
,
424 sd_bus_error
*error
) {
426 const int32_t *status
, *signal
;
427 size_t n_status
, n_signal
, i
;
430 r
= sd_bus_message_enter_container(message
, 'r', "aiai");
434 r
= sd_bus_message_read_array(message
, 'i', (const void **) &status
, &n_status
);
438 r
= sd_bus_message_read_array(message
, 'i', (const void **) &signal
, &n_signal
);
442 r
= sd_bus_message_exit_container(message
);
446 n_status
/= sizeof(int32_t);
447 n_signal
/= sizeof(int32_t);
449 if (n_status
== 0 && n_signal
== 0 && !UNIT_WRITE_FLAGS_NOOP(flags
)) {
450 exit_status_set_free(status_set
);
451 unit_write_settingf(u
, flags
, name
, "%s=", name
);
455 for (i
= 0; i
< n_status
; i
++) {
456 if (status
[i
] < 0 || status
[i
] > 255)
457 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid status code in %s: %"PRIi32
, name
, status
[i
]);
459 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
460 r
= bitmap_set(&status_set
->status
, status
[i
]);
464 unit_write_settingf(u
, flags
, name
, "%s=%"PRIi32
, name
, status
[i
]);
468 for (i
= 0; i
< n_signal
; i
++) {
471 str
= signal_to_string((int) signal
[i
]);
473 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid signal in %s: %"PRIi32
, name
, signal
[i
]);
475 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
476 r
= bitmap_set(&status_set
->signal
, signal
[i
]);
480 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, str
);
487 static int bus_set_transient_std_fd(
492 sd_bus_message
*message
,
493 UnitWriteFlags flags
,
494 sd_bus_error
*error
) {
501 r
= sd_bus_message_read(message
, "h", &fd
);
505 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
508 copy
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
512 asynchronous_close(*p
);
519 static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access
, NotifyAccess
, notify_access_from_string
);
520 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type
, ServiceType
, service_type_from_string
);
521 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_exit_type
, ServiceExitType
, service_exit_type_from_string
);
522 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart
, ServiceRestart
, service_restart_from_string
);
523 static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart_mode
, ServiceRestartMode
, service_restart_mode_from_string
);
524 static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy
, OOMPolicy
, oom_policy_from_string
);
525 static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name
, sd_bus_service_name_is_valid
);
526 static BUS_DEFINE_SET_TRANSIENT_PARSE(timeout_failure_mode
, ServiceTimeoutFailureMode
, service_timeout_failure_mode_from_string
);
527 static BUS_DEFINE_SET_TRANSIENT_TO_STRING(reload_signal
, "i", int32_t, int, "%" PRIi32
, signal_to_string_with_check
);
529 static int bus_service_set_transient_property(
532 sd_bus_message
*message
,
533 UnitWriteFlags flags
,
534 sd_bus_error
*error
) {
537 ServiceExecCommand ci
;
544 flags
|= UNIT_PRIVATE
;
546 if (streq(name
, "PermissionsStartOnly"))
547 return bus_set_transient_bool(u
, name
, &s
->permissions_start_only
, message
, flags
, error
);
549 if (streq(name
, "RootDirectoryStartOnly"))
550 return bus_set_transient_bool(u
, name
, &s
->root_directory_start_only
, message
, flags
, error
);
552 if (streq(name
, "RemainAfterExit"))
553 return bus_set_transient_bool(u
, name
, &s
->remain_after_exit
, message
, flags
, error
);
555 if (streq(name
, "GuessMainPID"))
556 return bus_set_transient_bool(u
, name
, &s
->guess_main_pid
, message
, flags
, error
);
558 if (streq(name
, "Type"))
559 return bus_set_transient_service_type(u
, name
, &s
->type
, message
, flags
, error
);
561 if (streq(name
, "ExitType"))
562 return bus_set_transient_service_exit_type(u
, name
, &s
->exit_type
, message
, flags
, error
);
564 if (streq(name
, "OOMPolicy"))
565 return bus_set_transient_oom_policy(u
, name
, &s
->oom_policy
, message
, flags
, error
);
567 if (streq(name
, "RestartUSec"))
568 return bus_set_transient_usec(u
, name
, &s
->restart_usec
, message
, flags
, error
);
570 if (streq(name
, "RestartSteps"))
571 return bus_set_transient_unsigned(u
, name
, &s
->restart_steps
, message
, flags
, error
);
573 if (streq(name
, "RestartMaxDelayUSec"))
574 return bus_set_transient_usec(u
, name
, &s
->restart_max_delay_usec
, message
, flags
, error
);
576 if (streq(name
, "TimeoutStartUSec")) {
577 r
= bus_set_transient_usec(u
, name
, &s
->timeout_start_usec
, message
, flags
, error
);
578 if (r
>= 0 && !UNIT_WRITE_FLAGS_NOOP(flags
))
579 s
->start_timeout_defined
= true;
584 if (streq(name
, "TimeoutStopUSec"))
585 return bus_set_transient_usec(u
, name
, &s
->timeout_stop_usec
, message
, flags
, error
);
587 if (streq(name
, "TimeoutAbortUSec")) {
588 r
= bus_set_transient_usec(u
, name
, &s
->timeout_abort_usec
, message
, flags
, error
);
589 if (r
>= 0 && !UNIT_WRITE_FLAGS_NOOP(flags
))
590 s
->timeout_abort_set
= true;
594 if (streq(name
, "TimeoutStartFailureMode"))
595 return bus_set_transient_timeout_failure_mode(u
, name
, &s
->timeout_start_failure_mode
, message
, flags
, error
);
597 if (streq(name
, "TimeoutStopFailureMode"))
598 return bus_set_transient_timeout_failure_mode(u
, name
, &s
->timeout_stop_failure_mode
, message
, flags
, error
);
600 if (streq(name
, "RuntimeMaxUSec"))
601 return bus_set_transient_usec(u
, name
, &s
->runtime_max_usec
, message
, flags
, error
);
603 if (streq(name
, "RuntimeRandomizedExtraUSec"))
604 return bus_set_transient_usec(u
, name
, &s
->runtime_rand_extra_usec
, message
, flags
, error
);
606 if (streq(name
, "WatchdogUSec"))
607 return bus_set_transient_usec(u
, name
, &s
->watchdog_usec
, message
, flags
, error
);
609 if (streq(name
, "FileDescriptorStoreMax"))
610 return bus_set_transient_unsigned(u
, name
, &s
->n_fd_store_max
, message
, flags
, error
);
612 if (streq(name
, "FileDescriptorStorePreserve"))
613 return bus_set_transient_exec_preserve_mode(u
, name
, &s
->fd_store_preserve_mode
, message
, flags
, error
);
615 if (streq(name
, "NotifyAccess"))
616 return bus_set_transient_notify_access(u
, name
, &s
->notify_access
, message
, flags
, error
);
618 if (streq(name
, "PIDFile")) {
619 _cleanup_free_
char *n
= NULL
;
622 r
= sd_bus_message_read(message
, "s", &v
);
627 n
= path_make_absolute(v
, u
->manager
->prefix
[EXEC_DIRECTORY_RUNTIME
]);
633 if (!path_is_normalized(n
))
634 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "PIDFile= path '%s' is not valid", n
);
636 e
= path_startswith(n
, "/var/run/");
640 z
= path_join("/run", e
);
644 if (!UNIT_WRITE_FLAGS_NOOP(flags
))
645 log_unit_notice(u
, "Transient unit's PIDFile= property references path below legacy directory /var/run, updating %s %s %s; please update client accordingly.",
646 n
, glyph(GLYPH_ARROW_RIGHT
), z
);
648 free_and_replace(n
, z
);
652 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
653 free_and_replace(s
->pid_file
, n
);
654 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, strempty(s
->pid_file
));
660 if (streq(name
, "USBFunctionDescriptors"))
661 return bus_set_transient_path(u
, name
, &s
->usb_function_descriptors
, message
, flags
, error
);
663 if (streq(name
, "USBFunctionStrings"))
664 return bus_set_transient_path(u
, name
, &s
->usb_function_strings
, message
, flags
, error
);
666 if (streq(name
, "BusName"))
667 return bus_set_transient_bus_name(u
, name
, &s
->bus_name
, message
, flags
, error
);
669 if (streq(name
, "Restart"))
670 return bus_set_transient_service_restart(u
, name
, &s
->restart
, message
, flags
, error
);
672 if (streq(name
, "RestartMode"))
673 return bus_set_transient_service_restart_mode(u
, name
, &s
->restart_mode
, message
, flags
, error
);
675 if (streq(name
, "RestartPreventExitStatus"))
676 return bus_set_transient_exit_status(u
, name
, &s
->restart_prevent_status
, message
, flags
, error
);
678 if (streq(name
, "RestartForceExitStatus"))
679 return bus_set_transient_exit_status(u
, name
, &s
->restart_force_status
, message
, flags
, error
);
681 if (streq(name
, "SuccessExitStatus"))
682 return bus_set_transient_exit_status(u
, name
, &s
->success_status
, message
, flags
, error
);
684 ci
= service_exec_command_from_string(name
);
686 ci
= service_exec_ex_command_from_string(name
);
688 return bus_set_transient_exec_command(u
, name
, &s
->exec_command
[ci
], message
, flags
, error
);
690 if (streq(name
, "StandardInputFileDescriptor"))
691 return bus_set_transient_std_fd(u
, name
, &s
->stdin_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
693 if (streq(name
, "StandardOutputFileDescriptor"))
694 return bus_set_transient_std_fd(u
, name
, &s
->stdout_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
696 if (streq(name
, "StandardErrorFileDescriptor"))
697 return bus_set_transient_std_fd(u
, name
, &s
->stderr_fd
, &s
->exec_context
.stdio_as_fds
, message
, flags
, error
);
699 if (streq(name
, "OpenFile")) {
700 const char *path
, *fdname
;
703 r
= sd_bus_message_enter_container(message
, 'a', "(sst)");
707 while ((r
= sd_bus_message_read(message
, "(sst)", &path
, &fdname
, &offlags
)) > 0) {
708 _cleanup_(open_file_freep
) OpenFile
*of
= NULL
;
709 _cleanup_free_
char *ofs
= NULL
;
711 of
= new(OpenFile
, 1);
716 .path
= strdup(path
),
717 .fdname
= strdup(fdname
),
721 if (!of
->path
|| !of
->fdname
)
724 r
= open_file_validate(of
);
728 if (UNIT_WRITE_FLAGS_NOOP(flags
))
731 r
= open_file_to_string(of
, &ofs
);
733 return sd_bus_error_set_errnof(
734 error
, r
, "Failed to convert OpenFile= value to string: %m");
736 LIST_APPEND(open_files
, s
->open_files
, TAKE_PTR(of
));
737 unit_write_settingf(u
, flags
| UNIT_ESCAPE_SPECIFIERS
, name
, "OpenFile=%s", ofs
);
742 r
= sd_bus_message_exit_container(message
);
749 if (streq(name
, "ReloadSignal"))
750 return bus_set_transient_reload_signal(u
, name
, &s
->reload_signal
, message
, flags
, error
);
752 if (streq(name
, "ExtraFileDescriptors")) {
753 r
= sd_bus_message_enter_container(message
, 'a', "(hs)");
761 r
= sd_bus_message_read(message
, "(hs)", &fd
, &fdname
);
767 /* Disallow empty string for ExtraFileDescriptors.
768 * Unlike OpenFile, StandardInput and friends, there isn't a good sane
769 * default for an arbitrary FD. */
770 if (isempty(fdname
) || !fdname_is_valid(fdname
))
771 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid extra fd name: %s", fdname
);
773 if (s
->n_extra_fds
>= NOTIFY_FD_MAX
)
774 return sd_bus_error_set(error
, SD_BUS_ERROR_LIMITS_EXCEEDED
, "Too many extra fds sent");
776 if (UNIT_WRITE_FLAGS_NOOP(flags
))
779 if (!GREEDY_REALLOC(s
->extra_fds
, s
->n_extra_fds
+ 1))
782 _cleanup_free_
char *fdname_dup
= strdup(fdname
);
786 _cleanup_close_
int fd_dup
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
790 s
->extra_fds
[s
->n_extra_fds
++] = (ServiceExtraFD
) {
791 .fd
= TAKE_FD(fd_dup
),
792 .fdname
= TAKE_PTR(fdname_dup
),
796 r
= sd_bus_message_exit_container(message
);
806 int bus_service_set_property(
809 sd_bus_message
*message
,
810 UnitWriteFlags flags
,
811 sd_bus_error
*error
) {
813 Service
*s
= SERVICE(u
);
820 r
= bus_cgroup_set_property(u
, &s
->cgroup_context
, name
, message
, flags
, error
);
824 if (u
->transient
&& u
->load_state
== UNIT_STUB
) {
825 /* This is a transient unit, let's allow a little more */
827 r
= bus_service_set_transient_property(s
, name
, message
, flags
, error
);
831 r
= bus_exec_context_set_transient_property(u
, &s
->exec_context
, name
, message
, flags
, error
);
835 r
= bus_kill_context_set_transient_property(u
, &s
->kill_context
, name
, message
, flags
, error
);
843 int bus_service_commit_properties(Unit
*u
) {
846 (void) unit_realize_cgroup(u
);