linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: Re: experimental udevd with builtin udev
Date: Tue, 19 Oct 2004 03:26:20 +0000	[thread overview]
Message-ID: <20041019032620.GA9106@vrfy.org> (raw)
In-Reply-To: <20041018232625.GA8419@vrfy.org>

[-- Attachment #1: Type: text/plain, Size: 2144 bytes --]

On Tue, Oct 19, 2004 at 01:26:25AM +0200, Kay Sievers wrote:
> Here is an experiment to build udev into udevd instead of loading the
> binary from disk. It still forks a child, but the child only handles node
> creation/removal and dev.d/ execution.
> 
> The rules are only parsed once on startup of udevd. The parsed config is
> available to the child, cause we don't exec() anything, we just continue
> the execution in the child.
> 
> If /dev is on tmpfs, no disk activity will happen on an udev event!
> 
> Changes to rules only apply on restart of udevd.
> 
> Don't install it! This is highly experimental and may render you system
> unusable. It can be easily tested by building it, killing the running
> udevd and start the copy in the tree with ./udevd. This copy will listen
> to the socket and handle all udev events from udevsend.
> 
> The log looks like this:
> 
>   udevd[11974]: main: version 039
>   udevd[11974]: get_dirs: sysfs_path='/sys'
>   udevd[11974]: parse_config_file: reading '/etc/udev/udev.conf' as config file
>   udevd[11974]: namedev_parse_rules: reading '/etc/udev/rules.d/50-udev.rules' as rules file
>   udevd[11974]: namedev_parse_permissions: reading '/etc/udev/permissions.d/50-udev.permissions' as permissions file
>   ...
>   kernel: usb 3-2: USB disconnect, address 9
>   udevd(event)[11977]: removing device node '/dev/input/mouse2'
>   udevd(event)[11979]: removing device node '/dev/input/event3'
>   ...
>   kernel: usb 3-2: new low speed USB device using address 10
>   kernel: input: USB HID v1.10 Mouse [Logitech USB-PS/2 Optical Mouse] on usb-0000:00:1d.1-2
>   udevd(event)[11989]: configured rule in '/etc/udev/rules.d/50-udev.rules' at line 24 applied, 'mouse2' becomes 'input/%k'
>   udevd(event)[11989]: creating device node '/dev/input/mouse2'
>   udevd(event)[11996]: configured rule in '/etc/udev/rules.d/50-udev.rules' at line 25 applied, 'event3' becomes 'input/%k'
>   udevd(event)[11996]: creating device node '/dev/input/event3'
>   ...
> 
> What do you think?

Here is the version to apply after the last the sysfs-expose and the
udevd-cleanup patch.

Enough for today, thanks,
Kay

[-- Attachment #2: udevd-new-noexec-02.patch --]
[-- Type: text/plain, Size: 5514 bytes --]

===== Makefile 1.197 vs edited =====
--- 1.197/Makefile	2004-10-19 04:07:38 +02:00
+++ edited/Makefile	2004-10-19 05:05:44 +02:00
@@ -217,6 +217,7 @@ OBJS =	udev_lib.o	\
 	namedev.o	\
 	namedev_parse.o	\
 	dev_d.o		\
+	udevstart.o		\
 	$(SYSFS)	\
 	$(TDB)
 
@@ -285,7 +286,7 @@ $(STARTER).o: $(GEN_HEADERS) $(HOST_PROG
 $(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS)
 
 $(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES)
-	$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS)
 	$(QUIET) $(STRIPCMD) $@
 
 $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS)
@@ -297,7 +298,7 @@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEA
 	$(QUIET) $(STRIPCMD) $@
 
 $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h
-	$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS)
+	$(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o $(OBJS) $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS)
 	$(QUIET) $(STRIPCMD) $@
 
 $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h
===== udevd.c 1.43 vs edited =====
--- 1.43/udevd.c	2004-10-19 05:02:16 +02:00
+++ edited/udevd.c	2004-10-19 05:20:19 +02:00
@@ -43,6 +43,16 @@
 #include "udev_version.h"
 #include "udevd.h"
 #include "logging.h"
+#include "namedev.h"
+#include "udevdb.h"
+#include "udev_sysfs.h"
+
+/* timeout flag for udevdb */
+extern sig_atomic_t gotalarm;
+
+/* global variables */
+char **main_argv;
+char **main_envp;
 
 static int pipefds[2];
 static unsigned long long expected_seqnum = 0;
@@ -129,29 +139,88 @@ static void msg_queue_insert(struct hotp
 	return ;
 }
 
