X Tutup
Skip to content

Commit 986935c

Browse files
committed
pid1: update manager settings on reload too
Most complexity of this patch is due to the fact that some manager settings (basically the watchdog properties) can be set at runtime and in this case the runtime values must be retained over daemon-reload or daemon-reexec. For consistency sake, all watchdog properties behaves now the same way, that is: - Values defined by config files can be overridden by writing the new value through their respective D-BUS properties. In this case, these values are preserved over reload/reexec until the special value '0' or USEC_INFINITY is written, which will then restore the last values loaded from the config files. If the restored value is '0' or 'USEC_INFINITY', the watchdogs will be disabled and the corresponding device will be closed. - Reading the properties from a user instance will return the USEC_INFINITY value as these properties are only meaningful for PID1. - Writing to one of the watchdog properties of a user instance's will be a NOP. Fixes: systemd#15453
1 parent 34d16ba commit 986935c

File tree

4 files changed

+223
-30
lines changed

4 files changed

+223
-30
lines changed

src/core/dbus-manager.c

Lines changed: 98 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -244,28 +244,116 @@ static int property_get_show_status(
244244
return sd_bus_message_append_basic(reply, 'b', &b);
245245
}
246246

247-
static int property_set_runtime_watchdog(
247+
static int property_get_runtime_watchdog(
248248
sd_bus *bus,
249249
const char *path,
250250
const char *interface,
251251
const char *property,
252-
sd_bus_message *value,
252+
sd_bus_message *reply,
253253
void *userdata,
254254
sd_bus_error *error) {
255255

256-
usec_t *t = userdata;
257-
int r;
256+
Manager *m = userdata;
258257

258+
assert(m);
259259
assert(bus);
260+
assert(reply);
261+
262+
return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_RUNTIME));
263+
}
264+
265+
static int property_get_reboot_watchdog(
266+
sd_bus *bus,
267+
const char *path,
268+
const char *interface,
269+
const char *property,
270+
sd_bus_message *reply,
271+
void *userdata,
272+
sd_bus_error *error) {
273+
274+
Manager *m = userdata;
275+
276+
assert(m);
277+
assert(bus);
278+
assert(reply);
279+
280+
return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_REBOOT));
281+
}
282+
283+
static int property_get_kexec_watchdog(
284+
sd_bus *bus,
285+
const char *path,
286+
const char *interface,
287+
const char *property,
288+
sd_bus_message *reply,
289+
void *userdata,
290+
sd_bus_error *error) {
291+
292+
Manager *m = userdata;
293+
294+
assert(m);
295+
assert(bus);
296+
assert(reply);
297+
298+
return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_KEXEC));
299+
}
300+
301+
static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *value) {
302+
usec_t timeout;
303+
int r;
304+
305+
assert(m);
260306
assert(value);
261307

262308
assert_cc(sizeof(usec_t) == sizeof(uint64_t));
263309

264-
r = sd_bus_message_read(value, "t", t);
310+
r = sd_bus_message_read(value, "t", &timeout);
265311
if (r < 0)
266312
return r;
267313

268-
return watchdog_set_timeout(t);
314+
return manager_set_watchdog_overridden(m, type, timeout);
315+
}
316+
317+
static int property_set_runtime_watchdog(
318+
sd_bus *bus,
319+
const char *path,
320+
const char *interface,
321+
const char *property,
322+
sd_bus_message *value,
323+
void *userdata,
324+
sd_bus_error *error) {
325+
326+
return property_set_watchdog(userdata, WATCHDOG_RUNTIME, value);
327+
}
328+
329+
static int property_set_reboot_watchdog(
330+
sd_bus *bus,
331+
const char *path,
332+
const char *interface,
333+
const char *property,
334+
sd_bus_message *value,
335+
void *userdata,
336+
sd_bus_error *error) {
337+
338+
return property_set_watchdog(userdata, WATCHDOG_REBOOT, value);
339+
}
340+
341+
static int property_set_kexec_watchdog(
342+
sd_bus *bus,
343+
const char *path,
344+
const char *interface,
345+
const char *property,
346+
sd_bus_message *value,
347+
void *userdata,
348+
sd_bus_error *error) {
349+
350+
Manager *m = userdata;
351+
352+
assert(m);
353+
assert(bus);
354+
assert(value);
355+
356+
return property_set_watchdog(userdata, WATCHDOG_KEXEC, value);
269357
}
270358

