From 472619672a731ac7daf28ad8002a03cb080432ad Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 30 Jun 2023 15:56:40 +0200 Subject: [PATCH] mount: make unit_start() mount ratelimiting check generic Let's move this into a vtable callout, so that unit.c doesn't check for explicit unit types anymore. (This is preparation for a future where we do a similar check for the automount logic, or the swap logic.) --- src/core/mount.c | 10 ++++++++++ src/core/unit.c | 11 ++++++++--- src/core/unit.h | 4 ++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/core/mount.c b/src/core/mount.c index 1424ad2bf47..765c9899ef6 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -2299,6 +2299,15 @@ static int mount_can_start(Unit *u) { return 1; } +static int mount_subsystem_ratelimited(Manager *m) { + assert(m); + + if (!m->mount_event_source) + return false; + + return sd_event_source_is_ratelimited(m->mount_event_source); +} + static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { [MOUNT_EXEC_MOUNT] = "ExecMount", [MOUNT_EXEC_UNMOUNT] = "ExecUnmount", @@ -2379,6 +2388,7 @@ const UnitVTable mount_vtable = { .enumerate_perpetual = mount_enumerate_perpetual, .enumerate = mount_enumerate, .shutdown = mount_shutdown, + .subsystem_ratelimited = mount_subsystem_ratelimited, .status_message_formats = { .starting_stopping = { diff --git a/src/core/unit.c b/src/core/unit.c index 6e0702a8742..5904c9f4b59 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1920,9 +1920,14 @@ int unit_start(Unit *u, ActivationDetails *details) { assert(u); - /* Let's hold off running start jobs for mount units when /proc/self/mountinfo monitor is rate limited. */ - if (u->type == UNIT_MOUNT && sd_event_source_is_ratelimited(u->manager->mount_event_source)) - return -EAGAIN; + /* Let's hold off running start jobs for mount units when /proc/self/mountinfo monitor is ratelimited. */ + if (UNIT_VTABLE(u)->subsystem_ratelimited) { + r = UNIT_VTABLE(u)->subsystem_ratelimited(u->manager); + if (r < 0) + return r; + if (r > 0) + return -EAGAIN; + } /* If this is already started, then this will succeed. Note that this will even succeed if this unit * is not startable by the user. This is relied on to detect when we need to wait for units and when diff --git a/src/core/unit.h b/src/core/unit.h index 3a7330c24ff..c0710299a54 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -756,6 +756,10 @@ typedef struct UnitVTable { * limiting checks to occur before we do anything else. */ int (*can_start)(Unit *u); + /* Returns > 0 if the whole subsystem is ratelimited, and new start operations should not be started + * for this unit type right now. */ + int (*subsystem_ratelimited)(Manager *m); + /* The strings to print in status messages */ UnitStatusMessageFormats status_message_formats; -- 2.47.3