Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sbin/devpubd At startup, instead of doing run-hooks for each...



details:   https://anonhg.NetBSD.org/src/rev/14028ccbba9e
branches:  trunk
changeset: 806315:14028ccbba9e
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sun Feb 15 15:56:30 2015 +0000

description:
At startup, instead of doing run-hooks for each device, call run-hooks
once with a list of all found devices. This lets us batch calls to MAKEDEV
which results in a noticeable improvement in Raspberry Pi boot time.

Run the initial device enumeration hooks before detaching from the foreground,
ensuring that any required devices have been created before the rc.d script
exits.

diffstat:

 sbin/devpubd/devpubd-run-hooks.in |   7 +-
 sbin/devpubd/devpubd.c            |  92 ++++++++++++++++++++++++++++++--------
 sbin/devpubd/hooks/01-makedev     |   7 +-
 sbin/devpubd/hooks/02-wedgenames  |  35 ++++++++------
 4 files changed, 100 insertions(+), 41 deletions(-)

diffs (truncated from 313 to 300 lines):

diff -r 6ad76109f4b2 -r 14028ccbba9e sbin/devpubd/devpubd-run-hooks.in
--- a/sbin/devpubd/devpubd-run-hooks.in Sun Feb 15 14:51:57 2015 +0000
+++ b/sbin/devpubd/devpubd-run-hooks.in Sun Feb 15 15:56:30 2015 +0000
@@ -1,18 +1,19 @@
 #!/bin/sh
 #
-# $NetBSD: devpubd-run-hooks.in,v 1.2 2011/12/04 13:01:54 jmcneill Exp $
+# $NetBSD: devpubd-run-hooks.in,v 1.3 2015/02/15 15:56:30 jmcneill Exp $
 #
 # devpubd run hooks
 
 devpubd_event=$1
-devpubd_device=$2
+shift
+devpubd_devices=$@
 devpubd_hooks_base=@HOOKSDIR@
 
 case $devpubd_event in
 device-attach|device-detach)
        for hook in ${devpubd_hooks_base}/*; do
                if [ -x "${hook}" ]; then
-                       "${hook}" ${devpubd_event} ${devpubd_device}
+                       "${hook}" ${devpubd_event} ${devpubd_devices}
                fi
        done
        ;;
diff -r 6ad76109f4b2 -r 14028ccbba9e sbin/devpubd/devpubd.c
--- a/sbin/devpubd/devpubd.c    Sun Feb 15 14:51:57 2015 +0000
+++ b/sbin/devpubd/devpubd.c    Sun Feb 15 15:56:30 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: devpubd.c,v 1.2 2011/09/16 15:42:56 joerg Exp $        */
+/*     $NetBSD: devpubd.c,v 1.3 2015/02/15 15:56:30 jmcneill Exp $     */
 
 /*-
  * Copyright (c) 2011 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -34,10 +34,11 @@
  */
 
 #include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2011\
+__COPYRIGHT("@(#) Copyright (c) 2011-2015\
 Jared D. McNeill <jmcneill%invisible.ca@localhost>. All rights reserved.");
-__RCSID("$NetBSD: devpubd.c,v 1.2 2011/09/16 15:42:56 joerg Exp $");
+__RCSID("$NetBSD: devpubd.c,v 1.3 2015/02/15 15:56:30 jmcneill Exp $");
 
+#include <sys/queue.h>
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/drvctlio.h>
@@ -57,18 +58,24 @@
 static int drvctl_fd = -1;
 static const char devpubd_script[] = DEVPUBD_RUN_HOOKS;
 
+struct devpubd_probe_event {
+       char *device;
+       TAILQ_ENTRY(devpubd_probe_event) entries;
+};
+
+static TAILQ_HEAD(, devpubd_probe_event) devpubd_probe_events;
+
 #define        DEVPUBD_ATTACH_EVENT    "device-attach"
 #define        DEVPUBD_DETACH_EVENT    "device-detach"
 
 __dead static void