271359
static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
@@ -2404,11 +2492,11 @@ const sd_bus_vtable bus_manager_vtable[] = {
24042492
SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
24052493
SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
24062494
SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2407-
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
2408-
SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, reboot_watchdog), 0),
2495+
SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", property_get_runtime_watchdog, property_set_runtime_watchdog, 0, 0),
2496+
SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, 0),
24092497
/* The following item is an obsolete alias */
2410-
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, reboot_watchdog), SD_BUS_VTABLE_HIDDEN),
2411-
SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, kexec_watchdog), 0),
2498+
SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, SD_BUS_VTABLE_HIDDEN),
2499+
SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", property_get_kexec_watchdog, property_set_kexec_watchdog, 0, 0),
24122500
SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0),
24132501
SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
24142502
SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),

src/core/main.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -703,16 +703,18 @@ static void set_manager_settings(Manager *m) {
703703

704704
assert(m);
705705

706-
/* Propagates the various manager settings into the manager object, i.e. properties that effect the manager
707-
* itself (as opposed to just being inherited into newly allocated units, see set_manager_defaults() above). */
706+
/* Propagates the various manager settings into the manager object, i.e. properties that
707+
* effect the manager itself (as opposed to just being inherited into newly allocated
708+
* units, see set_manager_defaults() above). */
708709

709710
m->confirm_spawn = arg_confirm_spawn;
710711
m->service_watchdogs = arg_service_watchdogs;
711-
m->runtime_watchdog = arg_runtime_watchdog;
712-
m->reboot_watchdog = arg_reboot_watchdog;
713-
m->kexec_watchdog = arg_kexec_watchdog;
714712
m->cad_burst_action = arg_cad_burst_action;
715713

714+
manager_set_watchdog(m, WATCHDOG_RUNTIME, arg_runtime_watchdog);
715+
manager_set_watchdog(m, WATCHDOG_REBOOT, arg_reboot_watchdog);
716+
manager_set_watchdog(m, WATCHDOG_KEXEC, arg_kexec_watchdog);
717+
716718
manager_set_show_status(m, arg_show_status, "commandline");
717719
m->status_unit_format = arg_status_unit_format;
718720
}
@@ -1784,6 +1786,7 @@ static int invoke_main_loop(
17841786
(void) parse_configuration(saved_rlimit_nofile, saved_rlimit_memlock);
17851787

17861788
set_manager_defaults(m);
1789+
set_manager_settings(m);
17871790

17881791
update_cpu_affinity(false);
17891792
update_numa_policy(false);
@@ -1974,9 +1977,6 @@ static int initialize_runtime(
19741977
if (r < 0)
19751978
log_warning_errno(r, "Failed to set watchdog device to %s, ignoring: %m", arg_watchdog_device);
19761979
}
1977-
1978-
if (timestamp_is_set(arg_runtime_watchdog))
1979-
watchdog_set_timeout(&arg_runtime_watchdog);
19801980
}
19811981

19821982
if (arg_timer_slack_nsec != NSEC_INFINITY)
@@ -2250,6 +2250,10 @@ static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
22502250
/* Note that this also parses bits from the kernel command line, including "debug". */
22512251
log_parse_environment();
22522252

2253+
/* Initialize the show status setting if it hasn't been set explicitly yet */
2254+
if (arg_show_status == _SHOW_STATUS_INVALID)
2255+
arg_show_status = SHOW_STATUS_YES;
2256+
22532257
return 0;
22542258
}
22552259

@@ -2273,10 +2277,6 @@ static int load_configuration(
22732277
return r;
22742278
}
22752279

2276-
/* Initialize the show status setting if it hasn't been set explicitly yet */
2277-
if (arg_show_status == _SHOW_STATUS_INVALID)
2278-
arg_show_status = SHOW_STATUS_YES;
2279-
22802280
return 0;
22812281
}
22822282

