diff options
author | Ray Strode <rstrode@redhat.com> | 2022-04-08 11:05:34 -0400 |
---|---|---|
committer | Ray Strode <rstrode@redhat.com> | 2022-04-08 11:14:08 -0400 |
commit | 836a9135fe2d8fdc7d6de3a6d11fb9a5fd05f926 (patch) | |
tree | 24055a81d25db05fb454ea4bf1bade5a930c597a | |
parent | c588aea01bcc20353f8d28a78125e211bdc25097 (diff) | |
download | accountsservice-836a9135fe2d8fdc7d6de3a6d11fb9a5fd05f926.tar.gz |
daemon: Reload users less aggressively on wtmp changes
accountsservice parses wtmp anytime it changes, so that it has
an accurate accounting of user login frequency. This is important
so that, e.g., the login screen can show the list of users in
the order they use the system the most.
The wtmp file can get very big though and take a long time to parse.
Furthermore, in one scenario where it gets big, a user constantly
logging in and out of the system, it also get written to frequently.
In that case accountsservice basically constantly reparses the big
file, chewing through CPU.
This commit attempts to mitigate that scenario, by more aggressively
rate limiting how often it reparses the file.
Previously it would only parse the file 2 times a seconds at most.
Now it only parses the file once every 10 seconds at most.
Closes: https://gitlab.freedesktop.org/accountsservice/accountsservice/-/issues/104
-rw-r--r-- | src/daemon.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/src/daemon.c b/src/daemon.c index c8b6320..ec2bf5c 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -615,6 +615,22 @@ reload_autologin_timeout (Daemon *daemon) } static void +queue_reload_users_eventually (Daemon *daemon) +{ + DaemonPrivate *priv = daemon_get_instance_private (daemon); + + if (priv->reload_id > 0) { + return; + } + + /* we wait 10 seconds before reloading the users, so e.g. wtmp + * parsing doesn't hammer the cpu if the user is logging in + * and out in a continuous loop. + */ + priv->reload_id = g_timeout_add_seconds (10, (GSourceFunc)reload_users_timeout, daemon); +} + +static void queue_reload_users_soon (Daemon *daemon) { DaemonPrivate *priv = daemon_get_instance_private (daemon); @@ -660,12 +676,18 @@ on_users_monitor_changed (GFileMonitor *monitor, GFileMonitorEvent event_type, Daemon *daemon) { + DaemonPrivate *priv = daemon_get_instance_private (daemon); + if (event_type != G_FILE_MONITOR_EVENT_CHANGED && event_type != G_FILE_MONITOR_EVENT_CREATED) { return; } - queue_reload_users_soon (daemon); + if (monitor == priv->wtmp_monitor) { + queue_reload_users_eventually (daemon); + } else { + queue_reload_users_soon (daemon); + } } static void |