diff options
Diffstat (limited to 'src/shared/bus-util.c')
-rw-r--r-- | src/shared/bus-util.c | 148 |
1 files changed, 74 insertions, 74 deletions
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c index 5c6dc34700..6df73c560a 100644 --- a/src/shared/bus-util.c +++ b/src/shared/bus-util.c @@ -1398,7 +1398,7 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) { int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) { const char *eq, *field; - int r; + int r, rl; assert(m); assert(assignment); @@ -1409,20 +1409,18 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return -EINVAL; } + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); + field = strndupa(assignment, eq - assignment); eq ++; if (streq(field, "CPUQuota")) { - if (isempty(eq)) { - - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec"); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_append(m, "v", "t", USEC_INFINITY); - - } else if (endswith(eq, "%")) { + if (isempty(eq)) + r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); + else if (endswith(eq, "%")) { double percent; if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) { @@ -1430,58 +1428,69 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return -EINVAL; } - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec"); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100); + r = sd_bus_message_append(m, "sv", "CPUQuotaPerSecUSec", "t", (usec_t) percent * USEC_PER_SEC / 100); } else { log_error("CPU quota needs to be in percent."); return -EINVAL; } - if (r < 0) - return bus_log_create_error(r); - - return 0; + goto finish; } else if (streq(field, "EnvironmentFile")) { - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "EnvironmentFiles"); - if (r < 0) - return bus_log_create_error(r); - - r = sd_bus_message_append(m, "v", "a(sb)", 1, + r = sd_bus_message_append(m, "sv", "EnvironmentFiles", "a(sb)", 1, eq[0] == '-' ? eq + 1 : eq, eq[0] == '-'); + goto finish; + + } else if (STR_IN_SET(field, "AccuracySec", "RandomizedDelaySec", "RuntimeMaxSec")) { + char *n; + usec_t t; + size_t l; + r = parse_sec(eq, &t); if (r < 0) - return bus_log_create_error(r); + return log_error_errno(r, "Failed to parse %s= parameter: %s", field, eq); - return 0; + l = strlen(field); + n = newa(char, l + 2); + if (!n) + return log_oom(); - } else if (streq(field, "RandomizedDelaySec")) { - usec_t t; + /* Change suffix Sec → USec */ + strcpy(mempcpy(n, field, l - 3), "USec"); + r = sd_bus_message_append(m, "sv", n, "t", t); + goto finish; + } - r = parse_sec(eq, &t); + r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); + if (r < 0) + return bus_log_create_error(r); + + rl = rlimit_from_string(field); + if (rl >= 0) { + const char *sn; + struct rlimit l; + + r = rlimit_parse(rl, eq, &l); if (r < 0) - return log_error_errno(r, "Failed to parse RandomizedDelaySec= parameter: %s", eq); + return log_error_errno(r, "Failed to parse resource limit: %s", eq); - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "RandomizedDelayUSec"); + r = sd_bus_message_append(m, "v", "t", l.rlim_max); if (r < 0) return bus_log_create_error(r); - r = sd_bus_message_append(m, "v", "t", t); + r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); - return 0; - } + r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv"); + if (r < 0) + return bus_log_create_error(r); - r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field); - if (r < 0) - return bus_log_create_error(r); + sn = strjoina(field, "Soft"); + r = sd_bus_message_append(m, "sv", sn, "t", l.rlim_cur); - if (STR_IN_SET(field, + } else if (STR_IN_SET(field, "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting", "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies", "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit", @@ -1662,21 +1671,6 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "v", "a(st)", path, u); } - } else if (rlimit_from_string(field) >= 0) { - uint64_t rl; - - if (streq(eq, "infinity")) - rl = (uint64_t) -1; - else { - r = safe_atou64(eq, &rl); - if (r < 0) { - log_error("Invalid resource limit: %s", eq); - return -EINVAL; - } - } - - r = sd_bus_message_append(m, "v", "t", rl); - } else if (streq(field, "Nice")) { int32_t i; @@ -1746,16 +1740,6 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen r = sd_bus_message_append(m, "v", "i", sig); - } else if (streq(field, "AccuracySec")) { - usec_t u; - - r = parse_sec(eq, &u); - if (r < 0) { - log_error("Failed to parse %s value %s", field, eq); - return -EINVAL; - } - - r = sd_bus_message_append(m, "v", "t", u); } else if (streq(field, "TimerSlackNSec")) { nsec_t n; @@ -1869,6 +1853,11 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen return -EINVAL; } +finish: + if (r < 0) + return bus_log_create_error(r); + + r = sd_bus_message_close_container(m); if (r < 0) return bus_log_create_error(r); @@ -2041,13 +2030,21 @@ static const struct { { "start-limit", "start of the service was attempted too often" } }; -static void log_job_error_with_service_result(const char* service, const char *result) { - _cleanup_free_ char *service_shell_quoted = NULL; +static void log_job_error_with_service_result(const char* service, const char *result, const char *extra_args) { + _cleanup_free_ char *service_shell_quoted = NULL, *systemctl_extra_args = NULL; assert(service); service_shell_quoted = shell_maybe_quote(service); + systemctl_extra_args = strjoin("systemctl ", extra_args, " ", NULL); + if (!systemctl_extra_args) { + log_oom(); + return; + } + + systemctl_extra_args = strstrip(systemctl_extra_args); + if (!isempty(result)) { unsigned i; @@ -2056,27 +2053,30 @@ static void log_job_error_with_service_result(const char* service, const char *r break; if (i < ELEMENTSOF(explanations)) { - log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n", + log_error("Job for %s failed because %s. See \"%s status %s\" and \"journalctl -xe\" for details.\n", service, explanations[i].explanation, + systemctl_extra_args, strna(service_shell_quoted)); goto finish; } } - log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n", + log_error("Job for %s failed. See \"%s status %s\" and \"journalctl -xe\" for details.\n", service, + systemctl_extra_args, strna(service_shell_quoted)); finish: /* For some results maybe additional explanation is required */ if (streq_ptr(result, "start-limit")) - log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.", + log_info("To force a start use \"%1$s reset-failed %2$s\" followed by \"%1$s start %2$s\" again.", + systemctl_extra_args, strna(service_shell_quoted)); } -static int check_wait_response(BusWaitForJobs *d, bool quiet) { +static int check_wait_response(BusWaitForJobs *d, bool quiet, const char *extra_args) { int r = 0; assert(d->result); @@ -2089,7 +2089,7 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet) { else if (streq(d->result, "dependency")) log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name)); else if (streq(d->result, "invalid")) - log_error("Job for %s invalid.", strna(d->name)); + log_error("%s is not active, cannot reload.", strna(d->name)); else if (streq(d->result, "assert")) log_error("Assertion failed on job for %s.", strna(d->name)); else if (streq(d->result, "unsupported")) @@ -2103,7 +2103,7 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet) { if (q < 0) log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name); - log_job_error_with_service_result(d->name, result); + log_job_error_with_service_result(d->name, result, extra_args); } else log_error("Job failed. See \"journalctl -xe\" for details."); } @@ -2127,7 +2127,7 @@ static int check_wait_response(BusWaitForJobs *d, bool quiet) { return r; } -int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) { +int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char *extra_args) { int r = 0; assert(d); @@ -2140,7 +2140,7 @@ int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) { return log_error_errno(q, "Failed to wait for response: %m"); if (d->result) { - q = check_wait_response(d, quiet); + q = check_wait_response(d, quiet, extra_args); /* Return the first error as it is most likely to be * meaningful. */ if (q < 0 && r == 0) @@ -2175,7 +2175,7 @@ int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) { if (r < 0) return log_oom(); - return bus_wait_for_jobs(d, quiet); + return bus_wait_for_jobs(d, quiet, NULL); } int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) { |