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);
prev parent 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).