summaryrefslogtreecommitdiff
path: root/src/core/job.c
diff options
context:
space:
mode:
authorMichal Koutný <mkoutny@suse.com>2017-02-17 17:47:20 +0100
committerMichal Koutný <mkoutny@suse.com>2017-04-25 18:00:29 +0200
commita2df3ea4ae058693bc7bf203d144e8af3c9493d2 (patch)
treee27f533ddbe214617cb5b144d2d4d778b67a3df6 /src/core/job.c
parent9e49656037717b96c06b1f1507a41550bdb2c795 (diff)
downloadsystemd-a2df3ea4ae058693bc7bf203d144e8af3c9493d2.tar.gz
job: add JobRunningTimeoutSec for JOB_RUNNING state
Unit.JobTimeoutSec starts when a job is enqueued in a transaction. The introduced distinct Unit.JobRunningTimeoutSec starts only when the job starts running (e.g. it groups all Exec* commands of a service or spans waiting for a device period.) Unit.JobRunningTimeoutSec is intended to be used by default instead of Unit.JobTimeoutSec for device units where such behavior causes less confusion (consider a job for a _netdev mount device, with this change the timeout will start ticking only after the network is ready).
Diffstat (limited to 'src/core/job.c')
-rw-r--r--src/core/job.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/core/job.c b/src/core/job.c
index e2349830a8..2b43cf6126 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -576,6 +576,7 @@ int job_run_and_invalidate(Job *j) {
if (!job_is_runnable(j))
return -EAGAIN;
+ job_start_timer(j, true);
job_set_state(j, JOB_RUNNING);
job_add_to_dbus_queue(j);
@@ -949,22 +950,45 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user
return 0;
}
-int job_start_timer(Job *j) {
+int job_start_timer(Job *j, bool job_running) {
int r;
+ usec_t run_begin, timeout_time, old_timeout_time;
- if (j->timer_event_source)
- return 0;
+ if (job_running) {
+ if (j->unit->job_running_timeout == USEC_INFINITY)
+ return 0;
- j->begin_usec = now(CLOCK_MONOTONIC);
+ run_begin = now(CLOCK_MONOTONIC);
+ timeout_time = usec_add(run_begin, j->unit->job_running_timeout);
- if (j->unit->job_timeout == USEC_INFINITY)
- return 0;
+ if (j->timer_event_source) {
+ /* Update only if JobRunningTimeoutSec= results in earlier timeout */
+ r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
+ if (r < 0)
+ return r;
+
+ if (old_timeout_time <= timeout_time)
+ return 0;
+
+ return sd_event_source_set_time(j->timer_event_source, timeout_time);
+ }
+ } else {
+ if (j->timer_event_source)
+ return 0;
+
+ j->begin_usec = now(CLOCK_MONOTONIC);
+
+ if (j->unit->job_timeout == USEC_INFINITY)
+ return 0;
+
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+ }
r = sd_event_add_time(
j->manager->event,
&j->timer_event_source,
CLOCK_MONOTONIC,
- usec_add(j->begin_usec, j->unit->job_timeout), 0,
+ timeout_time, 0,
job_dispatch_timer, j);
if (r < 0)
return r;