From e3f4759019544673d654ad8a1ea256ed481fa5e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Kl=C3=B6tzke?= Date: Sun, 22 Nov 2020 14:17:56 +0100 Subject: [PATCH] mdev: move daemon setup to dedicated function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jan Klötzke Signed-off-by: Denys Vlasenko --- util-linux/mdev.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/util-linux/mdev.c b/util-linux/mdev.c index 8b06d3456..4c00a2d7e 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c @@ -1165,6 +1165,29 @@ static void initial_scan(char *temp) # define KERN_RCVBUF (128 * 1024 * 1024) # define MAX_ENV 32 +static int daemon_init(char *temp) +{ + int fd; + + /* Subscribe for UEVENT kernel messages */ + /* Without a sufficiently big RCVBUF, a ton of simultaneous events + * can trigger ENOBUFS on read, which is unrecoverable. + * Reproducer: + * mdev -d + * find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' + */ + fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, KERN_RCVBUF); + + /* + * Make inital scan after the uevent socket is alive and + * _before_ we fork away. Already open mdev.log because we work + * in daemon mode. + */ + initial_scan(temp); + + return fd; +} + static void daemon_loop(char *temp, int fd) { for (;;) { @@ -1234,24 +1257,11 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_MDEV_DAEMON if (opt & MDEV_OPT_DAEMON) { /* - * Daemon mode listening on uevent netlink socket. + * Daemon mode listening on uevent netlink socket. Fork away + * after initial scan so that caller can be sure everything + * is up-to-date when mdev process returns. */ - int fd; - - /* Subscribe for UEVENT kernel messages */ - /* Without a sufficiently big RCVBUF, a ton of simultaneous events - * can trigger ENOBUFS on read, which is unrecoverable. - * Reproducer: - * mdev -d - * find /sys -name uevent -exec sh -c 'echo add >"{}"' ';' - */ - fd = create_and_bind_to_netlink(NETLINK_KOBJECT_UEVENT, 1 << 0, KERN_RCVBUF); - - /* - * Make inital scan after the uevent socket is alive and - * _before_ we fork away. - */ - initial_scan(temp); + int fd = daemon_init(temp); if (!(opt & MDEV_OPT_FOREGROUND)) bb_daemonize_or_rexec(0, argv);