summaryrefslogtreecommitdiffstats
path: root/src/core/service.c
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2024-05-04 16:54:41 +0200
committerDaan De Meyer <daan.j.demeyer@gmail.com>2024-05-05 14:19:30 +0200
commit7e0e6b50b4d26f13ccfc1df9f0daf50f839f8d00 (patch)
treed3b433b576035941d177c0f7d5210d2f38846f4a /src/core/service.c
parentMerge pull request #32588 from CodethinkLabs/mkosi-selinux (diff)
downloadsystemd-7e0e6b50b4d26f13ccfc1df9f0daf50f839f8d00.tar.xz
systemd-7e0e6b50b4d26f13ccfc1df9f0daf50f839f8d00.zip
core: Record ExecMainStartTimestamp before forking
Otherwise there's a chance the handover timestamp is less than the start timestamp depending on the whims of the scheduler. For non-forking services, we also propagate the start timestamp into Service->main_exec_status to make sure it starts earlier than the handoff timestamp.
Diffstat (limited to 'src/core/service.c')
-rw-r--r--src/core/service.c20
1 files changed, 10 insertions, 10 deletions
diff --git a/src/core/service.c b/src/core/service.c
index c527ad36bc..36671ae1c0 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -192,7 +192,7 @@ static void service_unwatch_pid_file(Service *s) {
s->pid_file_pathspec = mfree(s->pid_file_pathspec);
}
-static int service_set_main_pidref(Service *s, PidRef pidref_consume) {
+static int service_set_main_pidref(Service *s, PidRef pidref_consume, const dual_timestamp *start_timestamp) {
_cleanup_(pidref_done) PidRef pidref = pidref_consume;
int r;
@@ -214,7 +214,7 @@ static int service_set_main_pidref(Service *s, PidRef pidref_consume) {
if (!pidref_equal(&s->main_pid, &pidref)) {
service_unwatch_main_pid(s);
- exec_status_start(&s->main_exec_status, pidref.pid);
+ exec_status_start(&s->main_exec_status, pidref.pid, start_timestamp);
}
s->main_pid = TAKE_PIDREF(pidref);
@@ -1166,7 +1166,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
} else
log_unit_debug(UNIT(s), "Main PID loaded: "PID_FMT, pidref.pid);
- r = service_set_main_pidref(s, TAKE_PIDREF(pidref));
+ r = service_set_main_pidref(s, TAKE_PIDREF(pidref), /* start_timestamp = */ NULL);
if (r < 0)
return r;
@@ -1196,7 +1196,7 @@ static void service_search_main_pid(Service *s) {
return;
log_unit_debug(UNIT(s), "Main PID guessed: "PID_FMT, pid.pid);
- if (service_set_main_pidref(s, TAKE_PIDREF(pid)) < 0)
+ if (service_set_main_pidref(s, TAKE_PIDREF(pid), /* start_timestamp = */ NULL) < 0)
return;
r = unit_watch_pidref(UNIT(s), &s->main_pid, /* exclusive= */ false);
@@ -2417,7 +2417,7 @@ static void service_enter_start(Service *s) {
/* For simple services we immediately start
* the START_POST binaries. */
- (void) service_set_main_pidref(s, TAKE_PIDREF(pidref));
+ (void) service_set_main_pidref(s, TAKE_PIDREF(pidref), &c->exec_status.start_timestamp);
service_enter_start_post(s);
} else if (s->type == SERVICE_FORKING) {
@@ -2436,7 +2436,7 @@ static void service_enter_start(Service *s) {
/* For D-Bus services we know the main pid right away, but wait for the bus name to appear on the
* bus. 'notify' and 'exec' services are similar. */
- (void) service_set_main_pidref(s, TAKE_PIDREF(pidref));
+ (void) service_set_main_pidref(s, TAKE_PIDREF(pidref), &c->exec_status.start_timestamp);
service_set_state(s, SERVICE_START);
} else
assert_not_reached();
@@ -2709,7 +2709,7 @@ static void service_run_next_main(Service *s) {
return;
}
- (void) service_set_main_pidref(s, TAKE_PIDREF(pidref));
+ (void) service_set_main_pidref(s, TAKE_PIDREF(pidref), &s->main_command->exec_status.start_timestamp);
}
static int service_start(Unit *u) {
@@ -3187,7 +3187,7 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
PidRef pidref;
if (!pidref_is_set(&s->main_pid) && deserialize_pidref(fds, value, &pidref) >= 0)
- (void) service_set_main_pidref(s, pidref);
+ (void) service_set_main_pidref(s, pidref, /* start_timestamp = */ NULL);
} else if (streq(key, "main-pid-known")) {
int b;
@@ -4380,7 +4380,7 @@ static void service_notify_message(
log_unit_warning(u, "New main PID "PID_FMT" does not belong to service, refusing.", new_main_pid.pid);
}
if (r > 0) {
- (void) service_set_main_pidref(s, TAKE_PIDREF(new_main_pid));
+ (void) service_set_main_pidref(s, TAKE_PIDREF(new_main_pid), /* start_timestamp = */ NULL);
r = unit_watch_pidref(UNIT(s), &s->main_pid, /* exclusive= */ false);
if (r < 0)
@@ -4676,7 +4676,7 @@ static int bus_name_pid_lookup_callback(sd_bus_message *reply, void *userdata, s
log_unit_debug(UNIT(s), "D-Bus name %s is now owned by process " PID_FMT, s->bus_name, pidref.pid);
- (void) service_set_main_pidref(s, TAKE_PIDREF(pidref));
+ (void) service_set_main_pidref(s, TAKE_PIDREF(pidref), /* start_timestamp = */ NULL);
(void) unit_watch_pidref(UNIT(s), &s->main_pid, /* exclusive= */ false);
return 1;
}