]>
Commit | Line | Data |
---|---|---|
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ | |
2 | #pragma once | |
3 | ||
4 | #include "sd-id128.h" | |
5 | ||
6 | #include "bus-unit-util.h" | |
7 | #include "cgroup-util.h" | |
8 | #include "core-forward.h" | |
9 | #include "cpu-set-util.h" | |
10 | #include "exec-util.h" | |
11 | #include "list.h" | |
12 | #include "log-context.h" | |
13 | #include "namespace.h" | |
14 | #include "numa-util.h" | |
15 | #include "ratelimit.h" | |
16 | #include "rlimit-util.h" | |
17 | #include "time-util.h" | |
18 | ||
19 | #define EXEC_STDIN_DATA_MAX (64U*1024U*1024U) | |
20 | ||
21 | typedef enum ExecUtmpMode { | |
22 | EXEC_UTMP_INIT, | |
23 | EXEC_UTMP_LOGIN, | |
24 | EXEC_UTMP_USER, | |
25 | _EXEC_UTMP_MODE_MAX, | |
26 | _EXEC_UTMP_MODE_INVALID = -EINVAL, | |
27 | } ExecUtmpMode; | |
28 | ||
29 | typedef enum ExecInput { | |
30 | EXEC_INPUT_NULL, | |
31 | EXEC_INPUT_TTY, | |
32 | EXEC_INPUT_TTY_FORCE, | |
33 | EXEC_INPUT_TTY_FAIL, | |
34 | EXEC_INPUT_SOCKET, | |
35 | EXEC_INPUT_NAMED_FD, | |
36 | EXEC_INPUT_DATA, | |
37 | EXEC_INPUT_FILE, | |
38 | _EXEC_INPUT_MAX, | |
39 | _EXEC_INPUT_INVALID = -EINVAL, | |
40 | } ExecInput; | |
41 | ||
42 | typedef enum ExecOutput { | |
43 | EXEC_OUTPUT_INHERIT, | |
44 | EXEC_OUTPUT_NULL, | |
45 | EXEC_OUTPUT_TTY, | |
46 | EXEC_OUTPUT_KMSG, | |
47 | EXEC_OUTPUT_KMSG_AND_CONSOLE, | |
48 | EXEC_OUTPUT_JOURNAL, | |
49 | EXEC_OUTPUT_JOURNAL_AND_CONSOLE, | |
50 | EXEC_OUTPUT_SOCKET, | |
51 | EXEC_OUTPUT_NAMED_FD, | |
52 | EXEC_OUTPUT_FILE, | |
53 | EXEC_OUTPUT_FILE_APPEND, | |
54 | EXEC_OUTPUT_FILE_TRUNCATE, | |
55 | _EXEC_OUTPUT_MAX, | |
56 | _EXEC_OUTPUT_INVALID = -EINVAL, | |
57 | } ExecOutput; | |
58 | ||
59 | typedef enum ExecPreserveMode { | |
60 | EXEC_PRESERVE_NO, | |
61 | EXEC_PRESERVE_YES, | |
62 | EXEC_PRESERVE_RESTART, | |
63 | _EXEC_PRESERVE_MODE_MAX, | |
64 | _EXEC_PRESERVE_MODE_INVALID = -EINVAL, | |
65 | } ExecPreserveMode; | |
66 | ||
67 | typedef enum ExecKeyringMode { | |
68 | EXEC_KEYRING_INHERIT, | |
69 | EXEC_KEYRING_PRIVATE, | |
70 | EXEC_KEYRING_SHARED, | |
71 | _EXEC_KEYRING_MODE_MAX, | |
72 | _EXEC_KEYRING_MODE_INVALID = -EINVAL, | |
73 | } ExecKeyringMode; | |
74 | ||
75 | /* Contains start and exit information about an executed command. */ | |
76 | typedef struct ExecStatus { | |
77 | dual_timestamp start_timestamp; | |
78 | dual_timestamp exit_timestamp; | |
79 | dual_timestamp handoff_timestamp; | |
80 | pid_t pid; | |
81 | int code; /* as in siginfo_t::si_code */ | |
82 | int status; /* as in siginfo_t::si_status */ | |
83 | } ExecStatus; | |
84 | ||
85 | /* Stores information about commands we execute. Covers both configuration settings as well as runtime data. */ | |
86 | typedef struct ExecCommand { | |
87 | char *path; | |
88 | char **argv; | |
89 | ExecStatus exec_status; /* Note that this is not serialized to sd-executor */ | |
90 | ExecCommandFlags flags; | |
91 | LIST_FIELDS(ExecCommand, command); /* useful for chaining commands */ | |
92 | } ExecCommand; | |
93 | ||
94 | /* Encapsulates certain aspects of the runtime environment that is to be shared between multiple otherwise separate | |
95 | * invocations of commands. Specifically, this allows sharing of /tmp and /var/tmp data as well as network namespaces | |
96 | * between invocations of commands. This is a reference counted object, with one reference taken by each currently | |
97 | * active command invocation that wants to share this runtime. */ | |
98 | typedef struct ExecSharedRuntime { | |
99 | unsigned n_ref; | |
100 | ||
101 | Manager *manager; | |
102 | ||
103 | char *id; /* Unit id of the owner */ | |
104 | ||
105 | char *tmp_dir; | |
106 | char *var_tmp_dir; | |
107 | ||
108 | /* An AF_UNIX socket pair, that contains a datagram containing a file descriptor referring to the network | |
109 | * namespace. */ | |
110 | int netns_storage_socket[2]; | |
111 | ||
112 | /* Like netns_storage_socket, but the file descriptor is referring to the IPC namespace. */ | |
113 | int ipcns_storage_socket[2]; | |
114 | } ExecSharedRuntime; | |
115 | ||
116 | typedef struct ExecRuntime { | |
117 | ExecSharedRuntime *shared; | |
118 | DynamicCreds *dynamic_creds; | |
119 | ||
120 | /* The path to the ephemeral snapshot of the root directory or root image if one was requested. */ | |
121 | char *ephemeral_copy; | |
122 | ||
123 | /* An AF_UNIX socket pair that receives the locked file descriptor referring to the ephemeral copy of | |
124 | * the root directory or root image. The lock prevents tmpfiles from removing the ephemeral snapshot | |
125 | * until we're done using it. */ | |
126 | int ephemeral_storage_socket[2]; | |
127 | } ExecRuntime; | |
128 | ||
129 | typedef enum ExecDirectoryType { | |
130 | EXEC_DIRECTORY_RUNTIME, | |
131 | EXEC_DIRECTORY_STATE, | |
132 | EXEC_DIRECTORY_CACHE, | |
133 | EXEC_DIRECTORY_LOGS, | |
134 | EXEC_DIRECTORY_CONFIGURATION, | |
135 | _EXEC_DIRECTORY_TYPE_MAX, | |
136 | _EXEC_DIRECTORY_TYPE_INVALID = -EINVAL, | |
137 | } ExecDirectoryType; | |
138 | ||
139 | static inline bool EXEC_DIRECTORY_TYPE_SHALL_CHOWN(ExecDirectoryType t) { | |
140 | /* Returns true for the ExecDirectoryTypes that we shall chown()ing for the user to. We do this for | |
141 | * all of them, except for configuration */ | |
142 | return t >= 0 && t < _EXEC_DIRECTORY_TYPE_MAX && t != EXEC_DIRECTORY_CONFIGURATION; | |
143 | } | |
144 | ||
145 | typedef struct ExecDirectoryItem { | |
146 | char *path; | |
147 | char **symlinks; | |
148 | ExecDirectoryFlags flags; | |
149 | bool idmapped; | |
150 | } ExecDirectoryItem; | |
151 | ||
152 | typedef struct ExecDirectory { | |
153 | mode_t mode; | |
154 | size_t n_items; | |
155 | ExecDirectoryItem *items; | |
156 | } ExecDirectory; | |
157 | ||
158 | typedef enum ExecCleanMask { | |
159 | /* In case you wonder why the bitmask below doesn't use "directory" in its name: we want to keep this | |
160 | * generic so that .timer timestamp files can nicely be covered by this too, and similar. */ | |
161 | EXEC_CLEAN_RUNTIME = 1U << EXEC_DIRECTORY_RUNTIME, | |
162 | EXEC_CLEAN_STATE = 1U << EXEC_DIRECTORY_STATE, | |
163 | EXEC_CLEAN_CACHE = 1U << EXEC_DIRECTORY_CACHE, | |
164 | EXEC_CLEAN_LOGS = 1U << EXEC_DIRECTORY_LOGS, | |
165 | EXEC_CLEAN_CONFIGURATION = 1U << EXEC_DIRECTORY_CONFIGURATION, | |
166 | EXEC_CLEAN_FDSTORE = 1U << _EXEC_DIRECTORY_TYPE_MAX, | |
167 | EXEC_CLEAN_NONE = 0, | |
168 | EXEC_CLEAN_ALL = (1U << (_EXEC_DIRECTORY_TYPE_MAX+1)) - 1, | |
169 | _EXEC_CLEAN_MASK_INVALID = -EINVAL, | |
170 | } ExecCleanMask; | |
171 | ||
172 | /* Encodes configuration parameters applied to invoked commands. Does not carry runtime data, but only configuration | |
173 | * changes sourced from unit files and suchlike. ExecContext objects are usually embedded into Unit objects, and do not | |
174 | * change after being loaded. */ | |
175 | typedef struct ExecContext { | |
176 | char **environment; | |
177 | char **environment_files; | |
178 | char **pass_environment; | |
179 | char **unset_environment; | |
180 | ||
181 | struct rlimit *rlimit[_RLIMIT_MAX]; | |
182 | char *working_directory, *root_directory, *root_image, *root_verity, *root_hash_path, *root_hash_sig_path; | |
183 | void *root_hash, *root_hash_sig; | |
184 | size_t root_hash_size, root_hash_sig_size; | |
185 | LIST_HEAD(MountOptions, root_image_options); | |
186 | bool root_ephemeral; | |
187 | bool working_directory_missing_ok:1; | |
188 | bool working_directory_home:1; | |
189 | ||
190 | bool oom_score_adjust_set:1; | |
191 | bool coredump_filter_set:1; | |
192 | bool nice_set:1; | |
193 | bool ioprio_set:1; | |
194 | bool cpu_sched_set:1; | |
195 | ||
196 | /* This is not exposed to the user but available internally. We need it to make sure that whenever we | |
197 | * spawn /usr/bin/mount it is run in the same process group as us so that the autofs logic detects | |
198 | * that it belongs to us and we don't enter a trigger loop. */ | |
199 | bool same_pgrp; | |
200 | ||
201 | bool cpu_sched_reset_on_fork; | |
202 | bool non_blocking; | |
203 | ||
204 | mode_t umask; | |
205 | int oom_score_adjust; | |
206 | int nice; | |
207 | int ioprio; | |
208 | int cpu_sched_policy; | |
209 | int cpu_sched_priority; | |
210 | uint64_t coredump_filter; | |
211 | ||
212 | CPUSet cpu_set; | |
213 | NUMAPolicy numa_policy; | |
214 | bool cpu_affinity_from_numa; | |
215 | ||
216 | ExecInput std_input; | |
217 | ExecOutput std_output; | |
218 | ExecOutput std_error; | |
219 | ||
220 | /* At least one of stdin/stdout/stderr was initialized from an fd passed in. This boolean survives | |
221 | * the fds being closed. This only makes sense for transient units. */ | |
222 | bool stdio_as_fds; | |
223 | ||
224 | char *stdio_fdname[3]; | |
225 | char *stdio_file[3]; | |
226 | ||
227 | void *stdin_data; | |
228 | size_t stdin_data_size; | |
229 | ||
230 | nsec_t timer_slack_nsec; | |
231 | ||
232 | char *tty_path; | |
233 | ||
234 | bool tty_reset; | |
235 | bool tty_vhangup; | |
236 | bool tty_vt_disallocate; | |
237 | ||
238 | unsigned tty_rows; | |
239 | unsigned tty_cols; | |
240 | ||
241 | bool ignore_sigpipe; | |
242 | ||
243 | ExecKeyringMode keyring_mode; | |
244 | ||
245 | /* Since resolving these names might involve socket | |
246 | * connections and we don't want to deadlock ourselves these | |
247 | * names are resolved on execution only and in the child | |
248 | * process. */ | |
249 | char *user; | |
250 | char *group; | |
251 | char **supplementary_groups; | |
252 | ||
253 | int set_login_environment; | |
254 | ||
255 | char *pam_name; | |
256 | ||
257 | char *utmp_id; | |
258 | ExecUtmpMode utmp_mode; | |
259 | ||
260 | bool no_new_privileges; | |
261 | ||
262 | bool selinux_context_ignore; | |
263 | bool apparmor_profile_ignore; | |
264 | bool smack_process_label_ignore; | |
265 | ||
266 | char *selinux_context; | |
267 | char *apparmor_profile; | |
268 | char *smack_process_label; | |
269 | ||
270 | char **read_write_paths, **read_only_paths, **inaccessible_paths, **exec_paths, **no_exec_paths; | |
271 | char **exec_search_path; | |
272 | unsigned long mount_propagation_flag; | |
273 | BindMount *bind_mounts; | |
274 | size_t n_bind_mounts; | |
275 | TemporaryFileSystem *temporary_filesystems; | |
276 | size_t n_temporary_filesystems; | |
277 | MountImage *mount_images; | |
278 | size_t n_mount_images; | |
279 | MountImage *extension_images; | |
280 | size_t n_extension_images; | |
281 | char **extension_directories; | |
282 | ||
283 | uint64_t capability_bounding_set; | |
284 | uint64_t capability_ambient_set; | |
285 | int secure_bits; | |
286 | ||
287 | int syslog_priority; | |
288 | bool syslog_level_prefix; | |
289 | char *syslog_identifier; | |
290 | ||
291 | struct iovec* log_extra_fields; | |
292 | size_t n_log_extra_fields; | |
293 | Set *log_filter_allowed_patterns; | |
294 | Set *log_filter_denied_patterns; | |
295 | ||
296 | RateLimit log_ratelimit; | |
297 | ||
298 | int log_level_max; | |
299 | ||
300 | char *log_namespace; | |
301 | ||
302 | ProtectProc protect_proc; /* hidepid= */ | |
303 | ProcSubset proc_subset; /* subset= */ | |
304 | ||
305 | int private_mounts; | |
306 | int mount_apivfs; | |
307 | int bind_log_sockets; | |
308 | int memory_ksm; | |
309 | PrivateTmp private_tmp; | |
310 | PrivateTmp private_var_tmp; /* This is not an independent parameter, but calculated from other | |
311 | * parameters in unit_patch_contexts(). */ | |
312 | bool private_network; | |
313 | bool private_devices; | |
314 | PrivateUsers private_users; | |
315 | bool private_ipc; | |
316 | bool protect_kernel_tunables; | |
317 | bool protect_kernel_modules; | |
318 | bool protect_kernel_logs; | |
319 | bool protect_clock; | |
320 | ProtectControlGroups protect_control_groups; | |
321 | ProtectSystem protect_system; | |
322 | ProtectHome protect_home; | |
323 | PrivatePIDs private_pids; | |
324 | ProtectHostname protect_hostname; | |
325 | char *private_hostname; | |
326 | ||
327 | bool dynamic_user; | |
328 | bool remove_ipc; | |
329 | ||
330 | bool memory_deny_write_execute; | |
331 | bool restrict_realtime; | |
332 | bool restrict_suid_sgid; | |
333 | ||
334 | bool lock_personality; | |
335 | unsigned long personality; | |
336 | ||
337 | unsigned long restrict_namespaces; /* The CLONE_NEWxyz flags permitted to the unit's processes */ | |
338 | unsigned long delegate_namespaces; /* The CLONE_NEWxyz flags delegated to the unit's processes */ | |
339 | ||
340 | Set *restrict_filesystems; | |
341 | bool restrict_filesystems_allow_list:1; | |
342 | ||
343 | Hashmap *syscall_filter; | |
344 | Set *syscall_archs; | |
345 | int syscall_errno; | |
346 | bool syscall_allow_list:1; | |
347 | ||
348 | Hashmap *syscall_log; | |
349 | bool syscall_log_allow_list:1; /* Log listed system calls */ | |
350 | ||
351 | bool address_families_allow_list:1; | |
352 | Set *address_families; | |
353 | ||
354 | char *network_namespace_path; | |
355 | char *ipc_namespace_path; | |
356 | ||
357 | ExecDirectory directories[_EXEC_DIRECTORY_TYPE_MAX]; | |
358 | ExecPreserveMode runtime_directory_preserve_mode; | |
359 | usec_t timeout_clean_usec; | |
360 | ||
361 | Hashmap *set_credentials; /* output id → ExecSetCredential */ | |
362 | Hashmap *load_credentials; /* output id → ExecLoadCredential */ | |
363 | OrderedSet *import_credentials; /* ExecImportCredential */ | |
364 | ||
365 | ImagePolicy *root_image_policy, *mount_image_policy, *extension_image_policy; | |
366 | } ExecContext; | |
367 | ||
368 | typedef enum ExecFlags { | |
369 | EXEC_APPLY_SANDBOXING = 1 << 0, | |
370 | EXEC_APPLY_CHROOT = 1 << 1, | |
371 | EXEC_APPLY_TTY_STDIN = 1 << 2, | |
372 | EXEC_PASS_LOG_UNIT = 1 << 3, /* Whether to pass the unit name to the service's journal stream connection */ | |
373 | EXEC_CHOWN_DIRECTORIES = 1 << 4, /* chown() the runtime/state/cache/log directories to the user we run as, under all conditions */ | |
374 | EXEC_NSS_DYNAMIC_BYPASS = 1 << 5, /* Set the SYSTEMD_NSS_DYNAMIC_BYPASS environment variable, to disable nss-systemd blocking on PID 1, for use by dbus-daemon */ | |
375 | EXEC_CGROUP_DELEGATE = 1 << 6, | |
376 | EXEC_IS_CONTROL = 1 << 7, | |
377 | EXEC_CONTROL_CGROUP = 1 << 8, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */ | |
378 | EXEC_SETUP_CREDENTIALS = 1 << 9, /* Set up the credential store logic */ | |
379 | EXEC_SETUP_CREDENTIALS_FRESH = 1 << 10, /* Set up a new credential store (disable reuse) */ | |
380 | ||
381 | /* The following are not used by execute.c, but by consumers internally */ | |
382 | EXEC_PASS_FDS = 1 << 11, | |
383 | EXEC_SETENV_RESULT = 1 << 12, | |
384 | EXEC_SET_WATCHDOG = 1 << 13, | |
385 | EXEC_SETENV_MONITOR_RESULT = 1 << 14, /* Pass exit status to OnFailure= and OnSuccess= dependencies. */ | |
386 | } ExecFlags; | |
387 | ||
388 | /* Parameters for a specific invocation of a command. This structure is put together right before a command is | |
389 | * executed. */ | |
390 | typedef struct ExecParameters { | |
391 | RuntimeScope runtime_scope; | |
392 | ||
393 | char **environment; | |
394 | ||
395 | int *fds; | |
396 | char **fd_names; | |
397 | size_t n_socket_fds; | |
398 | size_t n_storage_fds; | |
399 | size_t n_extra_fds; | |
400 | ||
401 | ExecFlags flags; | |
402 | bool selinux_context_net:1; | |
403 | ||
404 | CGroupMask cgroup_supported; | |
405 | char *cgroup_path; | |
406 | uint64_t cgroup_id; | |
407 | ||
408 | char **prefix; | |
409 | char *received_credentials_directory; | |
410 | char *received_encrypted_credentials_directory; | |
411 | ||
412 | char *confirm_spawn; | |
413 | bool shall_confirm_spawn; | |
414 | ||
415 | usec_t watchdog_usec; | |
416 | ||
417 | int *idle_pipe; | |
418 | ||
419 | int stdin_fd; | |
420 | int stdout_fd; | |
421 | int stderr_fd; | |
422 | ||
423 | /* An fd that is closed by the execve(), and thus will result in EOF when the execve() is done. */ | |
424 | int exec_fd; | |
425 | ||
426 | char *notify_socket; | |
427 | ||
428 | LIST_HEAD(OpenFile, open_files); | |
429 | ||
430 | char *fallback_smack_process_label; | |
431 | ||
432 | char **files_env; | |
433 | int user_lookup_fd; | |
434 | int handoff_timestamp_fd; | |
435 | int pidref_transport_fd; | |
436 | ||
437 | int bpf_restrict_fs_map_fd; | |
438 | ||
439 | /* Used for logging in the executor functions */ | |
440 | char *unit_id; | |
441 | sd_id128_t invocation_id; | |
442 | char invocation_id_string[SD_ID128_STRING_MAX]; | |
443 | ||
444 | bool debug_invocation; | |
445 | } ExecParameters; | |
446 | ||
447 | #define EXEC_PARAMETERS_INIT(_flags) \ | |
448 | (ExecParameters) { \ | |
449 | .flags = (_flags), \ | |
450 | .stdin_fd = -EBADF, \ | |
451 | .stdout_fd = -EBADF, \ | |
452 | .stderr_fd = -EBADF, \ | |
453 | .exec_fd = -EBADF, \ | |
454 | .bpf_restrict_fs_map_fd = -EBADF, \ | |
455 | .user_lookup_fd = -EBADF, \ | |
456 | .handoff_timestamp_fd = -EBADF, \ | |
457 | .pidref_transport_fd = -EBADF, \ | |
458 | } | |
459 | ||
460 | int exec_spawn( | |
461 | Unit *unit, | |
462 | ExecCommand *command, | |
463 | const ExecContext *context, | |
464 | ExecParameters *exec_params, | |
465 | ExecRuntime *runtime, | |
466 | const CGroupContext *cgroup_context, | |
467 | PidRef *ret); | |
468 | ||
469 | void exec_command_done(ExecCommand *c); | |
470 | void exec_command_done_array(ExecCommand *c, size_t n); | |
471 | ExecCommand* exec_command_free(ExecCommand *c); | |
472 | DEFINE_TRIVIAL_CLEANUP_FUNC(ExecCommand*, exec_command_free); | |
473 | ExecCommand* exec_command_free_list(ExecCommand *c); | |
474 | void exec_command_free_array(ExecCommand **c, size_t n); | |
475 | void exec_command_reset_status_array(ExecCommand *c, size_t n); | |
476 | void exec_command_reset_status_list_array(ExecCommand **c, size_t n); | |
477 | ||
478 | void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix); | |
479 | void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix); | |
480 | void exec_command_append_list(ExecCommand **l, ExecCommand *e); | |
481 | int exec_command_set(ExecCommand *c, const char *path, ...) _sentinel_; | |
482 | int exec_command_append(ExecCommand *c, const char *path, ...) _sentinel_; | |
483 | ||
484 | void exec_context_init(ExecContext *c); | |
485 | void exec_context_done(ExecContext *c); | |
486 | void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix); | |
487 | ||
488 | int exec_context_destroy_runtime_directory(const ExecContext *c, const char *runtime_root); | |
489 | int exec_context_destroy_mount_ns_dir(Unit *u); | |
490 | ||
491 | const char* exec_context_fdname(const ExecContext *c, int fd_index); | |
492 | ||
493 | bool exec_context_may_touch_console(const ExecContext *c); | |
494 | bool exec_context_maintains_privileges(const ExecContext *c); | |
495 | bool exec_context_shall_ansi_seq_reset(const ExecContext *c); | |
496 | ||
497 | int exec_context_get_effective_ioprio(const ExecContext *c); | |
498 | bool exec_context_get_effective_mount_apivfs(const ExecContext *c); | |
499 | bool exec_context_get_effective_bind_log_sockets(const ExecContext *c); | |
500 | ||
501 | void exec_context_free_log_extra_fields(ExecContext *c); | |
502 | ||
503 | void exec_context_revert_tty(ExecContext *c, sd_id128_t invocation_id); | |
504 | ||
505 | int exec_context_get_clean_directories(ExecContext *c, char **prefix, ExecCleanMask mask, char ***ret); | |
506 | int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret); | |
507 | ||
508 | const char* exec_context_tty_path(const ExecContext *context); | |
509 | int exec_context_apply_tty_size(const ExecContext *context, int input_fd, int output_fd, const char *tty_path); | |
510 | void exec_context_tty_reset(const ExecContext *context, const ExecParameters *parameters, sd_id128_t invocation_id); | |
511 | ||
512 | uint64_t exec_context_get_rlimit(const ExecContext *c, const char *name); | |
513 | int exec_context_get_oom_score_adjust(const ExecContext *c); | |
514 | uint64_t exec_context_get_coredump_filter(const ExecContext *c); | |
515 | int exec_context_get_nice(const ExecContext *c); | |
516 | int exec_context_get_cpu_sched_policy(const ExecContext *c); | |
517 | int exec_context_get_cpu_sched_priority(const ExecContext *c); | |
518 | uint64_t exec_context_get_timer_slack_nsec(const ExecContext *c); | |
519 | bool exec_context_get_set_login_environment(const ExecContext *c); | |
520 | char** exec_context_get_syscall_filter(const ExecContext *c); | |
521 | char** exec_context_get_syscall_archs(const ExecContext *c); | |
522 | char** exec_context_get_syscall_log(const ExecContext *c); | |
523 | char** exec_context_get_address_families(const ExecContext *c); | |
524 | char** exec_context_get_restrict_filesystems(const ExecContext *c); | |
525 | bool exec_context_restrict_namespaces_set(const ExecContext *c); | |
526 | bool exec_context_restrict_filesystems_set(const ExecContext *c); | |
527 | bool exec_context_with_rootfs(const ExecContext *c); | |
528 | ||
529 | int exec_context_has_vpicked_extensions(const ExecContext *context); | |
530 | ||
531 | void exec_status_start(ExecStatus *s, pid_t pid, const dual_timestamp *ts); | |
532 | void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status); | |
533 | void exec_status_handoff(ExecStatus *s, const struct ucred *ucred, const dual_timestamp *ts); | |
534 | void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix); | |
535 | void exec_status_reset(ExecStatus *s); | |
536 | ||
537 | int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *name, bool create, ExecSharedRuntime **ret); | |
538 | ExecSharedRuntime *exec_shared_runtime_destroy(ExecSharedRuntime *r); | |
539 | ExecSharedRuntime *exec_shared_runtime_unref(ExecSharedRuntime *r); | |
540 | DEFINE_TRIVIAL_CLEANUP_FUNC(ExecSharedRuntime*, exec_shared_runtime_unref); | |
541 | ||
542 | int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds); | |
543 | int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds); | |
544 | int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds); | |
545 | void exec_shared_runtime_done(ExecSharedRuntime *rt); | |
546 | void exec_shared_runtime_vacuum(Manager *m); | |
547 | ||
548 | int exec_runtime_make(const Unit *unit, const ExecContext *context, ExecSharedRuntime *shared, DynamicCreds *creds, ExecRuntime **ret); | |
549 | ExecRuntime* exec_runtime_free(ExecRuntime *rt); | |
550 | DEFINE_TRIVIAL_CLEANUP_FUNC(ExecRuntime*, exec_runtime_free); | |
551 | ExecRuntime* exec_runtime_destroy(ExecRuntime *rt); | |
552 | void exec_runtime_clear(ExecRuntime *rt); | |
553 | ||
554 | int exec_params_needs_control_subcgroup(const ExecParameters *params); | |
555 | int exec_params_get_cgroup_path(const ExecParameters *params, const CGroupContext *c, const char *prefix, char **ret); | |
556 | void exec_params_shallow_clear(ExecParameters *p); | |
557 | void exec_params_dump(const ExecParameters *p, FILE* f, const char *prefix); | |
558 | void exec_params_deep_clear(ExecParameters *p); | |
559 | ||
560 | bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c); | |
561 | ||
562 | void exec_directory_done(ExecDirectory *d); | |
563 | int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink, ExecDirectoryFlags flags); | |
564 | void exec_directory_sort(ExecDirectory *d); | |
565 | bool exec_directory_is_private(const ExecContext *context, ExecDirectoryType type); | |
566 | ||
567 | ExecCleanMask exec_clean_mask_from_string(const char *s); | |
568 | ||
569 | const char* exec_output_to_string(ExecOutput i) _const_; | |
570 | ExecOutput exec_output_from_string(const char *s) _pure_; | |
571 | ||
572 | const char* exec_input_to_string(ExecInput i) _const_; | |
573 | ExecInput exec_input_from_string(const char *s) _pure_; | |
574 | ||
575 | const char* exec_utmp_mode_to_string(ExecUtmpMode i) _const_; | |
576 | ExecUtmpMode exec_utmp_mode_from_string(const char *s) _pure_; | |
577 | ||
578 | const char* exec_preserve_mode_to_string(ExecPreserveMode i) _const_; | |
579 | ExecPreserveMode exec_preserve_mode_from_string(const char *s) _pure_; | |
580 | ||
581 | const char* exec_keyring_mode_to_string(ExecKeyringMode i) _const_; | |
582 | ExecKeyringMode exec_keyring_mode_from_string(const char *s) _pure_; | |
583 | ||
584 | const char* exec_directory_type_to_string(ExecDirectoryType i) _const_; | |
585 | ExecDirectoryType exec_directory_type_from_string(const char *s) _pure_; | |
586 | ||
587 | const char* exec_directory_type_symlink_to_string(ExecDirectoryType i) _const_; | |
588 | ExecDirectoryType exec_directory_type_symlink_from_string(const char *s) _pure_; | |
589 | ||
590 | const char* exec_directory_type_mode_to_string(ExecDirectoryType i) _const_; | |
591 | ExecDirectoryType exec_directory_type_mode_from_string(const char *s) _pure_; | |
592 | ||
593 | const char* exec_resource_type_to_string(ExecDirectoryType i) _const_; | |
594 | ExecDirectoryType exec_resource_type_from_string(const char *s) _pure_; | |
595 | ||
596 | bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime); | |
597 | bool exec_needs_network_namespace(const ExecContext *context); | |
598 | bool exec_needs_ipc_namespace(const ExecContext *context); | |
599 | bool exec_needs_pid_namespace(const ExecContext *context, const ExecParameters *params); | |
600 | ||
601 | ProtectControlGroups exec_get_protect_control_groups(const ExecContext *context); | |
602 | bool exec_needs_cgroup_namespace(const ExecContext *context); | |
603 | bool exec_needs_cgroup_mount(const ExecContext *context); | |
604 | bool exec_is_cgroup_mount_read_only(const ExecContext *context); | |
605 | ||
606 | const char* exec_get_private_notify_socket_path(const ExecContext *context, const ExecParameters *params, bool needs_sandboxing); | |
607 | ||
608 | int exec_log_level_max(const ExecContext *context, const ExecParameters *params); | |
609 | ||
610 | /* These logging macros do the same logging as those in unit.h, but using ExecContext and ExecParameters | |
611 | * instead of the unit object, so that it can be used in the sd-executor context (where the unit object is | |
612 | * not available). */ | |
613 | ||
614 | #define LOG_EXEC_ID_FIELD(ep) \ | |
615 | ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_UNIT=" : "UNIT=") | |
616 | #define LOG_EXEC_INVOCATION_ID_FIELD(ep) \ | |
617 | ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_INVOCATION_ID=" : "INVOCATION_ID=") | |
618 | ||
619 | /* Like LOG_MESSAGE(), but with the unit name prefixed. */ | |
620 | #define LOG_EXEC_MESSAGE(ep, fmt, ...) LOG_MESSAGE("%s: " fmt, (ep)->unit_id, ##__VA_ARGS__) | |
621 | #define LOG_EXEC_ID(ep) LOG_ITEM("%s%s", LOG_EXEC_ID_FIELD(ep), (ep)->unit_id) | |
622 | #define LOG_EXEC_INVOCATION_ID(ep) LOG_ITEM("%s%s", LOG_EXEC_INVOCATION_ID_FIELD(ep), (ep)->invocation_id_string) | |
623 | ||
624 | #define _LOG_CONTEXT_PUSH_EXEC(ec, ep, p, c) \ | |
625 | const ExecContext *c = (ec); \ | |
626 | const ExecParameters *p = (ep); \ | |
627 | LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_ID_FIELD(p), p->unit_id); \ | |
628 | LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_INVOCATION_ID_FIELD(p), p->invocation_id_string); \ | |
629 | LOG_CONTEXT_PUSH_IOV(c->log_extra_fields, c->n_log_extra_fields) \ | |
630 | LOG_CONTEXT_SET_LOG_LEVEL(exec_log_level_max(c, p)) \ | |
631 | LOG_SET_PREFIX(p->unit_id); | |
632 | ||
633 | #define LOG_CONTEXT_PUSH_EXEC(ec, ep) \ | |
634 | _LOG_CONTEXT_PUSH_EXEC(ec, ep, UNIQ_T(p, UNIQ), UNIQ_T(c, UNIQ)) |