From be7e509e89dff09a569fb035b4e03a5084038922 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 15 Sep 2017 16:41:19 +0200 Subject: [PATCH 1/3] exit-status: drop EXIT_MAKE_STARTER This is unused since kdbus has been removed. --- src/basic/exit-status.c | 3 --- src/basic/exit-status.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c index fba012601d7..7cfebbae729 100644 --- a/src/basic/exit-status.c +++ b/src/basic/exit-status.c @@ -140,9 +140,6 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { case EXIT_RUNTIME_DIRECTORY: return "RUNTIME_DIRECTORY"; - case EXIT_MAKE_STARTER: - return "MAKE_STARTER"; - case EXIT_CHOWN: return "CHOWN"; diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h index e2c76f84f8d..195b3bc4865 100644 --- a/src/basic/exit-status.h +++ b/src/basic/exit-status.h @@ -79,7 +79,7 @@ enum { EXIT_APPARMOR_PROFILE, EXIT_ADDRESS_FAMILIES, EXIT_RUNTIME_DIRECTORY, - EXIT_MAKE_STARTER, + _EXIT_RESERVED2, /* used to be used by kdbus, don't reuse */ EXIT_CHOWN, EXIT_SMACK_PROCESS_LABEL, EXIT_KEYRING, From 0460aa5c0862cfc39d05ddfece35ba4f7b6cd929 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 15 Sep 2017 16:42:09 +0200 Subject: [PATCH 2/3] execute: improve and augment execution log messages Let's generate friendly messages for more cases, and make slight adjustments to the existing messages. --- src/core/execute.c | 50 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index e2d84feb0dd..9e1add3e7f3 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2399,7 +2399,7 @@ static int exec_child( r = reset_signal_mask(); if (r < 0) { *exit_status = EXIT_SIGNAL_MASK; - *error_message = strdup("Failed to reset signal mask"); + *error_message = strdup("Failed to set process signal mask"); /* If strdup fails, here and below, we will just print the generic error message. */ return r; } @@ -2417,13 +2417,14 @@ static int exec_child( r = close_remaining_fds(params, runtime, dcreds, user_lookup_fd, socket_fd, fds, n_fds); if (r < 0) { *exit_status = EXIT_FDS; - *error_message = strdup("Failed to close remaining fds"); + *error_message = strdup("Failed to close unwanted file descriptors"); return r; } if (!context->same_pgrp) if (setsid() < 0) { *exit_status = EXIT_SETSID; + *error_message = strdup("Failed to create new process session"); return -errno; } @@ -2435,7 +2436,7 @@ static int exec_child( cmdline = exec_command_line(argv); if (!cmdline) { - *exit_status = EXIT_CONFIRM; + *exit_status = EXIT_MEMORY; return -ENOMEM; } @@ -2446,7 +2447,7 @@ static int exec_child( return 0; } *exit_status = EXIT_CONFIRM; - *error_message = strdup("Execution cancelled"); + *error_message = strdup("Execution cancelled by the user"); return -ECANCELED; } } @@ -2532,21 +2533,21 @@ static int exec_child( r = setup_input(context, params, socket_fd, named_iofds); if (r < 0) { *exit_status = EXIT_STDIN; - *error_message = strdup("Failed to set up stdin"); + *error_message = strdup("Failed to set up standard input"); return r; } r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDOUT; - *error_message = strdup("Failed to set up stdout"); + *error_message = strdup("Failed to set up standard output"); return r; } r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDERR; - *error_message = strdup("Failed to set up stderr"); + *error_message = strdup("Failed to set up standard error output"); return r; } @@ -2575,7 +2576,7 @@ static int exec_child( log_close(); } else if (r < 0) { *exit_status = EXIT_OOM_ADJUST; - *error_message = strdup("Failed to write /proc/self/oom_score_adj"); + *error_message = strdup("Failed to adjust OOM setting"); return -errno; } } @@ -2583,6 +2584,7 @@ static int exec_child( if (context->nice_set) if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) { *exit_status = EXIT_NICE; + *error_message = strdup("Failed to set up process scheduling priority (nice level"); return -errno; } @@ -2598,6 +2600,7 @@ static int exec_child( ¶m); if (r < 0) { *exit_status = EXIT_SETSCHEDULER; + *error_message = strdup("Failed to set up CPU scheduling"); return -errno; } } @@ -2605,18 +2608,21 @@ static int exec_child( if (context->cpuset) if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) { *exit_status = EXIT_CPUAFFINITY; + *error_message = strdup("Failed to set up CPU affinity"); return -errno; } if (context->ioprio_set) if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { *exit_status = EXIT_IOPRIO; + *error_message = strdup("Failed to set up IO scheduling priority"); return -errno; } if (context->timer_slack_nsec != NSEC_INFINITY) if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { *exit_status = EXIT_TIMERSLACK; + *error_message = strdup("Failed to set up timer slack"); return -errno; } @@ -2624,6 +2630,7 @@ static int exec_child( r = safe_personality(context->personality); if (r < 0) { *exit_status = EXIT_PERSONALITY; + *error_message = strdup("Failed to set up execution domain (personality)"); return r; } } @@ -2640,6 +2647,7 @@ static int exec_child( r = chown_terminal(STDIN_FILENO, uid); if (r < 0) { *exit_status = EXIT_STDIN; + *error_message = strdup("Failed to change ownership of terminal"); return r; } } @@ -2651,6 +2659,7 @@ static int exec_child( r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid); if (r < 0) { *exit_status = EXIT_CGROUP; + *error_message = strdup("Failed to adjust control group access"); return r; } @@ -2658,14 +2667,17 @@ static int exec_child( r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid); if (r < 0) { *exit_status = EXIT_CGROUP; + *error_message = strdup("Failed to adjust control group access"); return r; } } for (dt = 0; dt < _EXEC_DIRECTORY_MAX; dt++) { r = setup_exec_directory(context, params, uid, gid, dt, exit_status); - if (r < 0) + if (r < 0) { + *error_message = strdup("Failed to set up special execution directory"); return r; + } } r = build_environment( @@ -2708,6 +2720,7 @@ static int exec_child( r = setup_keyring(unit, params, uid, gid); if (r < 0) { *exit_status = EXIT_KEYRING; + *error_message = strdup("Failed to set up kernel keyring"); return r; } @@ -2744,6 +2757,7 @@ static int exec_child( r = setup_pam(context->pam_name, username, uid, gid, context->tty_path, &accum_env, fds, n_fds); if (r < 0) { *exit_status = EXIT_PAM; + *error_message = strdup("Failed to set up PAM session"); return r; } } @@ -2753,6 +2767,7 @@ static int exec_child( r = setup_netns(runtime->netns_storage_socket); if (r < 0) { *exit_status = EXIT_NETWORK; + *error_message = strdup("Failed to set up network namespacing"); return r; } } @@ -2762,19 +2777,23 @@ static int exec_child( r = apply_mount_namespace(unit, command, context, params, runtime); if (r < 0) { *exit_status = EXIT_NAMESPACE; + *error_message = strdup("Failed to set up mount namespacing"); return r; } } /* Apply just after mount namespace setup */ r = apply_working_directory(context, params, home, needs_mount_namespace, exit_status); - if (r < 0) + if (r < 0) { + *error_message = strdup("Changing to the requested working directory failed"); return r; + } /* Drop groups as early as possbile */ if (needs_setuid) { r = enforce_groups(context, gid, supplementary_gids, ngids); if (r < 0) { + *error_message = strdup("Changing group credentials failed"); *exit_status = EXIT_GROUP; return r; } @@ -2785,6 +2804,7 @@ static int exec_child( if (use_selinux && params->selinux_context_net && socket_fd >= 0) { r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net); if (r < 0) { + *error_message = strdup("Failed to determine SELinux context"); *exit_status = EXIT_SELINUX_CONTEXT; return r; } @@ -2794,6 +2814,7 @@ static int exec_child( if (context->private_users) { r = setup_private_users(uid, gid); if (r < 0) { + *error_message = strdup("Failed to set up user namespacing"); *exit_status = EXIT_USER; return r; } @@ -2809,6 +2830,7 @@ static int exec_child( if (r >= 0) r = flags_fds(fds, n_storage_fds, n_socket_fds, context->non_blocking); if (r < 0) { + *error_message = strdup("Failed to adjust passed file descriptors"); *exit_status = EXIT_FDS; return r; } @@ -2825,6 +2847,7 @@ static int exec_child( r = setrlimit_closest(i, context->rlimit[i]); if (r < 0) { + *error_message = strdup("Failed to adjust resource limits"); *exit_status = EXIT_LIMITS; return r; } @@ -2833,6 +2856,7 @@ static int exec_child( /* Set the RTPRIO resource limit to 0, but only if nothing else was explicitly requested. */ if (context->restrict_realtime && !context->rlimit[RLIMIT_RTPRIO]) { if (setrlimit(RLIMIT_RTPRIO, &RLIMIT_MAKE_CONST(0)) < 0) { + *error_message = strdup("Failed to adjust RLIMIT_RTPRIO resource limit"); *exit_status = EXIT_LIMITS; return -errno; } @@ -2915,7 +2939,7 @@ static int exec_child( r = setexeccon(exec_context); if (r < 0) { *exit_status = EXIT_SELINUX_CONTEXT; - (void) asprintf(error_message, "Failed to set SELinux context to %s", exec_context); + (void) asprintf(error_message, "Failed to change SELinux context to %s", exec_context); return r; } } @@ -2951,7 +2975,7 @@ static int exec_child( if (prctl(PR_GET_SECUREBITS) != secure_bits) if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) { *exit_status = EXIT_SECUREBITS; - *error_message = strdup("Failed to set secure bits"); + *error_message = strdup("Failed to set process secure bits"); return -errno; } @@ -3031,7 +3055,7 @@ static int exec_child( r = apply_syscall_filter(unit, context, needs_ambient_hack); if (r < 0) { *exit_status = EXIT_SECCOMP; - *error_message = strdup("Failed to apply syscall filters"); + *error_message = strdup("Failed to apply system call filters"); return r; } #endif From 91a8f867b6fcdb9b2c4074b571e992e6c7869428 Mon Sep 17 00:00:00 2001 From: Jan Synacek Date: Thu, 26 Jan 2017 13:45:46 +0100 Subject: [PATCH 3/3] doc: document service exit codes (Heavily reworked by Lennart while rebasing) Fixes: #3545 Replaces: #5159 --- man/systemd.exec.xml | 310 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 53daff0f641..61e51becc6e 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2197,6 +2197,316 @@ CapabilityBoundingSet=~CAP_B CAP_C + + Process exit codes + + When invoking a unit process the service manager possibly fails to apply the execution parameters configured + with the settings above. In that case the already created service process will exit with a non-zero exit code + before the configured command line is executed. (Or in other words, the child process possibly exits with these + error codes, after having been created by the fork2 system call, but + before the matching execve2 system call is + called.) Specifically, exit codes defined by the C library, by the LSB specification and by the systemd service + manager itself are used. + + The following basic service exit codes are defined by the C library. + + + Basic C library exit codes + + + + Exit Code + Symbolic Name + Description + + + + + 0 + EXIT_SUCCESS + Generic success code. + + + 1 + EXIT_FAILURE + Generic failure or unspecified error. + + + +
+ + The following service exit codes are defined by the LSB specification + . + + + + LSB service exit codes + + + + Exit Code + Symbolic Name + Description + + + + + 2 + EXIT_INVALIDARGUMENT + Invalid or excess arguments. + + + 3 + EXIT_NOTIMPLEMENTED + Unimplemented feature. + + + 4 + EXIT_NOPERMISSION + The user has insufficient privileges. + + + 5 + EXIT_NOTINSTALLED + The program is not installed. + + + 6 + EXIT_NOTCONFIGURED + The program is not configured. + + + 7 + EXIT_NOTRUNNING + The program is not running. + + + +
+ + + The LSB specification suggests that error codes 200 and above are reserved for implementations. Some of them are + used by the service manager to indicate problems during process invocation: + + + systemd-specific exit codes + + + + Exit Code + Symbolic Name + Description + + + + + 200 + EXIT_CHDIR + Changing to the requested working directory failed. See WorkingDirectory= above. + + + 201 + EXIT_NICE + Failed to set up process scheduling priority (nice level). See Nice= above. + + + 202 + EXIT_FDS + Failed to close unwanted file descriptors, or to adjust passed file descriptors. + + + 203 + EXIT_EXEC + The actual process execution failed (specifically, the execve2 system call). Most likely this is caused by a missing or non-accessible executable file. + + + 204 + EXIT_MEMORY + Failed to perform an action due to memory shortage. + + + 205 + EXIT_LIMITS + Failed to adjust resoure limits. See LimitCPU= and related settings above. + + + 206 + EXIT_OOM_ADJUST + Failed to adjust the OOM setting. See OOMScoreAdjust= above. + + + 207 + EXIT_SIGNAL_MASK + Failed to set process signal mask. + + + 208 + EXIT_STDIN + Failed to set up standard input. See StandardInput= above. + + + 209 + EXIT_STDOUT + Failed to set up standard output. See StandardOutput= above. + + + 210 + EXIT_CHROOT + Failed to change root directory (chroot2). See RootDirectory=/RootImage= above. + + + 211 + EXIT_IOPRIO + Failed to set up IO scheduling priority. See IOSchedulingClass=/IOSchedulingPriority= above. + + + 212 + EXIT_TIMERSLACK + Failed to set up timer slack. See TimerSlackNSec= above. + + + 213 + EXIT_SECUREBITS + Failed to set process secure bits. See SecureBits= above. + + + 214 + EXIT_SETSCHEDULER + Failed to set up CPU scheduling. See CPUSchedulingPolicy=/CPUSchedulingPriority= above. + + + 215 + EXIT_CPUAFFINITY + Failed to set up CPU affinity. See CPUAffinity= above. + + + 216 + EXIT_GROUP + Failed to determine or change group credentials. See Group=/SupplementaryGroups= above. + + + 217 + EXIT_USER + Failed to determine or change user credentials, or to set up user namespacing. See User=/PrivateUsers= above. + + + 218 + EXIT_CAPABILITIES + Failed to drop capabilities, or apply ambient capabilities. See CapabilityBoundingSet=/AmbientCapabilities= above. + + + 219 + EXIT_CGROUP + Setting up the service control group failed. + + + 220 + EXIT_SETSID + Failed to create new process session. + + + 221 + EXIT_CONFIRM + Execution has been cancelled by the user. See the systemd.confirm_spawn= kernel command line setting on kernel-command-line7 for details. + + + 222 + EXIT_STDERR + Failed to set up standard error output. See StandardError= above. + + + 224 + EXIT_PAM + Failed to set up PAM session. See PAMName= above. + + + 225 + EXIT_NETWORK + Failed to set up network namespacing. See PrivateNetwork= above. + + + 226 + EXIT_NAMESPACE + Failed to set up mount namespacing. See ReadOnlyPaths= and related settings above. + + + 227 + EXIT_NO_NEW_PRIVILEGES + Failed to disable new priviliges. See NoNewPrivileges=yes above. + + + 228 + EXIT_SECCOMP + Failed to apply system call filters. See SystemCallFilter= and related settings above. + + + 229 + EXIT_SELINUX_CONTEXT + Determining or changing SELinux context failed. See SELinuxContext= above. + + + 230 + EXIT_PERSONALITY + Failed to set up a execution domain (personality). See Personality= above. + + + 231 + EXIT_APPARMOR_PROFILE + Failed to prepare changing AppArmor profile. See AppArmorProfile= above. + + + 232 + EXIT_ADDRESS_FAMILIES + Failed to restrict address families. See RestrictAddressFamilies= above. + + + 233 + EXIT_RUNTIME_DIRECTORY + Setting up runtime directory failed. See RuntimeDirectory= and related settings above. + + + 235 + EXIT_CHOWN + Failed to adjust socket ownership. Used for socket units only. + + + 236 + EXIT_SMACK_PROCESS_LABEL + Failed to set SMACK label. See SmackProcessLabel= above. + + + 237 + EXIT_KEYRING + Failed to set up kernel keyring. + + + 238 + EXIT_STATE_DIRECTORY + Failed to set up a the unit's state directory. See StateDirectory= above. + + + 239 + EXIT_CACHE_DIRECTORY + Failed to set up a the unit's cache directory. See CacheDirectory= above. + + + 240 + EXIT_LOGS_DIRECTORY + Failed to set up a the unit's logging directory. See LogsDirectory= above. + + + 241 + EXIT_CONFIGURATION_DIRECTORY + Failed to set up a the unit's configuration directory. See ConfigurationDirectory= above. + + + +
+
+ See Also