Module Name: src Committed By: mrg Date: Mon Aug 29 11:38:48 UTC 2011
Modified Files: src/distrib/sets/lists/base: mi src/doc: CHANGES src/etc/mtree: NetBSD.dist.base src/sbin: Makefile Added Files: src/sbin/devpubd: Makefile devpubd-run-hooks.in devpubd.c src/sbin/devpubd/hooks: 01-makedev Log Message: add the device publish daemon, written by jmcneill@. listens on drvctl for new devices and invokes MAKEDEV for them. missing: - manual page - rc.d script - more testing but it works well enough to make new disk nodes appear in /dev when netbsd sees them and they're missing. you will need to make sure you have a new /dev/MAKEDEV for this to work properly (postinstall should handle this normally, of course.) thanks jared! To generate a diff of this commit: cvs rdiff -u -r1.950 -r1.951 src/distrib/sets/lists/base/mi cvs rdiff -u -r1.1597 -r1.1598 src/doc/CHANGES cvs rdiff -u -r1.90 -r1.91 src/etc/mtree/NetBSD.dist.base cvs rdiff -u -r1.120 -r1.121 src/sbin/Makefile cvs rdiff -u -r0 -r1.1 src/sbin/devpubd/Makefile \ src/sbin/devpubd/devpubd-run-hooks.in src/sbin/devpubd/devpubd.c cvs rdiff -u -r0 -r1.1 src/sbin/devpubd/hooks/01-makedev Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/base/mi diff -u src/distrib/sets/lists/base/mi:1.950 src/distrib/sets/lists/base/mi:1.951 --- src/distrib/sets/lists/base/mi:1.950 Sat Aug 27 18:35:19 2011 +++ src/distrib/sets/lists/base/mi Mon Aug 29 11:38:48 2011 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.950 2011/08/27 18:35:19 joerg Exp $ +# $NetBSD: mi,v 1.951 2011/08/29 11:38:48 mrg Exp $ # # Note: Don't delete entries from here - mark them as "obsolete" instead, # unless otherwise stated below. @@ -183,18 +183,21 @@ ./libdata/firmware/rum/rum-rt2573 base-firmware-root ./libdata/firmware/upgt base-firmware-root ./libdata/firmware/zyd base-firmware-root -./libdata/firmware/zyd/zd1211-licence base-obsolete obsolete +./libdata/firmware/zyd/zd1211-licence base-obsolete obsolete ./libdata/firmware/zyd/zd1211-license base-firmware-root ./libdata/firmware/zyd/zyd-zd1211 base-firmware-root ./libdata/firmware/zyd/zyd-zd1211b base-firmware-root ./libexec base-sys-root +./libexec/devpubd-hooks base-sysutil-root +./libexec/devpubd-hooks/01-makedev base-sysutil-root +./libexec/devpubd-run-hooks base-sysutil-root ./libexec/dhcpcd-hooks base-dhcpcd-root ./libexec/dhcpcd-hooks/01-test base-dhcpcd-root ./libexec/dhcpcd-hooks/02-dump base-dhcpcd-root ./libexec/dhcpcd-hooks/10-mtu base-dhcpcd-root -./libexec/dhcpcd-hooks/10-resolv.conf base-obsolete obsolete -./libexec/dhcpcd-hooks/14-lookup-hostname base-obsolete obsolete -./libexec/dhcpcd-hooks/15-hostname base-obsolete obsolete +./libexec/dhcpcd-hooks/10-resolv.conf base-obsolete obsolete +./libexec/dhcpcd-hooks/14-lookup-hostname base-obsolete obsolete +./libexec/dhcpcd-hooks/15-hostname base-obsolete obsolete ./libexec/dhcpcd-hooks/20-resolv.conf base-dhcpcd-root ./libexec/dhcpcd-hooks/29-lookup-hostname base-dhcpcd-root ./libexec/dhcpcd-hooks/30-hostname base-dhcpcd-root @@ -221,6 +224,7 @@ ./sbin/chown base-sysutil-root ./sbin/rump.cgdconfig base-sysutil-root crypto ./sbin/clri base-sysutil-root +./sbin/devpubd base-sysutil-root ./sbin/dhclient base-dhclient-root ./sbin/dhclient-script base-dhclient-root ./sbin/dhcpcd base-dhcpcd-root Index: src/doc/CHANGES diff -u src/doc/CHANGES:1.1597 src/doc/CHANGES:1.1598 --- src/doc/CHANGES:1.1597 Wed Aug 17 18:54:08 2011 +++ src/doc/CHANGES Mon Aug 29 11:38:48 2011 @@ -1,4 +1,4 @@ -# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1597 $> +# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.1598 $> # # # [Note: This file does not mention every change made to the NetBSD source tree. @@ -1107,3 +1107,5 @@ mips: add support for MIPS DSP v2 ASE. [matt 20110815] sparc: Switch to GCC 4.5.3 [mrg 20110817] tmux(1): Import of tmux 1.5. [jmmv 20110817] + devpubd(8): Add a device publishing daemon, written by Jared D. + McNeill. [mrg 20110827] Index: src/etc/mtree/NetBSD.dist.base diff -u src/etc/mtree/NetBSD.dist.base:1.90 src/etc/mtree/NetBSD.dist.base:1.91 --- src/etc/mtree/NetBSD.dist.base:1.90 Fri Aug 26 21:22:10 2011 +++ src/etc/mtree/NetBSD.dist.base Mon Aug 29 11:38:48 2011 @@ -1,4 +1,4 @@ -# $NetBSD: NetBSD.dist.base,v 1.90 2011/08/26 21:22:10 dyoung Exp $ +# $NetBSD: NetBSD.dist.base,v 1.91 2011/08/29 11:38:48 mrg Exp $ # @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93 # Do not customize this file as it may be overwritten on upgrades. @@ -74,6 +74,7 @@ ./libdata/firmware/zyd ./libexec ./libexec/dhcpcd-hooks +./libexec/devpubd-hooks ./libexec/resolvconf ./mnt ./rescue Index: src/sbin/Makefile diff -u src/sbin/Makefile:1.120 src/sbin/Makefile:1.121 --- src/sbin/Makefile:1.120 Mon Jun 27 11:52:23 2011 +++ src/sbin/Makefile Mon Aug 29 11:38:48 2011 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.120 2011/06/27 11:52:23 uch Exp $ +# $NetBSD: Makefile,v 1.121 2011/08/29 11:38:48 mrg Exp $ # @(#)Makefile 8.5 (Berkeley) 3/31/94 # Not ported: XNSrouted enpload scsiformat startslip @@ -7,7 +7,7 @@ .include <bsd.own.mk> SUBDIR= amrctl apmlabel atactl badsect bioctl brconfig ccdconfig \ - chown disklabel dkctl dkscan_bsdlabel dmesg dmctl \ + chown devpubd disklabel dkctl dkscan_bsdlabel dmesg dmctl \ drvctl fastboot fdisk fsck fsirand gpt ifconfig init ldconfig \ mbrlabel mknod modload modstat modunload mount newbtconf nologin \ pdisk ping pppoectl raidctl reboot rcorder rndctl route routed \ Added files: Index: src/sbin/devpubd/Makefile diff -u /dev/null src/sbin/devpubd/Makefile:1.1 --- /dev/null Mon Aug 29 11:38:49 2011 +++ src/sbin/devpubd/Makefile Mon Aug 29 11:38:48 2011 @@ -0,0 +1,33 @@ +# $NetBSD: Makefile,v 1.1 2011/08/29 11:38:48 mrg Exp $ + +PROG= devpubd +SRCS= devpubd.c +NOMAN= # defined +WARNS= 4 + +BINDIR?= /sbin + +CPPFLAGS+= -DDEVPUBD_RUN_HOOKS=\"/libexec/devpubd-run-hooks\" + +SCRIPTS= devpubd-run-hooks +SCRIPTSDIR_devpubd-run-hooks= /libexec + +.PATH: ${.CURDIR}/hooks +HOOKS= 01-makedev +SCRIPTS+= ${HOOKS:C,^,hooks/,} +.for f in ${HOOKS} +SCRIPTSDIR_hooks/${f}= /libexec/devpubd-hooks +.endfor + +LDADD+= -lprop +DPADD+= ${LIBPROP} + +CLEANFILES= devpubd-run-hooks + +.for f in devpubd-run-hooks +${f}: ${f}.in + ${TOOL_SED} -e 's,@HOOKSDIR@,/libexec/devpubd-hooks,g' \ + ${.CURDIR}/${f}.in > $@ +.endfor + +.include <bsd.prog.mk> Index: src/sbin/devpubd/devpubd-run-hooks.in diff -u /dev/null src/sbin/devpubd/devpubd-run-hooks.in:1.1 --- /dev/null Mon Aug 29 11:38:49 2011 +++ src/sbin/devpubd/devpubd-run-hooks.in Mon Aug 29 11:38:48 2011 @@ -0,0 +1,21 @@ +#!/bin/sh +# +# $NetBSD: devpubd-run-hooks.in,v 1.1 2011/08/29 11:38:48 mrg Exp $ +# +# devpubd run hooks + +devpubd_event=$1 +devpubd_device=$2 +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} + fi + done + ;; +*) + ;; +esac Index: src/sbin/devpubd/devpubd.c diff -u /dev/null src/sbin/devpubd/devpubd.c:1.1 --- /dev/null Mon Aug 29 11:38:49 2011 +++ src/sbin/devpubd/devpubd.c Mon Aug 29 11:38:48 2011 @@ -0,0 +1,247 @@ +/* $NetBSD: devpubd.c,v 1.1 2011/08/29 11:38:48 mrg Exp $ */ + +/*- + * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__COPYRIGHT("@(#) Copyright (c) 2011\ +Jared D. McNeill <jmcne...@invisible.ca>. All rights reserved."); +__RCSID("$NetBSD: devpubd.c,v 1.1 2011/08/29 11:38:48 mrg Exp $"); + +#include <sys/types.h> +#include <sys/ioctl.h> +#include <sys/drvctlio.h> +#include <sys/wait.h> +#include <sys/poll.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +static int drvctl_fd = -1; +static const char *devpubd_script = DEVPUBD_RUN_HOOKS; + +#define DEVPUBD_ATTACH_EVENT "device-attach" +#define DEVPUBD_DETACH_EVENT "device-detach" + +static void +devpubd_exec(const char *path, const char *event, const char *device) +{ + int error; + + error = execl(path, path, event, device, NULL); + if (error) { + syslog(LOG_ERR, "couldn't exec '%s %s %s': %m", + path, event, device); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} + +static void +devpubd_eventhandler(const char *event, const char *device) +{ + pid_t pid; + int status; + + syslog(LOG_DEBUG, "event = '%s', device = '%s'", event, device); + + pid = fork(); + switch (pid) { + case -1: + syslog(LOG_ERR, "fork failed: %m"); + break; + case 0: + devpubd_exec(devpubd_script, event, device); + /* NOTREACHED */ + default: + if (waitpid(pid, &status, 0) == -1) { + syslog(LOG_ERR, "waitpid(%d) failed: %m", pid); + break; + } + if (WIFEXITED(status) && WEXITSTATUS(status)) { + syslog(LOG_WARNING, "%s exited with status %d", + devpubd_script, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + syslog(LOG_WARNING, "%s received signal %d", + devpubd_script, WTERMSIG(status)); + } + break; + } +} + +static void +devpubd_eventloop(void) +{ + const char *event, *device; + prop_dictionary_t ev; + int res; + + assert(drvctl_fd != -1); + + 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); + + printf("%s: event='%s', device='%s'\n", __func__, + event, device); + + devpubd_eventhandler(event, device); + + prop_object_release(ev); + } +} + +static void +devpubd_probe(const char *device) +{ + struct devlistargs laa; + size_t len, children, n; + void *p; + int error; + + assert(drvctl_fd != -1); + + memset(&laa, 0, sizeof(laa)); + if (device) + strlcpy(laa.l_devname, device, sizeof(laa.l_devname)); + + /* Get the child device count for this device */ + error = ioctl(drvctl_fd, DRVLISTDEV, &laa); + if (error) { + syslog(LOG_ERR, "DRVLISTDEV failed: %m"); + return; + } + +child_count_changed: + /* If this device has no children, return */ + if (laa.l_children == 0) + return; + + /* Allocate a buffer large enough to hold the child device names */ + p = laa.l_childname; + children = laa.l_children; + + len = children * sizeof(laa.l_childname[0]); + laa.l_childname = realloc(laa.l_childname, len); + if (laa.l_childname == NULL) { + syslog(LOG_ERR, "couldn't allocate %zu bytes", len); + laa.l_childname = p; + goto done; + } + + /* Get a list of child devices */ + error = ioctl(drvctl_fd, DRVLISTDEV, &laa); + if (error) { + syslog(LOG_ERR, "DRVLISTDEV failed: %m"); + goto done; + } + + /* If the child count changed between DRVLISTDEV calls, retry */ + if (children != laa.l_children) + goto child_count_changed; + + /* + * For each child device, first post 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++) + devpubd_probe(laa.l_childname[n]); + +done: + free(laa.l_childname); + return; +} + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-f]\n", getprogname()); + exit(EXIT_FAILURE); +} + +int +main(int argc, char *argv[]) +{ + bool fflag = false; + int ch; + + setprogname(argv[0]); + + while ((ch = getopt(argc, argv, "fh")) != -1) { + switch (ch) { + case 'f': + fflag = true; + break; + case 'h': + default: + usage(); + /* NOTREACHED */ + } + } + argc -= optind; + argv += optind; + + if (argc) + usage(); + /* NOTREACHED */ + + drvctl_fd = open(DRVCTLDEV, O_RDWR); + if (drvctl_fd == -1) + err(EXIT_FAILURE, "couldn't open " DRVCTLDEV); + + 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 /dev/null src/sbin/devpubd/hooks/01-makedev:1.1 --- /dev/null Mon Aug 29 11:38:49 2011 +++ src/sbin/devpubd/hooks/01-makedev Mon Aug 29 11:38:48 2011 @@ -0,0 +1,15 @@ +#!/bin/sh +# +# $NetBSD: 01-makedev,v 1.1 2011/08/29 11:38:48 mrg Exp $ +# +# Try to create a device node if it doesn't exist +# + +event="$1" +device="$2" + +case $event in +device-attach) + cd /dev && sh MAKEDEV -u "$device" 2>/dev/null + ;; +esac