mirror of
https://github.com/systemd/systemd.git
synced 2025-01-23 02:04:32 +03:00
manager: switch service unit type over to using new handoff timestamping logic
Also: rename Handover → Handoff. I think it makes it clearer that this is not really about handing over any resources, but that the executor is out off the game from that point on.
This commit is contained in:
parent
12001b1bf0
commit
3c1d1ca146
13
NEWS
13
NEWS
@ -198,13 +198,12 @@ CHANGES WITH 256-rc1:
|
||||
PID 1 will start to have the effect of shutting down the system
|
||||
cleanly).
|
||||
|
||||
* New D-Bus properties ExecMainHandoverTimestamp and
|
||||
ExecMainHandoverTimestampMonotonic are now published by services of
|
||||
type exec, dbus, notify, and notify-reload.
|
||||
This timestamp is taken as the very last operation before executing
|
||||
a service's binary, which allows users to accurately track when
|
||||
execution control of the process is handed over from systemd to the
|
||||
payload.
|
||||
* New D-Bus properties ExecMainHandoffTimestamp and
|
||||
ExecMainHandoffTimestampMonotonic are now published by services
|
||||
units. This timestamp is taken as the very last operation before
|
||||
handing off control to invoked binaries. This information is
|
||||
available for other unit types that fork off processes (i.e. mount,
|
||||
swap, socket units), but currently only via "systemd-analyze dump".
|
||||
|
||||
Journal:
|
||||
|
||||
|
@ -2766,8 +2766,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
readonly t ExecMainStartTimestampMonotonic = ...;
|
||||
readonly t ExecMainExitTimestamp = ...;
|
||||
readonly t ExecMainExitTimestampMonotonic = ...;
|
||||
readonly t ExecMainHandoverTimestamp = ...;
|
||||
readonly t ExecMainHandoverTimestampMonotonic = ...;
|
||||
readonly t ExecMainHandoffTimestamp = ...;
|
||||
readonly t ExecMainHandoffTimestampMonotonic = ...;
|
||||
readonly u ExecMainPID = ...;
|
||||
readonly i ExecMainCode = ...;
|
||||
readonly i ExecMainStatus = ...;
|
||||
@ -4057,9 +4057,9 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainExitTimestampMonotonic"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainHandoverTimestamp"/>
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainHandoffTimestamp"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainHandoverTimestampMonotonic"/>
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainHandoffTimestampMonotonic"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="ExecMainPID"/>
|
||||
|
||||
@ -4710,18 +4710,20 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<para><varname>ExecMainStartTimestamp</varname>, <varname>ExecMainStartTimestampMonotonic</varname>,
|
||||
<varname>ExecMainExitTimestamp</varname>, <varname>ExecMainExitTimestampMonotonic</varname>,
|
||||
<varname>ExecMainHandoverTimestamp</varname>, <varname>ExecMainHandoverTimestampMonotonic</varname>,
|
||||
<varname>ExecMainHandoffTimestamp</varname>, <varname>ExecMainHandoffTimestampMonotonic</varname>,
|
||||
<varname>ExecMainPID</varname>, <varname>ExecMainCode</varname>, <varname>ExecMainStatus</varname>
|
||||
contain information about the main process of the service as far as it is known. The
|
||||
<varname>ExecMainStartTimestamp</varname> timestamps record when the main child process is spawned by
|
||||
the service manager. <varname>ExecMainExitTimestamp</varname> timestamps record when the main child
|
||||
process exit has been detected by the service manager. <varname>ExecMainHandoverTimestamp</varname>
|
||||
timestamps record when the service executable is executed by <command>systemd-executor</command> for
|
||||
services of type <literal>exec</literal>, <literal>dbus</literal>, <literal>notify</literal>, and
|
||||
<literal>notify-reload</literal>. This is often the same runtime information that is stored in
|
||||
<varname>ExecStart=</varname>. However, it deviates for <varname>Type=forking</varname> services where
|
||||
the main process of the service is not forked off systemd directly. These fields either contain
|
||||
information of the last run of the process or of the current running process.</para>
|
||||
<varname>ExecMainStartTimestamp</varname> timestamps record when the main process of the service is
|
||||
created. <varname>ExecMainExitTimestamp</varname> timestamps record when the main process exit has been
|
||||
detected by the service manager. <varname>ExecMainHandoffTimestamp</varname> timestamps records when
|
||||
the service binary is about to be executed by <command>systemd-executor</command> (this timestamp is
|
||||
recorded regardless if the immediately following <function>execve()</function> system call succeeds or
|
||||
fails). This is often the same runtime information that is also maintained for
|
||||
<varname>ExecStart=</varname>. However, it deviates for services with <varname>Type=forking</varname>
|
||||
as well as services that use <varname>MAINPID=</varname> <function>sd_notify()</function> messages as
|
||||
the main process of the service is not forked off by the service manager directly in that case. These
|
||||
fields either contain information of the last run of the process or of the current running
|
||||
process.</para>
|
||||
|
||||
<para><varname>MainPID</varname> and <varname>ControlPID</varname> contain the main and control PID of
|
||||
the service. The main PID is the current main PID of the service and is 0 when the service currently
|
||||
@ -12067,8 +12069,8 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \
|
||||
<varname>EffectiveMemoryMax</varname>,
|
||||
<varname>EffectiveTasksMax</varname>,
|
||||
<varname>MemoryZSwapWriteback</varname>,
|
||||
<varname>ExecMainHandoverTimestampMonotonic</varname>, and
|
||||
<varname>ExecMainHandoverTimestamp</varname> were added in version 256.</para>
|
||||
<varname>ExecMainHandoffTimestampMonotonic</varname>, and
|
||||
<varname>ExecMainHandoffTimestamp</varname> were added in version 256.</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Socket Unit Objects</title>
|
||||
|
@ -9,7 +9,7 @@
|
||||
#define BUS_EXEC_STATUS_VTABLE(prefix, offset, flags) \
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP(prefix "StartTimestamp", (offset) + offsetof(ExecStatus, start_timestamp), flags), \
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP(prefix "ExitTimestamp", (offset) + offsetof(ExecStatus, exit_timestamp), flags), \
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP(prefix "HandoverTimestamp", (offset) + offsetof(ExecStatus, handover_timestamp), flags), \
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP(prefix "HandoffTimestamp", (offset) + offsetof(ExecStatus, handoff_timestamp), flags), \
|
||||
SD_BUS_PROPERTY(prefix "PID", "u", bus_property_get_pid, (offset) + offsetof(ExecStatus, pid), flags), \
|
||||
SD_BUS_PROPERTY(prefix "Code", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, code), flags), \
|
||||
SD_BUS_PROPERTY(prefix "Status", "i", bus_property_get_int, (offset) + offsetof(ExecStatus, status), flags)
|
||||
|
@ -1842,6 +1842,19 @@ void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int
|
||||
(void) utmp_put_dead_process(context->utmp_id, pid, code, status);
|
||||
}
|
||||
|
||||
void exec_status_handoff(ExecStatus *s, const struct ucred *ucred, const dual_timestamp *ts) {
|
||||
assert(s);
|
||||
assert(ucred);
|
||||
assert(ts);
|
||||
|
||||
if (ucred->pid != s->pid)
|
||||
*s = (ExecStatus) {
|
||||
.pid = ucred->pid,
|
||||
};
|
||||
|
||||
s->handoff_timestamp = *ts;
|
||||
}
|
||||
|
||||
void exec_status_reset(ExecStatus *s) {
|
||||
assert(s);
|
||||
|
||||
@ -1866,10 +1879,10 @@ void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
|
||||
"%sStart Timestamp: %s\n",
|
||||
prefix, FORMAT_TIMESTAMP(s->start_timestamp.realtime));
|
||||
|
||||
if (dual_timestamp_is_set(&s->handover_timestamp))
|
||||
if (dual_timestamp_is_set(&s->handoff_timestamp))
|
||||
fprintf(f,
|
||||
"%sHandover Timestamp: %s\n",
|
||||
prefix, FORMAT_TIMESTAMP(s->handover_timestamp.realtime));
|
||||
"%sHandoff Timestamp: %s\n",
|
||||
prefix, FORMAT_TIMESTAMP(s->handoff_timestamp.realtime));
|
||||
|
||||
if (dual_timestamp_is_set(&s->exit_timestamp))
|
||||
fprintf(f,
|
||||
|
@ -91,7 +91,7 @@ typedef enum ExecKeyringMode {
|
||||
struct ExecStatus {
|
||||
dual_timestamp start_timestamp;
|
||||
dual_timestamp exit_timestamp;
|
||||
dual_timestamp handover_timestamp;
|
||||
dual_timestamp handoff_timestamp;
|
||||
pid_t pid;
|
||||
int code; /* as in siginfo_t::si_code */
|
||||
int status; /* as in siginfo_t::si_status */
|
||||
@ -444,9 +444,7 @@ struct ExecParameters {
|
||||
int stdout_fd;
|
||||
int stderr_fd;
|
||||
|
||||
/* An fd that is closed by the execve(), and thus will result in EOF when the execve() is done. It
|
||||
* will also be used to send a timestamp taken as the very last operation before execve, for
|
||||
* tracking purposes. */
|
||||
/* An fd that is closed by the execve(), and thus will result in EOF when the execve() is done. */
|
||||
int exec_fd;
|
||||
|
||||
char *notify_socket;
|
||||
@ -547,6 +545,7 @@ char** exec_context_get_restrict_filesystems(const ExecContext *c);
|
||||
|
||||
void exec_status_start(ExecStatus *s, pid_t pid);
|
||||
void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status);
|
||||
void exec_status_handoff(ExecStatus *s, const struct ucred *ucred, const dual_timestamp *ts);
|
||||
void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix);
|
||||
void exec_status_reset(ExecStatus *s);
|
||||
|
||||
|
@ -3009,7 +3009,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
(void) serialize_item_format(f, "main-exec-status-pid", PID_FMT, s->main_exec_status.pid);
|
||||
(void) serialize_dual_timestamp(f, "main-exec-status-start", &s->main_exec_status.start_timestamp);
|
||||
(void) serialize_dual_timestamp(f, "main-exec-status-exit", &s->main_exec_status.exit_timestamp);
|
||||
(void) serialize_dual_timestamp(f, "main-exec-status-handover", &s->main_exec_status.handover_timestamp);
|
||||
(void) serialize_dual_timestamp(f, "main-exec-status-handoff", &s->main_exec_status.handoff_timestamp);
|
||||
|
||||
if (dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) {
|
||||
(void) serialize_item_format(f, "main-exec-status-code", "%i", s->main_exec_status.code);
|
||||
@ -3294,8 +3294,8 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
deserialize_dual_timestamp(value, &s->main_exec_status.start_timestamp);
|
||||
else if (streq(key, "main-exec-status-exit"))
|
||||
deserialize_dual_timestamp(value, &s->main_exec_status.exit_timestamp);
|
||||
else if (streq(key, "main-exec-status-handover"))
|
||||
deserialize_dual_timestamp(value, &s->main_exec_status.handover_timestamp);
|
||||
else if (streq(key, "main-exec-status-handoff"))
|
||||
deserialize_dual_timestamp(value, &s->main_exec_status.handoff_timestamp);
|
||||
else if (streq(key, "notify-access-override")) {
|
||||
NotifyAccess notify_access;
|
||||
|
||||
@ -4578,6 +4578,29 @@ static void service_notify_message(
|
||||
unit_add_to_dbus_queue(u);
|
||||
}
|
||||
|
||||
static void service_handoff_timestamp(
|
||||
Unit *u,
|
||||
const struct ucred *ucred,
|
||||
const dual_timestamp *ts) {
|
||||
|
||||
Service *s = ASSERT_PTR(SERVICE(u));
|
||||
|
||||
assert(ucred);
|
||||
assert(ts);
|
||||
|
||||
if (s->main_pid.pid == ucred->pid) {
|
||||
if (s->main_command)
|
||||
exec_status_handoff(&s->main_command->exec_status, ucred, ts);
|
||||
|
||||
exec_status_handoff(&s->main_exec_status, ucred, ts);
|
||||
} else if (s->control_pid.pid == ucred->pid && s->control_command)
|
||||
exec_status_handoff(&s->control_command->exec_status, ucred, ts);
|
||||
else
|
||||
return;
|
||||
|
||||
unit_add_to_dbus_queue(u);
|
||||
}
|
||||
|
||||
static int service_get_timeout(Unit *u, usec_t *timeout) {
|
||||
Service *s = ASSERT_PTR(SERVICE(u));
|
||||
uint64_t t;
|
||||
@ -5163,6 +5186,7 @@ const UnitVTable service_vtable = {
|
||||
.notify_cgroup_empty = service_notify_cgroup_empty_event,
|
||||
.notify_cgroup_oom = service_notify_cgroup_oom_event,
|
||||
.notify_message = service_notify_message,
|
||||
.notify_handoff_timestamp = service_handoff_timestamp,
|
||||
|
||||
.main_pid = service_main_pid,
|
||||
.control_pid = service_control_pid,
|
||||
|
@ -8,10 +8,10 @@ set -o pipefail
|
||||
systemd-run --service-type notify --property NotifyAccess=all --unit notify.service --wait sh -c 'systemd-notify --ready; exit 1' || :
|
||||
|
||||
start=$(systemctl show --property=ExecMainStartTimestampMonotonic --value notify.service)
|
||||
handover=$(systemctl show --property=ExecMainHandoverTimestampMonotonic --value notify.service)
|
||||
handoff=$(systemctl show --property=ExecMainHandoffTimestampMonotonic --value notify.service)
|
||||
active=$(systemctl show --property=ActiveEnterTimestampMonotonic --value notify.service)
|
||||
exit=$(systemctl show --property=ExecMainExitTimestampMonotonic --value notify.service)
|
||||
|
||||
[[ $start -le $handover ]]
|
||||
[[ $handover -le $active ]]
|
||||
[[ $start -le $handoff ]]
|
||||
[[ $handoff -le $active ]]
|
||||
[[ $active -le $exit ]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user