All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.