mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 10:25:06 +03:00
Merge pull request #11212 from keszybz/mount-storm-revert
Revert the patches for mount-storm prevention for now
This commit is contained in:
commit
2141bedb39
@ -227,10 +227,6 @@ struct Manager {
|
||||
/* Data specific to the mount subsystem */
|
||||
struct libmnt_monitor *mount_monitor;
|
||||
sd_event_source *mount_event_source;
|
||||
sd_event_source *mount_timeout_source;
|
||||
usec_t mount_last_read_usec;
|
||||
usec_t mount_last_duration_usec;
|
||||
unsigned mount_pending_count;
|
||||
|
||||
/* Data specific to the swap filesystem */
|
||||
FILE *proc_swaps;
|
||||
|
103
src/core/mount.c
103
src/core/mount.c
@ -55,7 +55,6 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
|
||||
|
||||
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
|
||||
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||
static int mount_dispatch_proc_self_mountinfo_timer(sd_event_source *source, usec_t usec, void *userdata);
|
||||
|
||||
static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
|
||||
return IN_SET(state,
|
||||
@ -218,12 +217,6 @@ static void mount_done(Unit *u) {
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!IN_SET(m->state, MOUNT_DEAD, MOUNT_MOUNTED, MOUNT_FAILED)) {
|
||||
/* This was pending, so need to udpate the count */
|
||||
assert(u->manager->mount_pending_count > 0);
|
||||
u->manager->mount_pending_count--;
|
||||
}
|
||||
|
||||
m->where = mfree(m->where);
|
||||
|
||||
mount_parameters_done(&m->parameters_proc_self_mountinfo);
|
||||
@ -656,7 +649,6 @@ static int mount_load(Unit *u) {
|
||||
|
||||
static void mount_set_state(Mount *m, MountState state) {
|
||||
MountState old_state;
|
||||
int was_pending, is_pending;
|
||||
assert(m);
|
||||
|
||||
if (m->state != state)
|
||||
@ -665,17 +657,6 @@ static void mount_set_state(Mount *m, MountState state) {
|
||||
old_state = m->state;
|
||||
m->state = state;
|
||||
|
||||
was_pending = !IN_SET(old_state, MOUNT_DEAD, MOUNT_MOUNTED, MOUNT_FAILED);
|
||||
is_pending = !IN_SET(state, MOUNT_DEAD, MOUNT_MOUNTED, MOUNT_FAILED);
|
||||
|
||||
if (was_pending && !is_pending) {
|
||||
assert(UNIT(m)->manager->mount_pending_count > 0);
|
||||
UNIT(m)->manager->mount_pending_count--;
|
||||
}
|
||||
|
||||
if (is_pending && !was_pending)
|
||||
UNIT(m)->manager->mount_pending_count++;
|
||||
|
||||
if (!MOUNT_STATE_WITH_PROCESS(state)) {
|
||||
m->timer_event_source = sd_event_source_unref(m->timer_event_source);
|
||||
mount_unwatch_control_pid(m);
|
||||
@ -1684,7 +1665,6 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
||||
static void mount_shutdown(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
m->mount_timeout_source = sd_event_source_unref(m->mount_timeout_source);
|
||||
m->mount_event_source = sd_event_source_unref(m->mount_event_source);
|
||||
|
||||
mnt_unref_monitor(m->mount_monitor);
|
||||
@ -1800,55 +1780,13 @@ fail:
|
||||
mount_shutdown(m);
|
||||
}
|
||||
|
||||
static void mount_process_proc_self_mountinfo(Manager *m);
|
||||
|
||||
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||
_cleanup_set_free_free_ Set *around = NULL, *gone = NULL;
|
||||
Manager *m = userdata;
|
||||
const char *what;
|
||||
Iterator i;
|
||||
Unit *u;
|
||||
int r;
|
||||
usec_t next_read = usec_add(m->mount_last_read_usec,
|
||||
m->mount_last_duration_usec * 10);
|
||||
|
||||
/* If there are pending mounts initiated by systemd, then
|
||||
* we need to process changes promptly, otherwise we
|
||||
* rate limit re-reading the file.
|
||||
*/
|
||||
if (m->mount_pending_count == 0 &&
|
||||
now(CLOCK_MONOTONIC) < next_read) {
|
||||
/* The (current) API for getting mount events from the Linux kernel
|
||||
* involves getting a "something changed" notification, and then having
|
||||
* to re-read the entire /proc/self/mountinfo file. When there are lots
|
||||
* of mountpoints, this file is large and parsing it can take noticeable
|
||||
* time. As most of the file won't have changed, this can be seen as wasted time.
|
||||
* If there is a "mount storm" such as 1000 mount points being created
|
||||
* in quick succession, this will result in 1000 successive notification.
|
||||
* If we respond to every notification, we will do quadratically more work
|
||||
* than if we respond just once after all the notifications have arrived.
|
||||
* In this (pathological) case, a delay in scheduling would actually
|
||||
* improve throughput as we would combine notifications and parse
|
||||
* the file less often. We cannot expect the scheduler to notice
|
||||
* this pathology without help.
|
||||
* So when the rate of notifications means we are spending more than
|
||||
* 10% of real time handling them, we set a timer and stop listening
|
||||
* to notifications for a while.
|
||||
* If/when Linux provides an API which provides only details of what
|
||||
* has changed, this rate-limiting can be removed.
|
||||
*/
|
||||
|
||||
r = sd_event_source_set_enabled(source, SD_EVENT_OFF);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to disable monitoring of /proc/self/mounting, ignoring: %m");
|
||||
if (!m->mount_timeout_source) {
|
||||
r = sd_event_add_time(m->event, &m->mount_timeout_source,
|
||||
CLOCK_MONOTONIC,
|
||||
next_read,
|
||||
0,
|
||||
mount_dispatch_proc_self_mountinfo_timer,
|
||||
m);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to set timeout to reread /proc/self/mounting, ignoring: %m");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(m);
|
||||
assert(revents & EPOLLIN);
|
||||
@ -1876,40 +1814,13 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
|
||||
return 0;
|
||||
}
|
||||
|
||||
mount_process_proc_self_mountinfo(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mount_dispatch_proc_self_mountinfo_timer(sd_event_source *source, usec_t usec, void *userdata) {
|
||||
Manager *m = userdata;
|
||||
int r;
|
||||
|
||||
r = sd_event_source_set_enabled(m->mount_event_source, SD_EVENT_ON);
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to reenable /proc/self/mountinfo monitor, ignoring: %m");
|
||||
m->mount_timeout_source = sd_event_source_unref(source);
|
||||
mount_process_proc_self_mountinfo(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mount_process_proc_self_mountinfo(Manager *m) {
|
||||
_cleanup_set_free_free_ Set *around = NULL, *gone = NULL;
|
||||
const char *what;
|
||||
Iterator i;
|
||||
Unit *u;
|
||||
int r;
|
||||
|
||||
m->mount_last_read_usec = now(CLOCK_MONOTONIC);
|
||||
/* If an error occurs, assume 10ms */
|
||||
m->mount_last_duration_usec = 10 * USEC_PER_MSEC;
|
||||
|
||||
r = mount_load_proc_self_mountinfo(m, true);
|
||||
if (r < 0) {
|
||||
/* Reset flags, just in case, for later calls */
|
||||
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT])
|
||||
MOUNT(u)->proc_flags = 0;
|
||||
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
manager_dispatch_load_queue(m);
|
||||
@ -1997,8 +1908,8 @@ static void mount_process_proc_self_mountinfo(Manager *m) {
|
||||
/* Let the device units know that the device is no longer mounted */
|
||||
device_found_node(m, what, 0, DEVICE_FOUND_MOUNT);
|
||||
}
|
||||
m->mount_last_duration_usec = usec_sub_unsigned(now(CLOCK_MONOTONIC),
|
||||
m->mount_last_read_usec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mount_reset_failed(Unit *u) {
|
||||
|
Loading…
Reference in New Issue
Block a user