Module Name: src Committed By: jmcneill Date: Sun Feb 15 15:56:30 UTC 2015
Modified Files: src/sbin/devpubd: devpubd-run-hooks.in devpubd.c src/sbin/devpubd/hooks: 01-makedev 02-wedgenames Log Message: 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. To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sbin/devpubd/devpubd-run-hooks.in \ src/sbin/devpubd/devpubd.c cvs rdiff -u -r1.1 -r1.2 src/sbin/devpubd/hooks/01-makedev \ src/sbin/devpubd/hooks/02-wedgenames Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/devpubd/devpubd-run-hooks.in diff -u src/sbin/devpubd/devpubd-run-hooks.in:1.2 src/sbin/devpubd/devpubd-run-hooks.in:1.3 --- src/sbin/devpubd/devpubd-run-hooks.in:1.2 Sun Dec 4 13:01:54 2011 +++ src/sbin/devpubd/devpubd-run-hooks.in Sun Feb 15 15:56:30 2015 @@ -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 ;; Index: src/sbin/devpubd/devpubd.c diff -u src/sbin/devpubd/devpubd.c:1.2 src/sbin/devpubd/devpubd.c:1.3 --- src/sbin/devpubd/devpubd.c:1.2 Fri Sep 16 15:42:56 2011 +++ src/sbin/devpubd/devpubd.c Sun Feb 15 15:56:30 2015 @@ -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 <jmcne...@invisible.ca> @@ -34,10 +34,11 @@ */ #include <sys/cdefs.h> -__COPYRIGHT("@(#) Copyright (c) 2011\ +__COPYRIGHT("@(#) Copyright (c) 2011-2015\ Jared D. McNeill <jmcne...@invisible.ca>. 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 @@ __RCSID("$NetBSD: devpubd.c,v 1.2 2011/0 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 @@ devpubd_exec(const char *path, const cha } 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 @@ devpubd_eventhandler(const char *event, 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 @@ devpubd_eventhandler(const char *event, } 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 @@ child_count_changed: 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 @@ done: 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 @@ main(int argc, char *argv[]) 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; Index: src/sbin/devpubd/hooks/01-makedev diff -u src/sbin/devpubd/hooks/01-makedev:1.1 src/sbin/devpubd/hooks/01-makedev:1.2 --- src/sbin/devpubd/hooks/01-makedev:1.1 Mon Aug 29 11:38:48 2011 +++ src/sbin/devpubd/hooks/01-makedev Sun Feb 15 15:56:30 2015 @@ -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 Index: src/sbin/devpubd/hooks/02-wedgenames diff -u src/sbin/devpubd/hooks/02-wedgenames:1.1 src/sbin/devpubd/hooks/02-wedgenames:1.2 --- src/sbin/devpubd/hooks/02-wedgenames:1.1 Fri Jan 11 23:49:23 2013 +++ src/sbin/devpubd/hooks/02-wedgenames Sun Feb 15 15:56:30 2015 @@ -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 @@ remove_wedge() { | 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 @@ remove_wedge() { } add_wedge() { - n=$(dkctl "$device" getwedgeinfo \ + n=$(dkctl "$1" getwedgeinfo \ | sed -ne '1s#^[^:]*: ##p' \ | awk -v GOOD='._:;!^$&~()[]{}=,+-/' ' BEGIN { @@ -51,21 +52,23 @@ add_wedge() { 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 + device-attach) + remove_wedge $device + add_wedge $device + ;; + device-detach) + remove_wedge $device + ;; + esac ;; esac - ;; -esac +done