manager: add needs-stop/needs-start (#40709)
Intend to use these in the deb packaging scriptlets Fixes: #19755
This commit is contained in:
+14
-5
@@ -2132,17 +2132,26 @@ static int method_enqueue_marked_jobs(sd_bus_message *message, void *userdata, s
|
||||
continue;
|
||||
|
||||
BusUnitQueueFlags flags;
|
||||
if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART))
|
||||
JobType job;
|
||||
if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART)) {
|
||||
flags = 0;
|
||||
else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RELOAD))
|
||||
job = JOB_TRY_RESTART;
|
||||
} else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_RELOAD)) {
|
||||
flags = BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
|
||||
else
|
||||
job = JOB_TRY_RESTART;
|
||||
} else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_STOP)) {
|
||||
flags = 0;
|
||||
job = JOB_STOP;
|
||||
} else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_START)) {
|
||||
flags = 0;
|
||||
job = JOB_START;
|
||||
} else
|
||||
continue;
|
||||
|
||||
r = mac_selinux_unit_access_check(u, message, "start", &error);
|
||||
r = mac_selinux_unit_access_check(u, message, job_type_to_access_method(job), &error);
|
||||
if (r >= 0)
|
||||
r = bus_unit_queue_job_one(message, u,
|
||||
JOB_TRY_RESTART, JOB_FAIL, flags,
|
||||
job, JOB_FAIL, flags,
|
||||
reply, &error);
|
||||
if (ERRNO_IS_NEG_RESOURCE(r))
|
||||
return r;
|
||||
|
||||
@@ -2151,9 +2151,8 @@ static int bus_unit_set_live_property(
|
||||
|
||||
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||
if (some_absolute)
|
||||
u->markers = settings;
|
||||
else
|
||||
u->markers = settings | (u->markers & ~mask);
|
||||
mask = UINT_MAX;
|
||||
u->markers = unit_normalize_markers((u->markers & ~mask), settings);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
+45
-2
@@ -11,6 +11,7 @@
|
||||
#include "all-units.h"
|
||||
#include "alloc-util.h"
|
||||
#include "ansi-color.h"
|
||||
#include "bitfield.h"
|
||||
#include "bpf-restrict-fs.h"
|
||||
#include "bus-common-errors.h"
|
||||
#include "bus-internal.h"
|
||||
@@ -479,6 +480,9 @@ bool unit_may_gc(Unit *u) {
|
||||
if (r <= 0 && !IN_SET(r, -ENXIO, -EOWNERDEAD))
|
||||
return false; /* ENXIO/EOWNERDEAD means: currently not realized */
|
||||
|
||||
if (unit_can_start(u) && BIT_SET(u->markers, UNIT_MARKER_NEEDS_START))
|
||||
return false;
|
||||
|
||||
if (!UNIT_VTABLE(u)->may_gc)
|
||||
return true;
|
||||
|
||||
@@ -2758,11 +2762,13 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
|
||||
/* 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),
|
||||
(1u << UNIT_MARKER_NEEDS_RELOAD)|(1u << UNIT_MARKER_NEEDS_RESTART)|(1u << UNIT_MARKER_NEEDS_STOP),
|
||||
false);
|
||||
unit_prune_cgroup(u);
|
||||
unit_unlink_state_files(u);
|
||||
} else if (ns != os && ns == UNIT_RELOADING)
|
||||
} else if (UNIT_IS_ACTIVE_OR_ACTIVATING(ns))
|
||||
SET_FLAG(u->markers, 1u << UNIT_MARKER_NEEDS_START, false);
|
||||
else if (ns != os && ns == UNIT_RELOADING)
|
||||
SET_FLAG(u->markers, 1u << UNIT_MARKER_NEEDS_RELOAD, false);
|
||||
|
||||
unit_update_on_console(u);
|
||||
@@ -7086,8 +7092,45 @@ int parse_unit_marker(const char *marker, unsigned *settings, unsigned *mask) {
|
||||
if (m < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* When +- are not used, last one wins, so reset the bitmask before storing the new result */
|
||||
if (!some_plus_minus)
|
||||
*settings = 0;
|
||||
|
||||
SET_FLAG(*settings, 1u << m, b);
|
||||
SET_FLAG(*mask, 1u << m, true);
|
||||
|
||||
return some_plus_minus;
|
||||
}
|
||||
|
||||
unsigned unit_normalize_markers(unsigned existing_markers, unsigned new_markers) {
|
||||
/* Follow the job merging logic: when new markers conflict with existing ones, the new marker
|
||||
* takes precedence and clears out conflicting existing markers. Then standard normalization
|
||||
* resolves any remaining conflicts. */
|
||||
|
||||
/* New stop wins against all existing markers */
|
||||
if (BIT_SET(new_markers, UNIT_MARKER_NEEDS_STOP))
|
||||
CLEAR_BITS(existing_markers, UNIT_MARKER_NEEDS_RESTART, UNIT_MARKER_NEEDS_START, UNIT_MARKER_NEEDS_RELOAD);
|
||||
/* New start wins against existing stop */
|
||||
if (BIT_SET(new_markers, UNIT_MARKER_NEEDS_START))
|
||||
CLEAR_BIT(existing_markers, UNIT_MARKER_NEEDS_STOP);
|
||||
/* New restart wins against existing start and reload */
|
||||
if (BIT_SET(new_markers, UNIT_MARKER_NEEDS_RESTART))
|
||||
CLEAR_BITS(existing_markers, UNIT_MARKER_NEEDS_START, UNIT_MARKER_NEEDS_RELOAD);
|
||||
|
||||
unsigned markers = existing_markers | new_markers;
|
||||
|
||||
/* Standard normalization: reload loses against everything */
|
||||
if (BIT_SET(markers, UNIT_MARKER_NEEDS_RESTART) || BIT_SET(markers, UNIT_MARKER_NEEDS_START) || BIT_SET(markers, UNIT_MARKER_NEEDS_STOP))
|
||||
CLEAR_BIT(markers, UNIT_MARKER_NEEDS_RELOAD);
|
||||
/* Stop wins against restart and reload */
|
||||
if (BIT_SET(markers, UNIT_MARKER_NEEDS_STOP))
|
||||
CLEAR_BITS(markers, UNIT_MARKER_NEEDS_RESTART, UNIT_MARKER_NEEDS_RELOAD);
|
||||
/* Start wins against stop */
|
||||
if (BIT_SET(markers, UNIT_MARKER_NEEDS_START))
|
||||
CLEAR_BIT(markers, UNIT_MARKER_NEEDS_STOP);
|
||||
/* Restart wins against start */
|
||||
if (BITS_SET(markers, UNIT_MARKER_NEEDS_RESTART, UNIT_MARKER_NEEDS_START))
|
||||
CLEAR_BIT(markers, UNIT_MARKER_NEEDS_START);
|
||||
|
||||
return markers;
|
||||
}
|
||||
|
||||
@@ -1095,6 +1095,7 @@ DECLARE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);
|
||||
int unit_queue_job_check_and_mangle_type(Unit *u, JobType *type, bool reload_if_possible, sd_bus_error *reterr_error);
|
||||
|
||||
int parse_unit_marker(const char *marker, unsigned *settings, unsigned *mask);
|
||||
unsigned unit_normalize_markers(unsigned existing_markers, unsigned new_markers);
|
||||
|
||||
/* Macros which append UNIT= or USER_UNIT= to the message */
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error bus_error = SD_BUS_ERROR_NULL;
|
||||
const char *error_id = NULL;
|
||||
uint32_t job_id = 0; /* silence 'maybe-uninitialized' compiler warning */
|
||||
JobType job;
|
||||
|
||||
/* ignore aliases */
|
||||
if (u->id != k)
|
||||
@@ -350,14 +351,20 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
|
||||
|
||||
if (u->markers == 0)
|
||||
continue;
|
||||
if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_STOP))
|
||||
job = JOB_STOP;
|
||||
else if (BIT_SET(u->markers, UNIT_MARKER_NEEDS_START))
|
||||
job = JOB_START;
|
||||
else
|
||||
job = JOB_TRY_RESTART;
|
||||
|
||||
r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(JOB_TRY_RESTART));
|
||||
r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(job));
|
||||
if (r < 0)
|
||||
error_id = SD_VARLINK_ERROR_PERMISSION_DENIED;
|
||||
else
|
||||
r = varlink_unit_queue_job_one(
|
||||
u,
|
||||
JOB_TRY_RESTART,
|
||||
job,
|
||||
JOB_FAIL,
|
||||
/* reload_if_possible= */ !BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART),
|
||||
&job_id,
|
||||
|
||||
@@ -668,7 +668,7 @@ int vl_method_set_unit_properties(sd_varlink *link, sd_json_variant *parameters,
|
||||
return r;
|
||||
|
||||
if (p.markers_found)
|
||||
unit->markers = p.markers | (unit->markers & ~p.markers_mask);
|
||||
unit->markers = unit_normalize_markers((unit->markers & ~p.markers_mask), p.markers);
|
||||
|
||||
return sd_varlink_reply(link, NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user