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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user