summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dbus-unit.c1
-rw-r--r--src/core/device.c2
-rw-r--r--src/core/job.c38
-rw-r--r--src/core/job.h2
-rw-r--r--src/core/load-fragment-gperf.gperf.m41
-rw-r--r--src/core/main.c12
-rw-r--r--src/core/service.c3
-rw-r--r--src/core/transaction.c2
-rw-r--r--src/core/unit.c4
-rw-r--r--src/core/unit.h1
10 files changed, 53 insertions, 13 deletions
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index f15bb2196c..b0645ce294 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -748,6 +748,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
diff --git a/src/core/device.c b/src/core/device.c
index 0e67c96552..da008f6041 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -112,7 +112,7 @@ static void device_init(Unit *u) {
* indefinitely for plugged in devices, something which cannot
* happen for the other units since their operations time out
* anyway. */
- u->job_timeout = u->manager->default_timeout_start_usec;
+ u->job_running_timeout = u->manager->default_timeout_start_usec;
u->ignore_on_isolate = true;
}
diff --git a/src/core/job.c b/src/core/job.c
index a02f1bb2bc..5067006d63 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;
diff --git a/src/core/job.h b/src/core/job.h
index bea743f462..8b3d38fc60 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -220,7 +220,7 @@ int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
void job_add_to_run_queue(Job *j);
void job_add_to_dbus_queue(Job *j);
-int job_start_timer(Job *j);
+int job_start_timer(Job *j, bool job_running);
int job_run_and_invalidate(Job *j);
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already);
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index cb9e6fea27..97adbdd7bb 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -194,6 +194,7 @@ Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0,
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_warn_compat, DISABLED_LEGACY, 0
Unit.JobTimeoutSec, config_parse_sec_fix_0, 0, offsetof(Unit, job_timeout)
+Unit.JobRunningTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_running_timeout)
Unit.JobTimeoutAction, config_parse_emergency_action, 0, offsetof(Unit, job_timeout_action)
Unit.JobTimeoutRebootArgument, config_parse_unit_string_printf, 0, offsetof(Unit, job_timeout_reboot_arg)
Unit.StartLimitIntervalSec, config_parse_sec, 0, offsetof(Unit, start_limit.interval)
diff --git a/src/core/main.c b/src/core/main.c
index bcf9ea5f25..e6ae0bee31 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -1162,6 +1162,8 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
struct rlimit nl;
int r;
+ int min_max;
+ _cleanup_free_ char *nr_open = NULL;
assert(saved_rlimit);
@@ -1182,8 +1184,16 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
arg_default_rlimit[RLIMIT_NOFILE] = rl;
}
+ /* Get current RLIMIT_NOFILE maximum compiled into the kernel. */
+ r = read_one_line_file("/proc/sys/fs/nr_open", &nr_open);
+ if (r == 0)
+ r = safe_atoi(nr_open, &min_max);
+ /* If we fail, fallback to the hard-coded kernel limit of 1024 * 1024. */
+ if (r < 0)
+ min_max = 1024 * 1024;
+
/* Bump up the resource limit for ourselves substantially */
- nl.rlim_cur = nl.rlim_max = 64*1024;
+ nl.rlim_cur = nl.rlim_max = min_max;
r = setrlimit_closest(RLIMIT_NOFILE, &nl);
if (r < 0)
return log_warning_errno(r, "Setting RLIMIT_NOFILE failed, ignoring: %m");
diff --git a/src/core/service.c b/src/core/service.c
index a63c6d8bc3..b45929e535 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -2163,7 +2163,6 @@ static int service_serialize_exec_command(Unit *u, FILE *f, ExecCommand *command
unsigned idx;
const char *type;
char **arg;
- _cleanup_strv_free_ char **escaped_args = NULL;
_cleanup_free_ char *args = NULL, *p = NULL;
size_t allocated = 0, length = 0;
@@ -2306,7 +2305,7 @@ static int service_deserialize_exec_command(Unit *u, const char *key, const char
bool control, found = false;
ServiceExecCommand id = _SERVICE_EXEC_COMMAND_INVALID;
ExecCommand *command = NULL;
- _cleanup_free_ char *args = NULL, *path = NULL;
+ _cleanup_free_ char *path = NULL;
_cleanup_strv_free_ char **argv = NULL;
enum ExecCommandState {
diff --git a/src/core/transaction.c b/src/core/transaction.c
index b6d1062414..a2dfd8ae90 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -632,7 +632,7 @@ static int transaction_apply(Transaction *tr, Manager *m, JobMode mode) {
job_add_to_run_queue(j);
job_add_to_dbus_queue(j);
- job_start_timer(j);
+ job_start_timer(j, false);
job_shutdown_magic(j);
}
diff --git a/src/core/unit.c b/src/core/unit.c
index 25ea5a8591..01fa0d0d46 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -99,6 +99,7 @@ Unit *unit_new(Manager *m, size_t size) {
u->on_failure_job_mode = JOB_REPLACE;
u->cgroup_inotify_wd = -1;
u->job_timeout = USEC_INFINITY;
+ u->job_running_timeout = USEC_INFINITY;
u->ref_uid = UID_INVALID;
u->ref_gid = GID_INVALID;
u->cpu_usage_last = NSEC_INFINITY;
@@ -1336,6 +1337,9 @@ int unit_load(Unit *u) {
goto fail;
}
+ if (u->job_running_timeout != USEC_INFINITY && u->job_running_timeout > u->job_timeout)
+ log_unit_warning(u, "JobRunningTimeoutSec= is greater than JobTimeoutSec=, it has no effect.");
+
unit_update_cgroup_members_masks(u);
}
diff --git a/src/core/unit.h b/src/core/unit.h
index 8052c234fd..cf21b37e22 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -114,6 +114,7 @@ struct Unit {
/* Job timeout and action to take */
usec_t job_timeout;
+ usec_t job_running_timeout;
EmergencyAction job_timeout_action;
char *job_timeout_reboot_arg;