summaryrefslogtreecommitdiff
path: root/sbin/devpubd
diff options
context:
space:
mode:
authorjmcneill <jmcneill@NetBSD.org>2015-02-15 15:56:30 +0000
committerjmcneill <jmcneill@NetBSD.org>2015-02-15 15:56:30 +0000
commita8454729e4217bd117aec3b765e4bef4367ec65e (patch)
treec5dd637124c5b75bb59773b7fc438c3cd308d667 /sbin/devpubd
parent5c5470a44938b781fe58c8e2a350bb6d91d61926 (diff)
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 (limited to 'sbin/devpubd')
-rwxr-xr-xsbin/devpubd/devpubd-run-hooks.in7
-rw-r--r--sbin/devpubd/devpubd.c92
-rwxr-xr-xsbin/devpubd/hooks/01-makedev7
-rwxr-xr-xsbin/devpubd/hooks/02-wedgenames35
4 files changed, 100 insertions, 41 deletions
diff --git a/sbin/devpubd/devpubd-run-hooks.in b/sbin/devpubd/devpubd-run-hooks.in
index 195fd16bcf1..cfac7fa5ea4 100755
--- a/sbin/devpubd/devpubd-run-hooks.in
+++ b/sbin/devpubd/devpubd-run-hooks.in
@@ -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 --git a/sbin/devpubd/devpubd.c b/sbin/devpubd/devpubd.c
index ef02f014097..bfeea0a2473 100644
--- a/sbin/devpubd/devpubd.c
+++ b/sbin/devpubd/devpubd.c
@@ -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>
@@ -34,10 +34,11 @@
*/
#include <sys/cdefs.h>
-__COPYRIGHT("@(#) Copyright (c) 2011\
+__COPYRIGHT("@(#) Copyright (c) 2011-2015\
Jared D. McNeill <jmcneill@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/09/16 15:42:56 joerg Exp $");
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 char *event, const char *device)
}
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, const char *device)
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, const char *device)
}
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;
diff --git a/sbin/devpubd/hooks/01-makedev b/sbin/devpubd/hooks/01-makedev
index 14d7719cb71..10f49116a95 100755
--- a/sbin/devpubd/hooks/01-makedev
+++ b/sbin/devpubd/hooks/01-makedev
@@ -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 --git a/sbin/devpubd/hooks/02-wedgenames b/sbin/devpubd/hooks/02-wedgenames
index d30d361bad2..f70f2976a40 100755
--- a/sbin/devpubd/hooks/02-wedgenames
+++ b/sbin/devpubd/hooks/02-wedgenames
@@ -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