@@ -2753,8 +2753,8 @@ int main(int argc, char *argv[]) {
27532753
pager_close();
27542754

27552755
if (m) {
2756-
arg_reboot_watchdog = m->reboot_watchdog;
2757-
arg_kexec_watchdog = m->kexec_watchdog;
2756+
arg_reboot_watchdog = manager_get_watchdog(m, WATCHDOG_REBOOT);
2757+
arg_kexec_watchdog = manager_get_watchdog(m, WATCHDOG_KEXEC);
27582758
m = manager_free(m);
27592759
}
27602760

src/core/manager.c

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,10 @@ int manager_new(UnitFileScope scope, ManagerTestRunFlags test_run_flags, Manager
779779
.original_log_level = -1,
780780
.original_log_target = _LOG_TARGET_INVALID,
781781

782+
.watchdog_overridden[WATCHDOG_RUNTIME] = USEC_INFINITY,
783+
.watchdog_overridden[WATCHDOG_REBOOT] = USEC_INFINITY,
784+
.watchdog_overridden[WATCHDOG_KEXEC] = USEC_INFINITY,
785+
782786
.notify_fd = -1,
783787
.cgroups_agent_fd = -1,
784788
.signal_fd = -1,
@@ -2922,9 +2926,10 @@ int manager_loop(Manager *m) {
29222926
return log_error_errno(r, "Failed to enable SIGCHLD event source: %m");
29232927

29242928
while (m->objective == MANAGER_OK) {
2925-
usec_t wait_usec;
2929+
usec_t wait_usec, watchdog_usec;
29262930

2927-
if (timestamp_is_set(m->runtime_watchdog) && MANAGER_IS_SYSTEM(m))
2931+
watchdog_usec = manager_get_watchdog(m, WATCHDOG_RUNTIME);
2932+
if (timestamp_is_set(watchdog_usec))
29282933
watchdog_ping();
29292934

29302935
if (!ratelimit_below(&rl)) {
@@ -2955,7 +2960,7 @@ int manager_loop(Manager *m) {
29552960
continue;
29562961

29572962
/* Sleep for watchdog runtime wait time */
2958-
if (MANAGER_IS_SYSTEM(m))
2963+
if (timestamp_is_set(watchdog_usec))
29592964
wait_usec = watchdog_runtime_wait();
29602965
else
29612966
wait_usec = USEC_INFINITY;
@@ -3196,6 +3201,10 @@ int manager_serialize(
31963201
if (m->log_target_overridden)
31973202
(void) serialize_item(f, "log-target-override", log_target_to_string(log_get_target()));
31983203

3204+
(void) serialize_usec(f, "runtime-watchdog-overridden", m->watchdog_overridden[WATCHDOG_RUNTIME]);
3205+
(void) serialize_usec(f, "reboot-watchdog-overridden", m->watchdog_overridden[WATCHDOG_REBOOT]);
3206+
(void) serialize_usec(f, "kexec-watchdog-overridden", m->watchdog_overridden[WATCHDOG_KEXEC]);
3207+
31993208
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
32003209
_cleanup_free_ char *joined = NULL;
32013210

@@ -3328,6 +3337,68 @@ static int manager_deserialize_units(Manager *m, FILE *f, FDSet *fds) {
33283337
return 0;
33293338
}
33303339

3340+
usec_t manager_get_watchdog(Manager *m, WatchdogType t) {
3341+
assert(m);
3342+
3343+
if (MANAGER_IS_USER(m))
3344+
return USEC_INFINITY;
3345+
3346+
if (timestamp_is_set(m->watchdog_overridden[t]))
3347+
return m->watchdog_overridden[t];
3348+
3349+
return m->watchdog[t];
3350+
}
3351+
3352+
void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout) {
3353+
int r = 0;
3354+
3355+
assert(m);
3356+
3357+
if (MANAGER_IS_USER(m))
3358+
return;
3359+
3360+
if (m->watchdog[t] == timeout)
3361+
return;
3362+
3363+
if (t == WATCHDOG_RUNTIME)
3364+
if (!timestamp_is_set(m->watchdog_overridden[WATCHDOG_RUNTIME])) {
3365+
if (timestamp_is_set(timeout))
3366+
r = watchdog_set_timeout(&timeout);
3367+
else
3368+
watchdog_close(true);
3369+
}
3370+
3371+
if (r >= 0)
3372+
m->watchdog[t] = timeout;
3373+
}
3374+
3375+
int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout) {
3376+
int r = 0;
3377+
3378+
assert(m);
3379+
3380+
if (MANAGER_IS_USER(m))
3381+
return 0;
3382+
3383+
if (m->watchdog_overridden[t] == timeout)
3384+
return 0;
3385+
3386+
if (t == WATCHDOG_RUNTIME) {
3387+
usec_t *p;
3388+
3389+
p = timestamp_is_set(timeout) ? &timeout : &m->watchdog[t];
3390+
if (timestamp_is_set(*p))
3391+
r = watchdog_set_timeout(p);
3392+
else
3393+
watchdog_close(true);
3394+
}
3395+
3396+
if (r >= 0)
3397+
m->watchdog_overridden[t] = timeout;
3398+
3399+
return 0;
3400+
}
3401+
33313402
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
33323403
int r = 0;
33333404

@@ -3451,6 +3522,30 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
34513522
else
34523523
manager_override_log_target(m, target);
34533524

3525+
} else if ((val = startswith(l, "runtime-watchdog-overridden="))) {
3526+
usec_t t;
3527+
3528+
if (deserialize_usec(val, &t) < 0)
3529+
log_notice("Failed to parse runtime-watchdog-overridden value '%s', ignoring.", val);
3530+
else
3531+
manager_set_watchdog_overridden(m, WATCHDOG_RUNTIME, t);
3532+
3533+
} else if ((val = startswith(l, "reboot-watchdog-overridden="))) {
3534+
usec_t t;
3535+
3536+
if (deserialize_usec(val, &t) < 0)
3537+
log_notice("Failed to parse reboot-watchdog-overridden value '%s', ignoring.", val);
3538+
else
3539+
manager_set_watchdog_overridden(m, WATCHDOG_REBOOT, t);
3540+
3541+
} else if ((val = startswith(l, "kexec-watchdog-overridden="))) {
3542+
usec_t t;
3543+
3544+
if (deserialize_usec(val, &t) < 0)
3545+
log_notice("Failed to parse kexec-watchdog-overridden value '%s', ignoring.", val);
3546+
else
3547+
manager_set_watchdog_overridden(m, WATCHDOG_KEXEC, t);
3548+
34543549
} else if (startswith(l, "env=")) {
34553550
r = deserialize_environment(l + 4, &m->client_environment);
34563551
if (r < 0)

src/core/manager.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ typedef enum ManagerTimestamp {
114114
_MANAGER_TIMESTAMP_INVALID = -1,
115115
} ManagerTimestamp;
116116

117+
typedef enum WatchdogType {
118+
WATCHDOG_RUNTIME,
119+
WATCHDOG_REBOOT,
120+
WATCHDOG_KEXEC,
121+
_WATCHDOG_TYPE_MAX,
122+
} WatchdogType;
123+
117124
#include "execute.h"
118125
#include "job.h"
119126
#include "path-lookup.h"
@@ -231,9 +238,8 @@ struct Manager {
231238
char **transient_environment; /* The environment, as determined from config files, kernel cmdline and environment generators */
232239
char **client_environment; /* Environment variables created by clients through the bus API */
233240

234-
usec_t runtime_watchdog;
235-
usec_t reboot_watchdog;
236-
usec_t kexec_watchdog;
241+
usec_t watchdog[_WATCHDOG_TYPE_MAX];
242+
usec_t watchdog_overridden[_WATCHDOG_TYPE_MAX];
237243

238244
dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX];
239245

@@ -555,5 +561,9 @@ const char *manager_timestamp_to_string(ManagerTimestamp m) _const_;
555561
ManagerTimestamp manager_timestamp_from_string(const char *s) _pure_;
556562
ManagerTimestamp manager_timestamp_initrd_mangle(ManagerTimestamp s);
557563

564+
usec_t manager_get_watchdog(Manager *m, WatchdogType t);
565+
void manager_set_watchdog(Manager *m, WatchdogType t, usec_t timeout);
566+
int manager_set_watchdog_overridden(Manager *m, WatchdogType t, usec_t timeout);
567+
558568
const char* oom_policy_to_string(OOMPolicy i) _const_;
559569
OOMPolicy oom_policy_from_string(const char *s) _pure_;

0 commit comments

Comments
 (0)
X Tutup