mirror of
https://github.com/systemd/systemd.git
synced 2025-02-25 21:57:32 +03:00
core/transaction: add taint flag signifying presence of dependency cycles
This commit is contained in:
parent
321c202e7c
commit
afbde99253
@ -131,8 +131,10 @@ static int property_get_tainted(
|
||||
|
||||
assert(bus);
|
||||
assert(reply);
|
||||
assert(userdata);
|
||||
|
||||
_cleanup_free_ char *s = taint_string();
|
||||
Manager *m = userdata;
|
||||
_cleanup_free_ char *s = taint_string(m);
|
||||
if (!s)
|
||||
return log_oom();
|
||||
|
||||
|
@ -3857,7 +3857,7 @@ static void log_taint_string(Manager *m) {
|
||||
|
||||
m->taint_logged = true; /* only check for taint once */
|
||||
|
||||
_cleanup_free_ char *taint = taint_string();
|
||||
_cleanup_free_ char *taint = taint_string(m);
|
||||
if (isempty(taint))
|
||||
return;
|
||||
|
||||
@ -5302,6 +5302,16 @@ int manager_allocate_idle_pipe(Manager *m) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool manager_was_dependency_cycle(const Manager *m) {
|
||||
const Unit *u;
|
||||
|
||||
HASHMAP_FOREACH(u, m->units)
|
||||
if (u->was_on_dependency_cycle)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope) {
|
||||
assert(defaults);
|
||||
assert(scope >= 0);
|
||||
|
@ -679,6 +679,8 @@ OOMPolicy oom_policy_from_string(const char *s) _pure_;
|
||||
void unit_defaults_init(UnitDefaults *defaults, RuntimeScope scope);
|
||||
void unit_defaults_done(UnitDefaults *defaults);
|
||||
|
||||
bool manager_was_dependency_cycle(const Manager *m);
|
||||
|
||||
enum {
|
||||
/* most important … */
|
||||
EVENT_PRIORITY_USER_LOOKUP = SD_EVENT_PRIORITY_NORMAL-12,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
#include "manager.h"
|
||||
#include "os-util.h"
|
||||
#include "path-util.h"
|
||||
#include "strv.h"
|
||||
@ -31,8 +32,8 @@ static int short_uid_gid_range(UIDRangeUsernsMode mode) {
|
||||
return !uid_range_covers(p, 0, 65535);
|
||||
}
|
||||
|
||||
char** taint_strv(void) {
|
||||
const char *stage[12] = {};
|
||||
char** taint_strv(const Manager *m) {
|
||||
const char *stage[13] = {};
|
||||
size_t n = 0;
|
||||
|
||||
/* Returns a "taint string", e.g. "local-hwclock:var-run-bad". Only things that are detected at
|
||||
@ -78,16 +79,18 @@ char** taint_strv(void) {
|
||||
stage[n++] = "short-uid-range";
|
||||
if (short_uid_gid_range(GID_RANGE_USERNS_INSIDE) > 0)
|
||||
stage[n++] = "short-gid-range";
|
||||
if (manager_was_dependency_cycle(m))
|
||||
stage[n++] = "dependency-cycle";
|
||||
|
||||
assert(n < ELEMENTSOF(stage) - 1); /* One extra for NULL terminator */
|
||||
|
||||
return strv_copy((char *const *) stage);
|
||||
}
|
||||
|
||||
char* taint_string(void) {
|
||||
char* taint_string(const Manager *m) {
|
||||
_cleanup_strv_free_ char **taints = NULL;
|
||||
|
||||
taints = taint_strv();
|
||||
taints = taint_strv(m);
|
||||
if (!taints)
|
||||
return NULL;
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
char** taint_strv(void);
|
||||
char* taint_string(void);
|
||||
typedef struct Manager Manager;
|
||||
|
||||
char** taint_strv(const Manager *m);
|
||||
char* taint_string(const Manager *m);
|
||||
|
@ -383,6 +383,9 @@ static int transaction_verify_order_one(Transaction *tr, Job *j, Job *from, unsi
|
||||
if (strv_push_pair(&array, k->unit->id, (char*) job_type_to_string(k->type)) < 0)
|
||||
log_oom();
|
||||
|
||||
/* Mark every unit along the cycle */
|
||||
k->unit->was_on_dependency_cycle = true;
|
||||
|
||||
if (!delete && hashmap_contains(tr->jobs, k->unit) && !job_matters_to_anchor(k))
|
||||
/* Ok, we can drop this one, so let's do so. */
|
||||
delete = k;
|
||||
|
@ -3834,6 +3834,7 @@ void unit_reset_failed(Unit *u) {
|
||||
ratelimit_reset(&u->start_ratelimit);
|
||||
u->start_limit_hit = false;
|
||||
u->debug_invocation = false;
|
||||
u->was_on_dependency_cycle = false;
|
||||
}
|
||||
|
||||
Unit *unit_following(Unit *u) {
|
||||
|
@ -464,6 +464,9 @@ typedef struct Unit {
|
||||
/* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If
|
||||
* == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */
|
||||
signed int last_section_private:2;
|
||||
|
||||
/* Remember this unit was part of some dependency cycle. */
|
||||
bool was_on_dependency_cycle;
|
||||
} Unit;
|
||||
|
||||
typedef struct UnitStatusMessageFormats {
|
||||
|
@ -1,10 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "manager.h"
|
||||
#include "taint.h"
|
||||
#include "tests.h"
|
||||
|
||||
TEST(taint_string) {
|
||||
_cleanup_free_ char *a = taint_string();
|
||||
Manager m = {};
|
||||
_cleanup_free_ char *a = taint_string(&m);
|
||||
assert_se(a);
|
||||
log_debug("taint string: '%s'", a);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user