diff options
author | Michal Schmidt <mschmidt@redhat.com> | 2011-11-17 00:21:16 +0100 |
---|---|---|
committer | Michal Schmidt <mschmidt@redhat.com> | 2011-11-17 01:36:11 +0100 |
commit | 4c2630ebf23b6348174f0bdf1110e90efe45259c (patch) | |
tree | c4f6f05327aadffdbb49314492309cac031ac391 /src/execute.c | |
parent | 9ba353983adc026b75a503c1381f6e5c8062f3e0 (diff) |
execute: log errors from "sd(EXEC)"
To give the administrator more hints about failures occuring in spawning
of commands than just the exit code, log the strerror.
All fds are closed, so reopen the log.
Related-to: https://bugzilla.redhat.com/show_bug.cgi?id=752901
Diffstat (limited to 'src/execute.c')
-rw-r--r-- | src/execute.c | 138 |
1 files changed, 102 insertions, 36 deletions
diff --git a/src/execute.c b/src/execute.c index 2039861782..481725d63d 100644 --- a/src/execute.c +++ b/src/execute.c @@ -989,7 +989,7 @@ int exec_spawn(ExecCommand *command, } if (pid == 0) { - int i; + int i, err; sigset_t ss; const char *username = NULL, *home = NULL; uid_t uid = (uid_t) -1; @@ -1015,6 +1015,7 @@ int exec_spawn(ExecCommand *command, if (sigemptyset(&ss) < 0 || sigprocmask(SIG_SETMASK, &ss, NULL) < 0) { + err = -errno; r = EXIT_SIGNAL_MASK; goto fail_child; } @@ -1023,14 +1024,16 @@ int exec_spawn(ExecCommand *command, * block init reexecution because it cannot bind its * sockets */ log_forget_fds(); - if (close_all_fds(socket_fd >= 0 ? &socket_fd : fds, - socket_fd >= 0 ? 1 : n_fds) < 0) { + err = close_all_fds(socket_fd >= 0 ? &socket_fd : fds, + socket_fd >= 0 ? 1 : n_fds); + if (err < 0) { r = EXIT_FDS; goto fail_child; } if (!context->same_pgrp) if (setsid() < 0) { + err = -errno; r = EXIT_SETSID; goto fail_child; } @@ -1038,12 +1041,14 @@ int exec_spawn(ExecCommand *command, if (context->tcpwrap_name) { if (socket_fd >= 0) if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) { + err = -EACCES; r = EXIT_TCPWRAP; goto fail_child; } for (i = 0; i < (int) n_fds; i++) { if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) { + err = -EACCES; r = EXIT_TCPWRAP; goto fail_child; } @@ -1059,11 +1064,14 @@ int exec_spawn(ExecCommand *command, /* Set up terminal for the question */ if ((r = setup_confirm_stdio(context, - &saved_stdin, &saved_stdout))) + &saved_stdin, &saved_stdout))) { + err = -errno; goto fail_child; + } /* Now ask the question. */ if (!(line = exec_command_line(argv))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1072,18 +1080,21 @@ int exec_spawn(ExecCommand *command, free(line); if (r < 0 || response == 'n') { + err = -ECANCELED; r = EXIT_CONFIRM; goto fail_child; } else if (response == 's') { - r = 0; + err = r = 0; goto fail_child; } /* Release terminal for the question */ if ((r = restore_confirm_stdio(context, &saved_stdin, &saved_stdout, - &keep_stdin, &keep_stdout))) + &keep_stdin, &keep_stdout))) { + err = -errno; goto fail_child; + } } /* If a socket is connected to STDIN/STDOUT/STDERR, we @@ -1091,28 +1102,35 @@ int exec_spawn(ExecCommand *command, if (socket_fd >= 0) fd_nonblock(socket_fd, false); - if (!keep_stdin) - if (setup_input(context, socket_fd, apply_tty_stdin) < 0) { + if (!keep_stdin) { + err = setup_input(context, socket_fd, apply_tty_stdin); + if (err < 0) { r = EXIT_STDIN; goto fail_child; } + } - if (!keep_stdout) - if (setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) { + if (!keep_stdout) { + err = setup_output(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + if (err < 0) { r = EXIT_STDOUT; goto fail_child; } + } - if (setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin) < 0) { + err = setup_error(context, socket_fd, file_name_from_path(command->path), apply_tty_stdin); + if (err < 0) { r = EXIT_STDERR; goto fail_child; } - if (cgroup_bondings) - if (cgroup_bonding_install_list(cgroup_bondings, 0) < 0) { + if (cgroup_bondings) { + err = cgroup_bonding_install_list(cgroup_bondings, 0); + if (err < 0) { r = EXIT_CGROUP; goto fail_child; } + } if (context->oom_score_adjust_set) { char t[16]; @@ -1133,6 +1151,7 @@ int exec_spawn(ExecCommand *command, if (write_one_line_file("/proc/self/oom_adj", t) < 0 && errno != EACCES) { + err = -errno; r = EXIT_OOM_ADJUST; goto fail_child; } @@ -1141,6 +1160,7 @@ int exec_spawn(ExecCommand *command, if (context->nice_set) if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) { + err = -errno; r = EXIT_NICE; goto fail_child; } @@ -1153,6 +1173,7 @@ int exec_spawn(ExecCommand *command, if (sched_setscheduler(0, context->cpu_sched_policy | (context->cpu_sched_reset_on_fork ? SCHED_RESET_ON_FORK : 0), ¶m) < 0) { + err = -errno; r = EXIT_SETSCHEDULER; goto fail_child; } @@ -1160,18 +1181,21 @@ int exec_spawn(ExecCommand *command, if (context->cpuset) if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) { + err = -errno; r = EXIT_CPUAFFINITY; goto fail_child; } if (context->ioprio_set) if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { + err = -errno; r = EXIT_IOPRIO; goto fail_child; } if (context->timer_slack_nsec_set) if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { + err = -errno; r = EXIT_TIMERSLACK; goto fail_child; } @@ -1181,36 +1205,45 @@ int exec_spawn(ExecCommand *command, if (context->user) { username = context->user; - if (get_user_creds(&username, &uid, &gid, &home) < 0) { + err = get_user_creds(&username, &uid, &gid, &home); + if (err < 0) { r = EXIT_USER; goto fail_child; } - if (is_terminal_input(context->std_input)) - if (chown_terminal(STDIN_FILENO, uid) < 0) { + if (is_terminal_input(context->std_input)) { + err = chown_terminal(STDIN_FILENO, uid); + if (err < 0) { r = EXIT_STDIN; goto fail_child; } + } - if (cgroup_bondings && context->control_group_modify) - if (cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid) < 0 || - cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid) < 0) { + if (cgroup_bondings && context->control_group_modify) { + err = cgroup_bonding_set_group_access_list(cgroup_bondings, 0755, uid, gid); + if (err >= 0) + err = cgroup_bonding_set_task_access_list(cgroup_bondings, 0644, uid, gid); + if (err < 0) { r = EXIT_CGROUP; goto fail_child; } + } } - if (apply_permissions) - if (enforce_groups(context, username, gid) < 0) { + if (apply_permissions) { + err = enforce_groups(context, username, gid); + if (err < 0) { r = EXIT_GROUP; goto fail_child; } + } umask(context->umask); #ifdef HAVE_PAM if (context->pam_name && username) { - if (setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds) != 0) { + err = setup_pam(context->pam_name, username, context->tty_path, &pam_env, fds, n_fds); + if (err < 0) { r = EXIT_PAM; goto fail_child; } @@ -1218,6 +1251,7 @@ int exec_spawn(ExecCommand *command, #endif if (context->private_network) { if (unshare(CLONE_NEWNET) < 0) { + err = -errno; r = EXIT_NETWORK; goto fail_child; } @@ -1229,23 +1263,28 @@ int exec_spawn(ExecCommand *command, strv_length(context->read_only_dirs) > 0 || strv_length(context->inaccessible_dirs) > 0 || context->mount_flags != MS_SHARED || - context->private_tmp) - if ((r = setup_namespace( - context->read_write_dirs, - context->read_only_dirs, - context->inaccessible_dirs, - context->private_tmp, - context->mount_flags)) < 0) + context->private_tmp) { + err = setup_namespace(context->read_write_dirs, + context->read_only_dirs, + context->inaccessible_dirs, + context->private_tmp, + context->mount_flags); + if (err < 0) { + r = EXIT_NAMESPACE; goto fail_child; + } + } if (apply_chroot) { if (context->root_directory) if (chroot(context->root_directory) < 0) { + err = -errno; r = EXIT_CHROOT; goto fail_child; } if (chdir(context->working_directory ? context->working_directory : "/") < 0) { + err = -errno; r = EXIT_CHDIR; goto fail_child; } @@ -1256,11 +1295,13 @@ int exec_spawn(ExecCommand *command, if (asprintf(&d, "%s/%s", context->root_directory ? context->root_directory : "", context->working_directory ? context->working_directory : "") < 0) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } if (chdir(d) < 0) { + err = -errno; free(d); r = EXIT_CHDIR; goto fail_child; @@ -1271,9 +1312,12 @@ int exec_spawn(ExecCommand *command, /* We repeat the fd closing here, to make sure that * nothing is leaked from the PAM modules */ - if (close_all_fds(fds, n_fds) < 0 || - shift_fds(fds, n_fds) < 0 || - flags_fds(fds, n_fds, context->non_blocking) < 0) { + err = close_all_fds(fds, n_fds); + if (err >= 0) + err = shift_fds(fds, n_fds); + if (err >= 0) + err = flags_fds(fds, n_fds, context->non_blocking); + if (err < 0) { r = EXIT_FDS; goto fail_child; } @@ -1285,22 +1329,27 @@ int exec_spawn(ExecCommand *command, continue; if (setrlimit(i, context->rlimit[i]) < 0) { + err = -errno; r = EXIT_LIMITS; goto fail_child; } } - if (context->capability_bounding_set_drop) - if (do_capability_bounding_set_drop(context->capability_bounding_set_drop) < 0) { + if (context->capability_bounding_set_drop) { + err = do_capability_bounding_set_drop(context->capability_bounding_set_drop); + if (err < 0) { r = EXIT_CAPABILITIES; goto fail_child; } + } - if (context->user) - if (enforce_user(context, uid) < 0) { + if (context->user) { + err = enforce_user(context, uid); + if (err < 0) { r = EXIT_USER; goto fail_child; } + } /* PR_GET_SECUREBITS is not privileged, while * PR_SET_SECUREBITS is. So to suppress @@ -1308,18 +1357,21 @@ int exec_spawn(ExecCommand *command, * PR_SET_SECUREBITS unless necessary. */ if (prctl(PR_GET_SECUREBITS) != context->secure_bits) if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) { + err = -errno; r = EXIT_SECUREBITS; goto fail_child; } if (context->capabilities) if (cap_set_proc(context->capabilities) < 0) { + err = -errno; r = EXIT_CAPABILITIES; goto fail_child; } } if (!(our_env = new0(char*, 7))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1327,12 +1379,14 @@ int exec_spawn(ExecCommand *command, if (n_fds > 0) if (asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 || asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } if (home) if (asprintf(our_env + n_env++, "HOME=%s", home) < 0) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1340,6 +1394,7 @@ int exec_spawn(ExecCommand *command, if (username) if (asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 || asprintf(our_env + n_env++, "USER=%s", username) < 0) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1348,6 +1403,7 @@ int exec_spawn(ExecCommand *command, context->std_output == EXEC_OUTPUT_TTY || context->std_error == EXEC_OUTPUT_TTY) if (!(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1362,11 +1418,13 @@ int exec_spawn(ExecCommand *command, files_env, pam_env, NULL))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } if (!(final_argv = replace_env_argv(argv, final_env))) { + err = -ENOMEM; r = EXIT_MEMORY; goto fail_child; } @@ -1374,9 +1432,17 @@ int exec_spawn(ExecCommand *command, final_env = strv_env_clean(final_env); execve(command->path, final_argv, final_env); + err = -errno; r = EXIT_EXEC; fail_child: + if (r != 0) { + log_open(); + log_warning("Failed at step %s spawning %s: %s", + exit_status_to_string(r, EXIT_STATUS_SYSTEMD), + command->path, strerror(-err)); + } + strv_free(our_env); strv_free(final_env); strv_free(pam_env); |