mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
core: add Unit.Markers property
The property is never set by systemd, only reset after a stop or restart or reload. It may externally be set to mark the unit for a later restart/reload. I wasn't sure whether to configure the property only for the types where this makes sense (Service, Swap, etc). But Restart() method is defined on the unit, and also having this always under the same property name is more convenient.
This commit is contained in:
parent
8c2524c7fd
commit
ff68472a20
@ -1685,6 +1685,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
readonly b IgnoreOnIsolate = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly b NeedDaemonReload = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
|
||||
readonly as Markers = ['...', ...];
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly t JobTimeoutUSec = ...;
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
@ -1969,6 +1971,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="NeedDaemonReload"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Markers"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="JobTimeoutUSec"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="JobRunningTimeoutUSec"/>
|
||||
@ -2160,8 +2164,16 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
|
||||
|
||||
<para><varname>NeedDaemonReload</varname> is a boolean that indicates whether the configuration file
|
||||
this unit is loaded from (i.e. <varname>FragmentPath</varname> or <varname>SourcePath</varname>) has
|
||||
changed since the configuration was read and hence whether a configuration reload is
|
||||
recommended.</para>
|
||||
changed since the configuration was read and hence whether a configuration reload is recommended.
|
||||
</para>
|
||||
|
||||
<para><varname>Markers</varname> is an array of string flags that can be set using
|
||||
<function>SetUnitProperties()</function> to indicate that the service should be reloaded or
|
||||
restarted. Currently known values are <literal>needs-restart</literal> and
|
||||
<literal>needs-reload</literal>. Package scripts may use the first to mark units for later restart when
|
||||
a new version of the package is installed. Configuration management scripts may use the second to mark
|
||||
units for a later reload when the configuration is adjusted. Those flags are not set by the manager,
|
||||
except to unset as appropriate when when the unit is stopped, restarted, or reloaded.</para>
|
||||
|
||||
<para><varname>JobTimeoutUSec</varname> maps directly to the corresponding configuration setting in the
|
||||
unit file.</para>
|
||||
|
@ -117,6 +117,13 @@ static const char* const freezer_state_table[_FREEZER_STATE_MAX] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(freezer_state, FreezerState);
|
||||
|
||||
static const char* const unit_marker_table[_UNIT_MARKER_MAX] = {
|
||||
[UNIT_MARKER_NEEDS_RELOAD] = "needs-reload",
|
||||
[UNIT_MARKER_NEEDS_RESTART] = "needs-restart",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(unit_marker, UnitMarker);
|
||||
|
||||
static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
|
||||
[AUTOMOUNT_DEAD] = "dead",
|
||||
[AUTOMOUNT_WAITING] = "waiting",
|
||||
|
@ -58,6 +58,13 @@ typedef enum FreezerState {
|
||||
_FREEZER_STATE_INVALID = -EINVAL,
|
||||
} FreezerState;
|
||||
|
||||
typedef enum UnitMarker {
|
||||
UNIT_MARKER_NEEDS_RELOAD,
|
||||
UNIT_MARKER_NEEDS_RESTART,
|
||||
_UNIT_MARKER_MAX,
|
||||
_UNIT_MARKER_INVALID = -1
|
||||
} UnitMarker;
|
||||
|
||||
typedef enum AutomountState {
|
||||
AUTOMOUNT_DEAD,
|
||||
AUTOMOUNT_WAITING,
|
||||
@ -267,6 +274,9 @@ UnitActiveState unit_active_state_from_string(const char *s) _pure_;
|
||||
const char *freezer_state_to_string(FreezerState i) _const_;
|
||||
FreezerState freezer_state_from_string(const char *s) _pure_;
|
||||
|
||||
const char *unit_marker_to_string(UnitMarker m) _const_;
|
||||
UnitMarker unit_marker_from_string(const char *s) _pure_;
|
||||
|
||||
const char* automount_state_to_string(AutomountState i) _const_;
|
||||
AutomountState automount_state_from_string(const char *s) _pure_;
|
||||
|
||||
|
@ -323,6 +323,39 @@ static int property_get_load_error(
|
||||
return sd_bus_message_append(reply, "(ss)", NULL, NULL);
|
||||
}
|
||||
|
||||
static int property_get_markers(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
const char *interface,
|
||||
const char *property,
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
unsigned *markers = userdata;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(markers);
|
||||
|
||||
r = sd_bus_message_open_container(reply, 'a', "s");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Make sure out values fit in the bitfield. */
|
||||
assert_cc(_UNIT_MARKER_MAX <= sizeof(((Unit){}).markers) * 8);
|
||||
|
||||
for (UnitMarker m = 0; m < _UNIT_MARKER_MAX; m++)
|
||||
if (FLAGS_SET(*markers, 1u << m)) {
|
||||
r = sd_bus_message_append(reply, "s", unit_marker_to_string(m));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return sd_bus_message_close_container(reply);
|
||||
}
|
||||
|
||||
static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = {
|
||||
[JOB_START] = N_("Authentication is required to start '$(unit)'."),
|
||||
[JOB_STOP] = N_("Authentication is required to stop '$(unit)'."),
|
||||
@ -864,6 +897,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
||||
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
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("Markers", "as", property_get_markers, offsetof(Unit, markers), 0),
|
||||
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),
|
||||
|
@ -28,6 +28,45 @@ static int serialize_cgroup_mask(FILE *f, const char *key, CGroupMask mask) {
|
||||
return serialize_item(f, key, s);
|
||||
}
|
||||
|
||||
/* Make sure out values fit in the bitfield. */
|
||||
assert_cc(_UNIT_MARKER_MAX <= sizeof(((Unit){}).markers) * 8);
|
||||
|
||||
static int serialize_markers(FILE *f, unsigned markers) {
|
||||
assert(f);
|
||||
|
||||
if (markers == 0)
|
||||
return 0;
|
||||
|
||||
fputs("markers=", f);
|
||||
for (UnitMarker m = 0; m < _UNIT_MARKER_MAX; m++)
|
||||
if (FLAGS_SET(markers, 1u << m))
|
||||
fputs(unit_marker_to_string(m), f);
|
||||
fputc('\n', f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deserialize_markers(Unit *u, const char *value) {
|
||||
assert(u);
|
||||
assert(value);
|
||||
int r;
|
||||
|
||||
for (const char *p = value;;) {
|
||||
_cleanup_free_ char *word = NULL;
|
||||
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
UnitMarker m = unit_marker_from_string(word);
|
||||
if (m < 0) {
|
||||
log_unit_debug_errno(u, m, "Unknown unit marker \"%s\", ignoring.", word);
|
||||
continue;
|
||||
}
|
||||
|
||||
u->markers |= 1u << m;
|
||||
}
|
||||
}
|
||||
|
||||
static const char *const ip_accounting_metric_field[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
|
||||
[CGROUP_IP_INGRESS_BYTES] = "ip-accounting-ingress-bytes",
|
||||
[CGROUP_IP_INGRESS_PACKETS] = "ip-accounting-ingress-packets",
|
||||
@ -121,6 +160,7 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
|
||||
(void) serialize_item_format(f, "invocation-id", SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id));
|
||||
|
||||
(void) serialize_item_format(f, "freezer-state", "%s", freezer_state_to_string(unit_freezer_state(u)));
|
||||
(void) serialize_markers(f, u->markers);
|
||||
|
||||
bus_track_serialize(u->bus_track, f, "ref");
|
||||
|
||||
@ -365,6 +405,13 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
} else if (MATCH_DESERIALIZE("freezer-state", l, v, freezer_state_from_string, u->freezer_state))
|
||||
continue;
|
||||
|
||||
else if (streq(l, "markers")) {
|
||||
r = deserialize_markers(u, v);
|
||||
if (r < 0)
|
||||
log_unit_debug_errno(u, r, "Failed to deserialize \"%s=%s\", ignoring: %m", l, v);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if this is an IP accounting metric serialization field */
|
||||
m = string_table_lookup(ip_accounting_metric_field, ELEMENTSOF(ip_accounting_metric_field), l);
|
||||
if (m >= 0) {
|
||||
@ -559,6 +606,15 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
|
||||
prefix, strna(u->cgroup_path),
|
||||
prefix, yes_no(u->cgroup_realized));
|
||||
|
||||
if (u->markers != 0) {
|
||||
fprintf(f, "%s\tMarkers:", prefix);
|
||||
|
||||
for (UnitMarker marker = 0; marker < _UNIT_MARKER_MAX; marker++)
|
||||
if (FLAGS_SET(u->markers, 1u << marker))
|
||||
fprintf(f, " %s", unit_marker_to_string(marker));
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
if (u->cgroup_realized_mask != 0) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
(void) cg_mask_to_string(u->cgroup_realized_mask, &s);
|
||||
|
@ -2390,9 +2390,13 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
|
||||
|
||||
/* Make sure the cgroup and state files are always removed when we become inactive */
|
||||
if (UNIT_IS_INACTIVE_OR_FAILED(ns)) {
|
||||
SET_FLAG(u->markers,
|
||||
(1u << UNIT_MARKER_NEEDS_RELOAD)|(1u << UNIT_MARKER_NEEDS_RESTART),
|
||||
false);
|
||||
unit_prune_cgroup(u);
|
||||
unit_unlink_state_files(u);
|
||||
}
|
||||
} else if (ns != os && ns == UNIT_RELOADING)
|
||||
SET_FLAG(u->markers, 1u << UNIT_MARKER_NEEDS_RELOAD, false);
|
||||
|
||||
unit_update_on_console(u);
|
||||
|
||||
|
@ -242,6 +242,9 @@ typedef struct Unit {
|
||||
RateLimit start_ratelimit;
|
||||
EmergencyAction start_limit_action;
|
||||
|
||||
/* The unit has been marked for reload, restart, etc. Stored as 1u << marker1 | 1u << marker2. */
|
||||
unsigned markers;
|
||||
|
||||
/* What to do on failure or success */
|
||||
EmergencyAction success_action, failure_action;
|
||||
int success_action_exit_status, failure_action_exit_status;
|
||||
|
@ -6,7 +6,7 @@
|
||||
static void test_udev_builtin_cmd_to_ptr(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
/* Those could have been static_assert()s, but ({}) is not allowed there. */
|
||||
/* Those could have been static asserts, but ({}) is not allowed there. */
|
||||
#if HAVE_BLKID
|
||||
assert_se(UDEV_BUILTIN_CMD_TO_PTR(UDEV_BUILTIN_BLKID));
|
||||
assert_se(PTR_TO_UDEV_BUILTIN_CMD(UDEV_BUILTIN_CMD_TO_PTR(UDEV_BUILTIN_BLKID)) == UDEV_BUILTIN_BLKID);
|
||||
|
Loading…
Reference in New Issue
Block a user