summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkay.sievers@vrfy.org <kay.sievers@vrfy.org>2004-11-23 07:34:56 +0100
committerGreg KH <gregkh@suse.de>2005-04-26 22:37:37 -0700
commitc449b25e3f998efe8f5988632126fb468ee55fc5 (patch)
tree2a9bedda0934f662dcfa0e1ceb68e25e9a4bb7e0
parentcc0e9bfc350e6a8b3fff79a9a0f2a97afa9b3825 (diff)
[PATCH] integrate wait_for_sysfs in udev
Move the wait_for_sysfs logic into the udev binary. udev is called for every hotplug event. It also waits for /devices events.
-rw-r--r--Makefile14
-rw-r--r--udev.c186
-rw-r--r--wait_for_sysfs.c165
3 files changed, 97 insertions, 268 deletions
diff --git a/Makefile b/Makefile
index de08f7cf52..c89fa0feee 100644
--- a/Makefile
+++ b/Makefile
@@ -34,7 +34,6 @@ SENDER = udevsend
INFO = udevinfo
TESTER = udevtest
STARTER = udevstart
-WAIT = wait_for_sysfs
VERSION = 046
INSTALL_DIR = /usr/local/bin
RELEASE_NAME = $(ROOT)-$(VERSION)
@@ -178,7 +177,7 @@ CFLAGS += -I$(PWD)/libsysfs/sysfs \
# config files automatically generated
GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf
-all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS)
+all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS)
@extras="$(EXTRAS)" ; for target in $$extras ; do \
echo $$target ; \
$(MAKE) prefix=$(prefix) \
@@ -282,7 +281,6 @@ $(INFO).o: $(GEN_HEADERS) $(HOST_PROGS)
$(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS)
$(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS)
$(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS)
-$(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS)
$(ROOT): $(LIBC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES)
$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS)
@@ -304,10 +302,6 @@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h
$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS)
$(QUIET) $(STRIPCMD) $@
-$(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC)
- $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o udev_sysfs.o udev_lib.o udev_config.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS)
- $(QUIET) $(STRIPCMD) $@
-
#.c.o:
# $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) -c -o $@ $<
.c.o:
@@ -317,7 +311,7 @@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC)
clean:
-find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \
| xargs rm -f
- -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(WAIT)
+ -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER)
-rm -f ccdv
$(MAKE) -C klibc clean
@extras="$(EXTRAS)" ; for target in $$extras ; do \
@@ -417,10 +411,8 @@ install: install-initscript install-config install-man install-dev.d all
$(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER)
$(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO)
$(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER)
- $(INSTALL_PROGRAM) -D $(WAIT) $(DESTDIR)$(sbindir)/$(WAIT)
- ln -f -s $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER)
- ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug
- - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/05-wait_for_sysfs.hotplug
ifndef DESTDIR
- killall $(DAEMON)
- rm -rf $(udevdb)
@@ -433,7 +425,6 @@ endif
uninstall: uninstall-man uninstall-dev.d
- rm $(hotplugdir)/10-udev.hotplug
- - rm $(hotplugdir)/05-wait_for_sysfs.hotplug
- rm $(configdir)/rules.d/50-udev.rules
- rm $(configdir)/permissions.d/50-udev.permissions
- rm $(configdir)/udev.conf
@@ -447,7 +438,6 @@ uninstall: uninstall-man uninstall-dev.d
- rm $(sbindir)/$(STARTER)
- rm $(usrbindir)/$(INFO)
- rm $(usrbindir)/$(TESTER)
- - rm $(usrbindir)/$(WAIT)
- rmdir $(hotplugdir)
- rm -rf $(udevdb)
- rmdir $(udevdir)
diff --git a/udev.c b/udev.c
index 605a55bf19..8e6d06f1bd 100644
--- a/udev.c
+++ b/udev.c
@@ -4,6 +4,7 @@
* Userspace devfs
*
* Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -24,6 +25,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
@@ -68,70 +70,19 @@ int main(int argc, char *argv[], char *envp[])
{
struct sigaction act;
struct sysfs_class_device *class_dev;
+ struct sysfs_device *devices_dev;
struct udevice udev;
char path[SYSFS_PATH_MAX];
int retval = -EINVAL;
- enum {
- ADD,
- REMOVE,
- UDEVSTART,
- } act_type;
+ const char *error;
+ const char *action = getenv("ACTION");
+ const char *devpath = getenv("DEVPATH");
+ const char *subsystem = argv[1];
dbg("version %s", UDEV_VERSION);
logging_init("udev");
udev_init_config();
- /* export logging flag, callouts may want to do the same as udev */
- if (udev_log)
- setenv("UDEV_LOG", "1", 1);
-
- if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) {
- act_type = UDEVSTART;
- } else {
- const char *action = getenv("ACTION");
- const char *devpath = getenv("DEVPATH");
- const char *subsystem = argv[1];
-
- if (!action) {
- dbg("no action?");
- goto exit;
- }
- if (strcmp(action, "add") == 0) {
- act_type = ADD;
- } else if (strcmp(action, "remove") == 0) {
- act_type = REMOVE;
- } else {
- dbg("no action '%s' for us", action);
- goto exit;
- }
-
- if (!devpath) {
- dbg("no devpath?");
- goto exit;
- }
- dbg("looking at '%s'", devpath);
-
- /* we only care about class devices and block stuff */
- if (!strstr(devpath, "class") && !strstr(devpath, "block")) {
- dbg("not a block or class device");
- goto exit;
- }
-
- if (!subsystem) {
- dbg("no subsystem");
- goto exit;
- }
-
- udev_set_values(&udev, devpath, subsystem, action);
-
- /* skip blacklisted subsystems */
- if (udev.type != 'n' && subsystem_expect_no_dev(subsystem)) {
- dbg("don't care about '%s' devices", subsystem);
- goto exit;
- };
-
- }
-
/* set signal handlers */
act.sa_handler = (void (*) (int))sig_handler;
sigemptyset (&act.sa_mask);
@@ -141,57 +92,110 @@ int main(int argc, char *argv[], char *envp[])
sigaction(SIGINT, &act, NULL);
sigaction(SIGTERM, &act, NULL);
- /* trigger timout to interrupt blocking syscalls */
+ /* trigger timeout to interrupt blocking syscalls */
alarm(ALARM_TIMEOUT);
- switch(act_type) {
- case UDEVSTART:
+ udev_set_values(&udev, devpath, subsystem, action);
+
+ if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) {
dbg("udevstart");
- /* disable all logging as it's much too slow on some facilities */
+ /* disable all logging, as it's much too slow on some facilities */
udev_log = 0;
- unsetenv("UDEV_LOG");
namedev_init();
retval = udev_start();
- break;
- case ADD:
- dbg("udev add");
-
- /* open the device */
- snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath);
- class_dev = sysfs_open_class_device_path(path);
- if (class_dev == NULL) {
- dbg ("sysfs_open_class_device_path failed");
- goto exit;
- }
- dbg("opened class_dev->name='%s'", class_dev->name);
+ goto exit;
+ }
- /* init rules */
- namedev_init();
+ if (!action) {
+ dbg("no action");
+ goto exit;
+ }
+
+ if (!subsystem) {
+ dbg("no subsystem");
+ goto exit;
+ }
+
+ if (!devpath) {
+ dbg("no devpath");
+ goto exit;
+ }
- /* name, create node, store in db */
- retval = udev_add_device(&udev, class_dev);
+ /* export logging flag, called scripts may want to do the same as udev */
+ if (udev_log)
+ setenv("UDEV_LOG", "1", 1);
+
+ if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) {
+ if (strcmp(action, "add") == 0) {
+ /* wait for sysfs and possibly add node */
+ dbg("udev add");
+
+ /* skip blacklisted subsystems */
+ if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) {
+ dbg("don't care about '%s' devices", udev.subsystem);
+ goto exit;
+ };
+
+ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath);
+ class_dev = wait_class_device_open(path);
+ if (class_dev == NULL) {
+ dbg ("open class device failed");
+ goto exit;
+ }
+ dbg("opened class_dev->name='%s'", class_dev->name);
+
+ wait_for_class_device(class_dev, &error);
+
+ /* init rules, permissions */
+ namedev_init();
+
+ /* name, create node, store in db */
+ retval = udev_add_device(&udev, class_dev);
+
+ /* run dev.d/ scripts if we created a node or changed a netif name */
+ if (udev.devname[0] != '\0') {
+ setenv("DEVNAME", udev.devname, 1);
+ dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX);
+ }
+
+ sysfs_close_class_device(class_dev);
+ } else if (strcmp(action, "remove") == 0) {
+ /* possibly remove a node */
+ dbg("udev remove");
+
+ /* get node from db, delete it */
+ retval = udev_remove_device(&udev);
+
+ /* run dev.d/ scripts if we're not instructed to ignore the event */
+ if (udev.devname[0] != '\0') {
+ setenv("DEVNAME", udev.devname, 1);
+ dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX);
+ }
- /* run dev.d/ scripts if we created a node or changed a netif name */
- if (udev.devname[0] != '\0') {
- setenv("DEVNAME", udev.devname, 1);
- dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX);
}
+ } else if ((strncmp(devpath, "/devices/", 9) == 0)) {
+ if (strcmp(action, "add") == 0) {
+ /* wait for sysfs */
+ dbg("devices add");
- sysfs_close_class_device(class_dev);
- break;
- case REMOVE:
- dbg("udev remove");
+ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath);
+ devices_dev = wait_devices_device_open(path);
+ if (!devices_dev) {
+ dbg("devices device unavailable (probably remove has beaten us)");
+ goto exit;
+ }
+ dbg("devices device opened '%s'", path);
- /* get node from db, delete it*/
- retval = udev_remove_device(&udev);
+ wait_for_devices_device(devices_dev, &error);
- /* run dev.d/ scripts if we're not instructed to ignore the event */
- if (udev.devname[0] != '\0') {
- setenv("DEVNAME", udev.devname, 1);
- dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX);
+ sysfs_close_device(devices_dev);
+ } else if (strcmp(action, "remove") == 0) {
+ dbg("devices remove");
}
+ } else {
+ dbg("unhandled");
}
exit:
diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c
deleted file mode 100644
index 84a25adb97..0000000000
--- a/wait_for_sysfs.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * wait_for_sysfs.c - small program to delay the execution
- * of /etc/hotplug.d/ programs, until sysfs
- * is fully populated by the kernel. Depending on
- * the type of device, we wait for all expected
- * directories and then just exit.
- *
- * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
- * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <sys/stat.h>
-
-#include "libsysfs/sysfs/libsysfs.h"
-#include "udev_lib.h"
-#include "udev_version.h"
-#include "udev_sysfs.h"
-#include "logging.h"
-
-#ifdef LOG
-unsigned char logname[LOGNAME_SIZE];
-void log_message(int level, const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vsyslog(level, format, args);
- va_end(args);
-}
-#endif
-
-int main(int argc, char *argv[], char *envp[])
-{
- const char *devpath = "";
- const char *action;
- const char *subsystem;
- char sysfs_mnt_path[SYSFS_PATH_MAX];
- char filename[SYSFS_PATH_MAX];
- struct sysfs_class_device *class_dev;
- struct sysfs_device *devices_dev;
- int rc = 0;
- const char *error = NULL;
-
- logging_init("wait_for_sysfs");
-
- if (argc != 2) {
- dbg("error: subsystem");
- return 1;
- }
- subsystem = argv[1];
-
- devpath = getenv ("DEVPATH");
- if (!devpath) {
- dbg("error: no DEVPATH");
- rc = 1;
- goto exit;
- }
-
- action = getenv ("ACTION");
- if (!action) {
- dbg("error: no ACTION");
- rc = 1;
- goto exit;
- }
-
- /* we only wait on an add event */
- if (strcmp(action, "add") != 0) {
- dbg("no add ACTION");
- goto exit;
- }
-
- if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) {
- dbg("error: no sysfs path");
- rc = 2;
- goto exit;
- }
-
- if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) {
- snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath);
- filename[SYSFS_PATH_MAX-1] = '\0';
-
- /* skip bad events where we get no device for the class */
- if (strncmp(devpath, "/class/", 7) == 0 && strchr(&devpath[7], '/') == NULL) {
- dbg("no device name for '%s', bad event", devpath);
- goto exit;
- }
-
- /* open the class device we are called for */
- class_dev = wait_class_device_open(filename);
- if (!class_dev) {
- dbg("error: class device unavailable (probably remove has beaten us)");
- goto exit;
- }
- dbg("class device opened '%s'", filename);
-
- /* wait for the class device with possible physical device and bus */
- wait_for_class_device(class_dev, &error);
-
- /*
- * we got too many unfixable class/net errors, kernel later than 2.6.10-rc1 will
- * solve this by exporting the needed information with the hotplug event
- * until we use this just don't print any error for net devices, but still
- * wait for it.
- */
- if (strncmp(devpath, "/class/net/", 11) == 0)
- error = NULL;
-
- sysfs_close_class_device(class_dev);
-
- } else if ((strncmp(devpath, "/devices/", 9) == 0)) {
- snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath);
- filename[SYSFS_PATH_MAX-1] = '\0';
-
- /* open the path we are called for */
- devices_dev = wait_devices_device_open(filename);
- if (!devices_dev) {
- dbg("error: devices device unavailable (probably remove has beaten us)");
- goto exit;
- }
- dbg("devices device opened '%s'", filename);
-
- /* wait for the devices device */
- wait_for_devices_device(devices_dev, &error);
-
- sysfs_close_device(devices_dev);
-
- } else {
- dbg("unhandled sysfs path, no need to wait");
- }
-
-exit:
- if (error) {
- info("either wait_for_sysfs (udev %s) needs an update to handle the device '%s' "
- "properly (%s) or the sysfs-support of your device's driver needs to be fixed, "
- "please report to <linux-hotplug-devel@lists.sourceforge.net>",
- UDEV_VERSION, devpath, error);
- rc =3;
- } else {
- dbg("result: waiting for sysfs successful '%s'", devpath);
- }
-
- logging_close();
- exit(rc);
-}