Merge pull request #20953 from msekletar/mount-ratelimit-followup-20329

Delay running mount start jobs when we /p/s/mountinfo event source is rate limited
This commit is contained in:
Lennart Poettering
2021-11-12 09:23:47 +01:00
committed by GitHub
15 changed files with 135 additions and 39 deletions
+3 -3
View File
@@ -1063,7 +1063,7 @@ static bool automount_supported(void) {
return supported;
}
static int automount_test_start_limit(Unit *u) {
static int automount_can_start(Unit *u) {
Automount *a = AUTOMOUNT(u);
int r;
@@ -1075,7 +1075,7 @@ static int automount_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
@@ -1142,5 +1142,5 @@ const UnitVTable automount_vtable = {
},
},
.test_start_limit = automount_test_start_limit,
.can_start = automount_can_start,
};
+27 -3
View File
@@ -1838,6 +1838,21 @@ static bool mount_is_mounted(Mount *m) {
return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
}
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
Manager *m = userdata;
int r;
assert(m);
/* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's
* make sure we dispatch them in the next iteration. */
r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT);
if (r < 0)
log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m");
return 0;
}
static void mount_enumerate(Manager *m) {
int r;
@@ -1891,6 +1906,12 @@ static void mount_enumerate(Manager *m) {
goto fail;
}
r = sd_event_source_set_ratelimit_expire_callback(m->mount_event_source, mount_on_ratelimit_expire);
if (r < 0) {
log_error_errno(r, "Failed to enable rate limit for mount events: %m");
goto fail;
}
(void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch");
}
@@ -2135,19 +2156,22 @@ static int mount_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&m->exec_context, ret);
}
static int mount_test_start_limit(Unit *u) {
static int mount_can_start(Unit *u) {
Mount *m = MOUNT(u);
int r;
assert(m);
if (sd_event_source_is_ratelimited(u->manager->mount_event_source))
return -EAGAIN;
r = unit_test_start_limit(u);
if (r < 0) {
mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT);
return r;
}
return 0;
return 1;
}
static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
@@ -2248,5 +2272,5 @@ const UnitVTable mount_vtable = {
},
},
.test_start_limit = mount_test_start_limit,
.can_start = mount_can_start,
};
+3 -3
View File
@@ -811,7 +811,7 @@ static void path_reset_failed(Unit *u) {
p->result = PATH_SUCCESS;
}
static int path_test_start_limit(Unit *u) {
static int path_can_start(Unit *u) {
Path *p = PATH(u);
int r;
@@ -823,7 +823,7 @@ static int path_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const path_type_table[_PATH_TYPE_MAX] = {
@@ -882,5 +882,5 @@ const UnitVTable path_vtable = {
.bus_set_property = bus_path_set_property,
.test_start_limit = path_test_start_limit,
.can_start = path_can_start,
};
+3 -3
View File
@@ -4482,7 +4482,7 @@ static const char *service_finished_job(Unit *u, JobType t, JobResult result) {
return NULL;
}
static int service_test_start_limit(Unit *u) {
static int service_can_start(Unit *u) {
Service *s = SERVICE(u);
int r;
@@ -4495,7 +4495,7 @@ static int service_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
@@ -4669,5 +4669,5 @@ const UnitVTable service_vtable = {
.finished_job = service_finished_job,
},
.test_start_limit = service_test_start_limit,
.can_start = service_can_start,
};
+3 -3
View File
@@ -3427,7 +3427,7 @@ static int socket_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
static int socket_test_start_limit(Unit *u) {
static int socket_can_start(Unit *u) {
Socket *s = SOCKET(u);
int r;
@@ -3439,7 +3439,7 @@ static int socket_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
@@ -3570,5 +3570,5 @@ const UnitVTable socket_vtable = {
},
},
.test_start_limit = socket_test_start_limit,
.can_start = socket_can_start,
};
+3 -3
View File
@@ -1581,7 +1581,7 @@ static int swap_can_clean(Unit *u, ExecCleanMask *ret) {
return exec_context_get_clean_mask(&s->exec_context, ret);
}
static int swap_test_start_limit(Unit *u) {
static int swap_can_start(Unit *u) {
Swap *s = SWAP(u);
int r;
@@ -1593,7 +1593,7 @@ static int swap_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
@@ -1692,5 +1692,5 @@ const UnitVTable swap_vtable = {
},
},
.test_start_limit = swap_test_start_limit,
.can_start = swap_can_start,
};
+3 -3
View File
@@ -889,7 +889,7 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) {
return 0;
}
static int timer_test_start_limit(Unit *u) {
static int timer_can_start(Unit *u) {
Timer *t = TIMER(u);
int r;
@@ -901,7 +901,7 @@ static int timer_test_start_limit(Unit *u) {
return r;
}
return 0;
return 1;
}
static const char* const timer_base_table[_TIMER_BASE_MAX] = {
@@ -965,5 +965,5 @@ const UnitVTable timer_vtable = {
.bus_set_property = bus_timer_set_property,
.test_start_limit = timer_test_start_limit,
.can_start = timer_can_start,
};
+3 -3
View File
@@ -1904,9 +1904,9 @@ int unit_start(Unit *u) {
return unit_start(following);
}
/* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */
if (UNIT_VTABLE(u)->test_start_limit) {
r = UNIT_VTABLE(u)->test_start_limit(u);
/* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */
if (UNIT_VTABLE(u)->can_start) {
r = UNIT_VTABLE(u)->can_start(u);
if (r < 0)
return r;
}
+1 -1
View File
@@ -665,7 +665,7 @@ typedef struct UnitVTable {
/* If this function is set, it's invoked first as part of starting a unit to allow start rate
* limiting checks to occur before we do anything else. */
int (*test_start_limit)(Unit *u);
int (*can_start)(Unit *u);
/* The strings to print in status messages */
UnitStatusMessageFormats status_message_formats;