summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Strode <rstrode@redhat.com>2022-04-08 11:05:34 -0400
committerRay Strode <rstrode@redhat.com>2022-04-08 11:14:08 -0400
commit836a9135fe2d8fdc7d6de3a6d11fb9a5fd05f926 (patch)
tree24055a81d25db05fb454ea4bf1bade5a930c597a
parentc588aea01bcc20353f8d28a78125e211bdc25097 (diff)
downloadaccountsservice-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.c24
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