+static void asmlinkage udev_sig_handler(int signum)
+{
+	switch (signum) {
+		case SIGALRM:
+			gotalarm = 1;
+			info("error: timeout reached, event probably not handled correctly");
+			break;
+		case SIGINT:
+		case SIGTERM:
+			udevdb_exit();
+			exit(20 + signum);
+		default:
+			dbg("unhandled signal %d", signum);
+	}
+}
+
 /* forks event and removes event from run queue when finished */
 static void udev_run(struct hotplug_msg *msg)
 {
+	char path[SYSFS_PATH_MAX];
+	struct sysfs_class_device *class_dev;
 	pid_t pid;
-	char action[ACTION_SIZE];
-	char devpath[DEVPATH_SIZE];
-	char seqnum[SEQNUM_SIZE];
-	char *env[] = { action, devpath, seqnum, NULL };
-
-	snprintf(action, ACTION_SIZE-1, "ACTION=%s", msg->action);
-	action[ACTION_SIZE-1] = '\0';
-	snprintf(devpath, DEVPATH_SIZE-1, "DEVPATH=%s", msg->devpath);
-	devpath[DEVPATH_SIZE-1] = '\0';
-	sprintf(seqnum, "SEQNUM=%llu", msg->seqnum);
+	struct sigaction act;
+	int retval = 0;
+	struct udevice udev;
 
 	pid = fork();
 	switch (pid) {
 	case 0:
-		/* child */
-		execle(udev_bin, "udev", msg->subsystem, NULL, env);
-		dbg("exec of child failed");
-		_exit(1);
-		break;
+		/* child reopens log for new name[pid] */
+		logging_close();
+		logging_init("udevd(event)");
+
+		/* set signal handlers */
+		act.sa_handler = (void (*) (int))udev_sig_handler;
+		sigemptyset (&act.sa_mask);
+		/* alarm must not restart syscalls*/
+		sigaction(SIGALRM, &act, NULL);
+		sigaction(SIGINT, &act, NULL);
+		sigaction(SIGTERM, &act, NULL);
+
+		/* trigger timout to interrupt blocking syscalls */
+		alarm(ALARM_TIMEOUT);
+
+		/* we only care about class block devices */
+		if (strstr(msg->devpath, "class") || strstr(msg->devpath, "block")) {
+			/* skip blacklisted subsystems */
+			udev_set_values(&udev, msg->devpath, msg->subsystem);
+			if (udev.type != 'n' && subsystem_expect_no_dev(msg->subsystem)) {
+				dbg("don't care about '%s' devices", msg->subsystem);
+				goto exit;
+			};
+
+			/* initialize udev database */
+			if (udevdb_init(UDEVDB_DEFAULT) != 0)
+				info("error: unable to initialize database, continuing without database");
+
+			if (strcmp(msg->action, "add") == 0) {
+				dbg("udev add");
+
+				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");
+					break;
+				}
+				dbg("opened class_dev->name='%s'", class_dev->name);
+
+				retval = udev_add_device(&udev, class_dev);
+				dev_d_execute(&udev);
+
+			} else if (strcmp(msg->action, "remove") == 0) {
+				dbg("udev remove");
+				retval = udev_remove_device(&udev);
+				dev_d_execute(&udev);
+			}
+			udevdb_exit();
+		}
+
+exit:
+		logging_close();
+		exit(retval);
 	case -1:
 		dbg("fork of child failed");
 		run_queue_delete(msg);
@@ -309,7 +378,7 @@ skip:
 	return;
 }
 
-static void asmlinkage sig_handler(int signum)
+static void asmlinkage udevd_sig_handler(int signum)
 {
 	int rc;
 
@@ -458,7 +527,7 @@ int main(int argc, char *argv[], char *e
 	}
 
 	/* set signal handlers */
-	act.sa_handler = (void (*) (int)) sig_handler;
+	act.sa_handler = (void (*) (int)) udevd_sig_handler;
 	sigemptyset(&act.sa_mask);
 	act.sa_flags = SA_RESTART;
 	sigaction(SIGINT, &act, NULL);
@@ -495,12 +564,9 @@ int main(int argc, char *argv[], char *e
 	/* enable receiving of the sender credentials */
 	setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on));
 
-	/* possible override of udev binary, used for testing */
-	udev_bin = getenv("UDEV_BIN");
-	if (udev_bin != NULL)
-		dbg("udev binary is set to '%s'", udev_bin);
-	else
-		udev_bin = UDEV_BIN;
+	/* read config and rules files for the forked udev instances */
+	udev_init_config();
+	namedev_init();
 
 	FD_ZERO(&readfds);
 	FD_SET(ssock, &readfds);

      reply	other threads:[~2004-10-19  3:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-10-18 23:26 experimental udevd with builtin udev Kay Sievers
2004-10-19  3:26 ` Kay Sievers [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20041019032620.GA9106@vrfy.org \
    --to=kay.sievers@vrfy.org \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).