int job_start_timer(Job *j, bool job_running) {
int r;
- usec_t run_begin, timeout_time, old_timeout_time;
+ usec_t timeout_time, old_timeout_time;
if (job_running) {
+ j->begin_running_usec = now(CLOCK_MONOTONIC);
+
if (j->unit->job_running_timeout == USEC_INFINITY)
return 0;
- run_begin = now(CLOCK_MONOTONIC);
- timeout_time = usec_add(run_begin, j->unit->job_running_timeout);
+ timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
if (j->timer_event_source) {
/* Update only if JobRunningTimeoutSec= results in earlier timeout */
if (j->begin_usec > 0)
fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
+ if (j->begin_running_usec > 0)
+ fprintf(f, "job-begin-running="USEC_FMT"\n", j->begin_running_usec);
bus_track_serialize(j->bus_track, f, "subscribed");
else
j->begin_usec = ull;
+ } else if (streq(l, "job-begin-running")) {
+ unsigned long long ull;
+
+ if (sscanf(v, "%llu", &ull) != 1)
+ log_debug("Failed to parse job-begin-running value %s", v);
+ else
+ j->begin_running_usec = ull;
+
} else if (streq(l, "subscribed")) {
if (strv_extend(&j->deserialized_clients, v) < 0)
int job_coldplug(Job *j) {
int r;
+ usec_t timeout_time = USEC_INFINITY;
assert(j);
/* Maybe due to new dependencies we don't actually need this job anymore? */
job_add_to_gc_queue(j);
- if (j->begin_usec == 0 || j->unit->job_timeout == USEC_INFINITY)
+ /* Create timer only when job began or began running and the respective timeout is finite.
+ * Follow logic of job_start_timer() if both timeouts are finite */
+ if (j->begin_usec == 0)
+ return 0;
+
+ if (j->unit->job_timeout != USEC_INFINITY)
+ timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
+
+ if (j->begin_running_usec > 0 && j->unit->job_running_timeout != USEC_INFINITY)
+ timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
+
+ if (timeout_time == USEC_INFINITY)
return 0;
j->timer_event_source = sd_event_source_unref(j->timer_event_source);
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)
log_debug_errno(r, "Failed to restart timeout for job: %m");