X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=76284700d7b3044b425775587b8296d62edd9038;hp=6e2b5e48a01c7be317ba292392dd0316656a17fa;hb=20ad4cfd8e5592f634f20468798cbc1055ab9faf;hpb=ac0930c892bc7979b4c9bc2a52e5e844650b025d diff --git a/src/core/execute.c b/src/core/execute.c index 6e2b5e48a..76284700d 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -50,6 +50,7 @@ #include "capability.h" #include "util.h" #include "log.h" +#include "sd-messages.h" #include "ioprio.h" #include "securebits.h" #include "cgroup.h" @@ -999,7 +1000,7 @@ int exec_spawn(ExecCommand *command, int r; char *line; int socket_fd; - char **files_env = NULL; + char _cleanup_strv_free_ **files_env = NULL; assert(command); assert(context); @@ -1020,8 +1021,13 @@ int exec_spawn(ExecCommand *command, } else socket_fd = -1; - if ((r = exec_context_load_environment(context, &files_env)) < 0) { - log_error("Failed to load environment files: %s", strerror(-r)); + r = exec_context_load_environment(context, &files_env); + if (r < 0) { + log_struct(LOG_ERR, + "UNIT=%s", unit_id, + "MESSAGE=Failed to load environment files: %s", strerror(-r), + "ERRNO=%d", -r, + NULL); return r; } @@ -1029,24 +1035,24 @@ int exec_spawn(ExecCommand *command, argv = command->argv; line = exec_command_line(argv); - if (!line) { - r = -ENOMEM; - goto fail_parent; - } + if (!line) + return log_oom(); - log_debug("About to execute: %s", line); + log_struct(LOG_DEBUG, + "UNIT=%s", unit_id, + "MESSAGE=About to execute %s", line, + NULL); free(line); r = cgroup_bonding_realize_list(cgroup_bondings); if (r < 0) - goto fail_parent; + return r; cgroup_attribute_apply_list(cgroup_attributes, cgroup_bondings); - if ((pid = fork()) < 0) { - r = -errno; - goto fail_parent; - } + pid = fork(); + if (pid < 0) + return -errno; if (pid == 0) { int i, err; @@ -1054,7 +1060,8 @@ int exec_spawn(ExecCommand *command, const char *username = NULL, *home = NULL; uid_t uid = (uid_t) -1; gid_t gid = (gid_t) -1; - char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL; + char _cleanup_strv_free_ **our_env = NULL, **pam_env = NULL, + **final_env = NULL, **final_argv = NULL; unsigned n_env = 0; bool set_access = false; @@ -1283,7 +1290,7 @@ int exec_spawn(ExecCommand *command, umask(context->umask); #ifdef HAVE_PAM - if (context->pam_name && username) { + if (apply_permissions && context->pam_name && username) { err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); if (err < 0) { r = EXIT_PAM; @@ -1331,8 +1338,7 @@ int exec_spawn(ExecCommand *command, goto fail_child; } } else { - - char *d; + char _cleanup_free_ *d = NULL; if (asprintf(&d, "%s/%s", context->root_directory ? context->root_directory : "", @@ -1344,12 +1350,9 @@ int exec_spawn(ExecCommand *command, if (chdir(d) < 0) { err = -errno; - free(d); r = EXIT_CHDIR; goto fail_child; } - - free(d); } /* We repeat the fd closing here, to make sure that @@ -1495,21 +1498,24 @@ int exec_spawn(ExecCommand *command, 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)); + log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED), + "EXECUTABLE=%s", command->path, + "MESSAGE=Failed at step %s spawning %s: %s", + exit_status_to_string(r, EXIT_STATUS_SYSTEMD), + command->path, strerror(-err), + "ERRNO=%d", -err, + NULL); + log_close(); } - strv_free(our_env); - strv_free(final_env); - strv_free(pam_env); - strv_free(files_env); - strv_free(final_argv); - _exit(r); } - strv_free(files_env); + log_struct(LOG_DEBUG, + "UNIT=%s", unit_id, + "MESSAGE=Forked %s as %lu", + command->path, (unsigned long) pid, + NULL); /* We add the new process to the cgroup both in the child (so * that we can be sure that no user code is ever executed @@ -1519,17 +1525,10 @@ int exec_spawn(ExecCommand *command, if (cgroup_bondings) cgroup_bonding_install_list(cgroup_bondings, pid, cgroup_suffix); - log_debug("Forked %s as %lu", command->path, (unsigned long) pid); - exec_status_start(&command->exec_status, pid); *ret = pid; return 0; - -fail_parent: - strv_free(files_env); - - return r; } void exec_context_init(ExecContext *c) { @@ -1769,21 +1768,37 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { if (c->rlimit[i]) fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max); - if (c->ioprio_set) + if (c->ioprio_set) { + char *class_str; + int r; + + r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str); + if (r < 0) + class_str = NULL; fprintf(f, "%sIOSchedulingClass: %s\n" "%sIOPriority: %i\n", - prefix, ioprio_class_to_string(IOPRIO_PRIO_CLASS(c->ioprio)), + prefix, strna(class_str), prefix, (int) IOPRIO_PRIO_DATA(c->ioprio)); + free(class_str); + } - if (c->cpu_sched_set) + if (c->cpu_sched_set) { + char *policy_str; + int r; + + r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str); + if (r < 0) + policy_str = NULL; fprintf(f, "%sCPUSchedulingPolicy: %s\n" "%sCPUSchedulingPriority: %i\n" "%sCPUSchedulingResetOnFork: %s\n", - prefix, sched_policy_to_string(c->cpu_sched_policy), + prefix, strna(policy_str), prefix, c->cpu_sched_priority, prefix, yes_no(c->cpu_sched_reset_on_fork)); + free(policy_str); + } if (c->cpuset) { fprintf(f, "%sCPUAffinity:", prefix); @@ -1818,12 +1833,26 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL || c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE || c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL || - c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) + c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) { + char *fac_str, *lvl_str; + int r; + + r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str); + if (r < 0) + fac_str = NULL; + + r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str); + if (r < 0) + lvl_str = NULL; + fprintf(f, "%sSyslogFacility: %s\n" "%sSyslogLevel: %s\n", - prefix, log_facility_unshifted_to_string(c->syslog_priority >> 3), - prefix, log_level_to_string(LOG_PRI(c->syslog_priority))); + prefix, strna(fac_str), + prefix, strna(lvl_str)); + free(lvl_str); + free(fac_str); + } if (c->capabilities) { char *t;