[systemd-devel] [PATCH] systemctl: provide better error message when start limit is exceeded.

Lennart Poettering lennart at poettering.net
Thu Nov 7 15:41:00 PST 2013


On Thu, 31.10.13 15:12, Vaclav Pavlin (vpavlin at redhat.com) wrote:

> From: Václav Pavlín <vpavlin at redhat.com>

I like the idea, but I'd prefer if we wouldn't let the service failure
field spill into the job result. I don't like redundant fields I must
say...

Also, the reason why a job failed is not just interesting for the start
limit stuff, but for other cases too. Hence, I'd much prefer if when we
see a job result of "failed" that we then read the "Result" property
from the service object and show it in a nice explanation string, one of
which the is the start limit thing. Such a change would only require
reading one more prop if we got "failed" as result, and would need
changes on the client side only.

I hope this makes sene? 

> 
> ---
>  src/core/job.c            | 12 ++++++++++--
>  src/core/job.h            |  1 +
>  src/systemctl/systemctl.c |  5 +++++
>  3 files changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/src/core/job.c b/src/core/job.c
> index e5dcef7..44b6b23 100644
> --- a/src/core/job.c
> +++ b/src/core/job.c
> @@ -752,6 +752,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
>          Unit *other;
>          JobType t;
>          Iterator i;
> +        JobResult r = result;
>  
>          assert(j);
>          assert(j->installed);
> @@ -760,7 +761,13 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
>          u = j->unit;
>          t = j->type;
>  
> -        j->result = result;
> +        if (result == JOB_FAILED && u->type == UNIT_SERVICE) {
> +                Service *s = SERVICE(u);
> +                if (s->result == SERVICE_FAILURE_START_LIMIT)
> +                        r = JOB_FAILED_LIMIT;
> +        }
> +
> +        j->result = r;
>  
>          if (j->state == JOB_RUNNING)
>                  j->manager->n_running_jobs--;
> @@ -1140,7 +1147,8 @@ static const char* const job_result_table[_JOB_RESULT_MAX] = {
>          [JOB_TIMEOUT] = "timeout",
>          [JOB_FAILED] = "failed",
>          [JOB_DEPENDENCY] = "dependency",
> -        [JOB_SKIPPED] = "skipped"
> +        [JOB_SKIPPED] = "skipped",
> +        [JOB_FAILED_LIMIT] = "failed-limit"
>  };
>  
>  DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
> diff --git a/src/core/job.h b/src/core/job.h
> index d90bc96..a41bfd9 100644
> --- a/src/core/job.h
> +++ b/src/core/job.h
> @@ -98,6 +98,7 @@ enum JobResult {
>          JOB_FAILED,              /* Job failed */
>          JOB_DEPENDENCY,          /* A required dependency job did not result in JOB_DONE */
>          JOB_SKIPPED,             /* JOB_RELOAD of inactive unit; negative result of JOB_VERIFY_ACTIVE */
> +        JOB_FAILED_LIMIT,        /* Service start limit exceeded */
>          _JOB_RESULT_MAX,
>          _JOB_RESULT_INVALID = -1
>  };
> diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
> index d458c65..67c25c8 100644
> --- a/src/systemctl/systemctl.c
> +++ b/src/systemctl/systemctl.c
> @@ -1602,6 +1602,11 @@ static int wait_for_jobs(DBusConnection *bus, Set *s) {
>                                  log_error("Job for %s canceled.", strna(d.name));
>                          else if (streq(d.result, "dependency"))
>                                  log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
> +                        else if (streq(d.result, "failed-limit"))
> +                                log_error("Starting %s has been attempted too often too quickly,"
> +                                          " the repeated start of the unit has been refused. To force a start please"
> +                                          " invoke 'systemctl reset-failed %s' followed by 'systemctl"
> +                                          " start %s' again.", strna(d.name), strna(d.name), strna(d.name));
>                          else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
>                                  log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
>                  }


Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list