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

Reply via email to