-devpubd_exec(const char *path, const char *event, const char *device)
+devpubd_exec(const char *path, char * const *argv)
 {
        int error;
 
-       error = execl(path, path, event, device, NULL);
+       error = execv(path, argv);
        if (error) {
-               syslog(LOG_ERR, "couldn't exec '%s %s %s': %m",
-                   path, event, device);
+               syslog(LOG_ERR, "couldn't exec '%s': %m", path);
                exit(EXIT_FAILURE);
        }
 
@@ -76,12 +83,25 @@
 }
 
 static void
-devpubd_eventhandler(const char *event, const char *device)
+devpubd_eventhandler(const char *event, const char **device)
 {
+       char **argv;
        pid_t pid;
-       int status;
+       int status, i, ndevs;
+
+       for (ndevs = 0, i = 0; device[i] != NULL; i++) {
+               ++ndevs;
+               syslog(LOG_DEBUG, "event = '%s', device = '%s'", event,
+                   device[i]);
+       }
 
-       syslog(LOG_DEBUG, "event = '%s', device = '%s'", event, device);
+       argv = calloc(3 + ndevs, sizeof(char *));
+       argv[0] = __UNCONST(devpubd_script);
+       argv[1] = __UNCONST(event);
+       for (i = 0; i < ndevs; i++) {
+               argv[2 + i] = __UNCONST(device[i]);
+       }
+       argv[2 + i] = NULL;
 
        pid = fork();
        switch (pid) {
@@ -89,7 +109,7 @@
                syslog(LOG_ERR, "fork failed: %m");
                break;
        case 0:
-               devpubd_exec(devpubd_script, event, device);
+               devpubd_exec(devpubd_script, argv);
                /* NOTREACHED */
        default:
                if (waitpid(pid, &status, 0) == -1) {
@@ -105,23 +125,27 @@
                }
                break;
        }
+
+       free(argv);
 }
 
 __dead static void
 devpubd_eventloop(void)
 {
-       const char *event, *device;
+       const char *event, *device[2];
        prop_dictionary_t ev;
        int res;
 
        assert(drvctl_fd != -1);
 
+       device[1] = NULL;
+
        for (;;) {
                res = prop_dictionary_recv_ioctl(drvctl_fd, DRVGETEVENT, &ev);
                if (res)
                        err(EXIT_FAILURE, "DRVGETEVENT failed");
                prop_dictionary_get_cstring_nocopy(ev, "event", &event);
-               prop_dictionary_get_cstring_nocopy(ev, "device", &device);
+               prop_dictionary_get_cstring_nocopy(ev, "device", &device[0]);
 
                printf("%s: event='%s', device='%s'\n", __func__,
                    event, device);
@@ -182,11 +206,14 @@
                goto child_count_changed;
 
        /*
-        * For each child device, first post an attach event and
+        * For each child device, queue an attach event and
         * then scan each one for additional devices.
         */
-       for (n = 0; n < laa.l_children; n++)
-               devpubd_eventhandler(DEVPUBD_ATTACH_EVENT, laa.l_childname[n]);
+       for (n = 0; n < laa.l_children; n++) {
+               struct devpubd_probe_event *ev = calloc(1, sizeof(*ev));
+               ev->device = strdup(laa.l_childname[n]);
+               TAILQ_INSERT_TAIL(&devpubd_probe_events, ev, entries);
+       }
        for (n = 0; n < laa.l_children; n++)
                devpubd_probe(laa.l_childname[n]);
 
@@ -195,6 +222,33 @@
        return;
 }
 
+static void
+devpubd_init(void)
+{
+       struct devpubd_probe_event *ev;
+       const char **devs;
+       int ndevs, i;
+
+       TAILQ_INIT(&devpubd_probe_events);
+       devpubd_probe(NULL);
+       ndevs = 0;
+       TAILQ_FOREACH(ev, &devpubd_probe_events, entries) {
+               ++ndevs;
+       }
+       devs = calloc(ndevs + 1, sizeof(*devs));
+       i = 0;
+       TAILQ_FOREACH(ev, &devpubd_probe_events, entries) {
+               devs[i++] = ev->device;
+       }
+       devpubd_eventhandler(DEVPUBD_ATTACH_EVENT, devs);
+       free(devs);
+       while (ev = TAILQ_FIRST(&devpubd_probe_events)) {
+               TAILQ_REMOVE(&devpubd_probe_events, ev, entries);
+               free(ev->device);
+               free(ev);
+       }
+}
+
 __dead static void
 usage(void)
 {
@@ -232,15 +286,15 @@
        if (drvctl_fd == -1)
                err(EXIT_FAILURE, "couldn't open " DRVCTLDEV);
 
+       /* Look for devices that are already present */
+       devpubd_init();
+
        if (!fflag) {
                if (daemon(0, 0) == -1) {
                        err(EXIT_FAILURE, "couldn't fork");
                }
        }
 
-       /* Look for devices that are already present */
-       devpubd_probe(NULL);
-
        devpubd_eventloop();
 
        return EXIT_SUCCESS;
diff -r 6ad76109f4b2 -r 14028ccbba9e sbin/devpubd/hooks/01-makedev
--- a/sbin/devpubd/hooks/01-makedev     Sun Feb 15 14:51:57 2015 +0000
+++ b/sbin/devpubd/hooks/01-makedev     Sun Feb 15 15:56:30 2015 +0000
@@ -1,15 +1,16 @@
 #!/bin/sh
 #
-# $NetBSD: 01-makedev,v 1.1 2011/08/29 11:38:48 mrg Exp $
+# $NetBSD: 01-makedev,v 1.2 2015/02/15 15:56:30 jmcneill Exp $
 #
 # Try to create a device node if it doesn't exist
 #
 
 event="$1"
-device="$2"
+shift
+devices=$@
 
 case $event in
 device-attach)
-       cd /dev && sh MAKEDEV -u "$device" 2>/dev/null
+       cd /dev && sh MAKEDEV -u $devices 2>/dev/null
        ;;
 esac
diff -r 6ad76109f4b2 -r 14028ccbba9e sbin/devpubd/hooks/02-wedgenames
--- a/sbin/devpubd/hooks/02-wedgenames  Sun Feb 15 14:51:57 2015 +0000
+++ b/sbin/devpubd/hooks/02-wedgenames  Sun Feb 15 15:56:30 2015 +0000
@@ -1,12 +1,13 @@
 #!/bin/sh
 #
-# $NetBSD: 02-wedgenames,v 1.1 2013/01/11 23:49:23 mlelstv Exp $
+# $NetBSD: 02-wedgenames,v 1.2 2015/02/15 15:56:30 jmcneill Exp $
 #
 # Try to maintain symlinks to wedge devices
 #
 
 event="$1"
-device="$2"
+shift
+devices=$@
 
 wedgedir=/dev/wedges
 
@@ -15,7 +16,7 @@
        | sed -e 's# #\\ #g' \
        | while read w; do
                t=$(readlink "$w")
-               if [ x"$t" = x"/dev/$device" ]; then
+               if [ x"$t" = x"/dev/$1" ]; then
                        rm -f "$w"
                        basedir=$(dirname "$w")
                        rmdir -p "$basedir" 2>/dev/null
@@ -24,7 +25,7 @@
 }
 
 add_wedge() {
-       n=$(dkctl "$device" getwedgeinfo \
+       n=$(dkctl "$1" getwedgeinfo \
                | sed -ne '1s#^[^:]*: ##p' \
                | awk -v GOOD='._:;!^$&~()[]{}=,+-/' '
                BEGIN {
@@ -51,21 +52,23 @@
                test -d $wedgedir || mkdir -m 755 $wedgedir
                basedir=$(dirname "$wedgedir/$n")
                test -d "$basedir" || mkdir -p -m 755 "$basedir"
-               ln -s "/dev/$device" "$wedgedir/$n"
+               ln -s "/dev/$1" "$wedgedir/$n"
                ;;
        esac
 }
 
-case $device in
-dk*)
-       case $event in
-       device-attach)
-               remove_wedge
-               add_wedge
-               ;;
-       device-detach)
-               remove_wedge
+for device in $devices; do
+       case $device in
+       dk*)
+               case $event in



Home | Main Index | Thread Index | Old Index