summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Yurchenko <grange@cvs.openbsd.org>2004-05-30 08:28:29 +0000
committerAlexander Yurchenko <grange@cvs.openbsd.org>2004-05-30 08:28:29 +0000
commit0cfc09514721fd5490d1b579e2233213321491cb (patch)
tree44be8fde070b50437ad2d3eb81067c2518285981
parent148660ad683d28da2bdb330138d50e5363c3bedb (diff)
hotplugd -- devices hot plugging monitor daemon.
The hotplugd daemon monitors the hotplug(4) pseudo-device, acting on signaled events by executing the scripts in the /etc/hotplug directory. Not linked to the build yet.
-rw-r--r--usr.sbin/hotplugd/Makefile12
-rw-r--r--usr.sbin/hotplugd/hotplugd.8126
-rw-r--r--usr.sbin/hotplugd/hotplugd.c163
3 files changed, 301 insertions, 0 deletions
diff --git a/usr.sbin/hotplugd/Makefile b/usr.sbin/hotplugd/Makefile
new file mode 100644
index 00000000000..ae891b74bdf
--- /dev/null
+++ b/usr.sbin/hotplugd/Makefile
@@ -0,0 +1,12 @@
+# $OpenBSD: Makefile,v 1.1 2004/05/30 08:28:28 grange Exp $
+
+PROG= hotplugd
+SRCS= hotplugd.c
+MAN= hotplugd.8
+
+CFLAGS+= -Wall
+CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
+CLFAGS+= -Wmissing-declarations -Wredundant-decls
+CFLAGS+= -Wshadow -Wpointer-arith -Wcast-qual
+
+.include <bsd.prog.mk>
diff --git a/usr.sbin/hotplugd/hotplugd.8 b/usr.sbin/hotplugd/hotplugd.8
new file mode 100644
index 00000000000..fd400566bdc
--- /dev/null
+++ b/usr.sbin/hotplugd/hotplugd.8
@@ -0,0 +1,126 @@
+.\" $OpenBSD: hotplugd.8,v 1.1 2004/05/30 08:28:28 grange Exp $
+.\"
+.\" Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd March 30, 2004
+.Dt HOTPLUGD 8
+.Os
+.Sh NAME
+.Nm hotplugd
+.Nd devices hot plugging monitor daemon
+.Sh SYNOPSIS
+.Nm hotplugd
+.Op Fl d Ar device
+.Sh DESCRIPTION
+The
+.Nm
+daemon monitors the
+.Xr hotplug 4
+pseudo-device, acting on signaled events by executing the scripts in the
+.Pa /etc/hotplug
+directory.
+By default it uses the
+.Pa /dev/hotplug
+device for reading events from, but an alternative device can be
+specified with the
+.Fl d
+option.
+Actions can be configured either for device attachment or detachment.
+On device attachment the
+.Pa attach
+script is executed if it exists.
+On device detachment the
+.Pa detach
+script is executed if it exists.
+In both cases two parameters are passed to the scripts: the class and name
+of the attached or detached device.
+Device class corresponds to the classes described in the
+.Aq Pa sys/device.h
+header file and can be one of the following:
+.Bl -tag -width Ds
+.It 0
+generic, no special info
+.It 1
+CPU (carries resource utilization)
+.It 2
+disk drive
+.It 3
+network interface
+.It 4
+tape device
+.It 5
+serial line interface
+.El
+.Pp
+Not all classes can be really usable, e.g. it's unlikely to have
+a hot plug CPU.
+.Pp
+Device name is a usual name including unit number, e.g.\&
+.Pa sd1 .
+.Sh FILES
+.Bl -tag -width "/dev/hotplug/attach" -compact
+.It /dev/hotplug
+Pseudo-device file.
+.It /etc/hotplug
+Directory where the scripts to execute are located.
+.It /etc/hotplug/attach
+Script to execute on device attachment.
+.It /etc/hotplug/detach
+Script to execute on device detachment.
+.El
+.Sh EXAMPLES
+Sample
+.Pa attach
+script:
+.Bd -literal -offset indent
+#!/bin/sh
+
+DEVCLASS=$1
+DEVNAME=$2
+
+case $DEVCLASS in
+2)
+ # disk devices
+
+ disklabel=`/sbin/disklabel $DEVNAME | grep '^label:' | \e
+ sed -e 's/^label: //'`
+ case $disklabel in
+ Sony*DSC*)
+ # Sony DSC camera
+ mount /dev/"$DEVNAME"i /mnt/camera
+ ;;
+ esac
+
+ ;;
+3)
+ # network devices
+
+ /sbin/dhclient $DEVNAME
+
+ ;;
+esac
+.Ed
+.Sh SEE ALSO
+.Xr hotplug 4
+.Sh HISTORY
+The
+.Nm
+program first appeared in
+.Ox 3.6 .
+.Sh AUTHORS
+The
+.Nm
+program was written by
+.An Alexander Yurchenko Aq grange@openbsd.org .
diff --git a/usr.sbin/hotplugd/hotplugd.c b/usr.sbin/hotplugd/hotplugd.c
new file mode 100644
index 00000000000..2f18d7b9159
--- /dev/null
+++ b/usr.sbin/hotplugd/hotplugd.c
@@ -0,0 +1,163 @@
+/* $OpenBSD: hotplugd.c,v 1.1 2004/05/30 08:28:28 grange Exp $ */
+/*
+ * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Devices hot plugging daemon.
+ */
+
+#include <sys/types.h>
+#include <sys/device.h>
+#include <sys/hotplug.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#define _PATH_DEV_HOTPLUG "/dev/hotplug"
+#define _PATH_ETC_HOTPLUG "/etc/hotplug"
+#define _PATH_ETC_HOTPLUG_ATTACH _PATH_ETC_HOTPLUG "/attach"
+#define _PATH_ETC_HOTPLUG_DETACH _PATH_ETC_HOTPLUG "/detach"
+
+volatile sig_atomic_t quit = 0;
+char *device = _PATH_DEV_HOTPLUG;
+int devfd = -1;
+
+void exec_script(const char *, int, char *);
+
+void sigquit(int);
+__dead void usage(void);
+
+int
+main(int argc, char *argv[])
+{
+ int ch;
+ struct sigaction sact;
+ struct hotplug_event he;
+
+ while ((ch = getopt(argc, argv, "d:")) != -1)
+ switch (ch) {
+ case 'd':
+ device = optarg;
+ break;
+ case '?':
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ if ((devfd = open(device, O_RDONLY)) == -1)
+ err(1, "%s", device);
+
+ bzero(&sact, sizeof(sact));
+ sigemptyset(&sact.sa_mask);
+ sact.sa_flags = 0;
+ sact.sa_handler = sigquit;
+ sigaction(SIGINT, &sact, NULL);
+ sigaction(SIGQUIT, &sact, NULL);
+ sigaction(SIGTERM, &sact, NULL);
+ sact.sa_handler = SIG_IGN;
+ sigaction(SIGHUP, &sact, NULL);
+
+ openlog("hotplugd", LOG_NDELAY | LOG_PID, LOG_DAEMON);
+ if (daemon(0, 0) == -1)
+ err(1, "daemon");
+
+ syslog(LOG_INFO, "started");
+
+ while (!quit) {
+ if (read(devfd, &he, sizeof(he)) == -1) {
+ if (errno == EINTR)
+ /* ignore */
+ continue;
+ syslog(LOG_ERR, "read: %m");
+ exit(1);
+ }
+
+ switch (he.he_type) {
+ case HOTPLUG_DEVAT:
+ syslog(LOG_INFO, "%s attached, class %d",
+ he.he_devname, he.he_devclass);
+ exec_script(_PATH_ETC_HOTPLUG_ATTACH, he.he_devclass,
+ he.he_devname);
+ break;
+ case HOTPLUG_DEVDT:
+ syslog(LOG_INFO, "%s detached, class %d",
+ he.he_devname, he.he_devclass);
+ exec_script(_PATH_ETC_HOTPLUG_DETACH, he.he_devclass,
+ he.he_devname);
+ break;
+ default:
+ syslog(LOG_NOTICE, "unknown event (0x%x)", he.he_type);
+ }
+ }
+
+ syslog(LOG_INFO, "terminated");
+
+ closelog();
+ close(devfd);
+
+ return (0);
+}
+
+void
+exec_script(const char *file, int class, char *name)
+{
+ char strclass[8];
+ pid_t pid;
+
+ snprintf(strclass, sizeof(strclass), "%d", class);
+
+ if (access(file, X_OK | R_OK))
+ /* do nothing if file can't be accessed */
+ return;
+
+ if ((pid = fork()) == -1) {
+ syslog(LOG_ERR, "fork: %m");
+ return;
+ }
+ if (pid == 0) {
+ /* child process */
+ execl(file, basename(file), strclass, name, (char *)NULL);
+ syslog(LOG_ERR, "execl: %m");
+ _exit(1);
+ /* NOTREACHED */
+ }
+}
+
+void
+sigquit(int signum)
+{
+ quit = 1;
+}
+
+__dead void
+usage(void)
+{
+ extern char *__progname;
+
+ fprintf(stderr, "usage: %s [-d device]\n", __progname);
+ exit(1);
+}