* replace dev.d/ with a rule based program execution
@ 2005-02-21 18:12 Kay Sievers
2005-02-22 8:08 ` Hannes Reinecke
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-21 18:12 UTC (permalink / raw)
To: linux-hotplug
Here is an experimental patch to replace the brute-force dev.d/ script
execution by a rule based model, with the same logic we currently use to
name a device. While searching for a rule to apply, we collect programs
to execute after node creation/removal.
This makes it possible to gain complete control of the execution of programs
for a specific device instead of letting the programs exit if they don't
want to handle the device.
We apply the rule on device remove events too. A ACTION="<value>" match can
be used to write rules that are only applied on a specific action.
I've replaced the following:
[kay@pim ~]$ tree /etc/dev.d/
/etc/dev.d/
|-- default
| |-- 00-log.dev
| |-- 05-pam_console.dev -> ../../udev/scripts/pam_console.dev
| `-- 10-hal.dev -> /usr/libexec/hal.dev
|-- fd0
| `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
|-- fd1
| `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
|-- fd2
| `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
|-- fd3
| `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
`-- sound
`-- alsa.dev
With these rules:
KERNEL="ttyUSB*", HOTPLUG="<usb-serial-device program>"
SUBSYSTEM="tty", OPTIONS="no_hotplug"
SUBSYSTEM="vc", OPTIONS="no_hotplug"
ACTION="add", SUBSYSTEM="sound", HOTPLUG="/etc/dev.d/sound/alsa.dev"
ACTION="add", KERNEL="fd*", HOTPLUG="/etc/udev/scripts/MAKEDEV.dev"
ACTION="add", HOTPLUG="/etc/udev/scripts/pam_console.dev"
HOTPLUG="/usr/libexec/hal.dev"
HOTPLUG="/etc/dev.d/default/00-log.dev"
On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
my default setup. Mainly because it will not run anything for all the virtual
tty devices. Any tty device which should be catched, needs a rule before the
"no_hotplug" option.
It is also possible to pass arguments to the scripts, which sometimes
makes it no longer necessary to wrap a program with a shell script.
We could also remove all the hardcoded knowledge about sysfs in the
wait_for_sysfs logic and replace it by a few simple ignore_device rules.
The same model could easily replace the whole hotplug.d/ multiplexing and
give use an efficient rule based event management with a single source of
policy.
What do you think?
Thanks,
Kay
=== namedev.c 1.188 vs edited ==--- 1.188/namedev.c 2005-02-21 07:01:52 +01:00
+++ edited/namedev.c 2005-02-21 17:29:11 +01:00
@@ -571,7 +571,7 @@ static int match_rule(struct udevice *ud
if (dev->kernel[0] != '\0') {
dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'",
dev->kernel, class_dev->name);
- if (strcmp_pattern(dev->kernel, class_dev->name) != 0) {
+ if (strcmp_pattern(dev->kernel, udev->kernel_name) != 0) {
dbg(FIELD_KERNEL " is not matching");
goto exit;
}
@@ -588,6 +588,16 @@ static int match_rule(struct udevice *ud
dbg(FIELD_SUBSYSTEM " matches");
}
+ if (dev->action[0] != '\0') {
+ dbg("check for " FIELD_ACTION " dev->action='%s' class_dev->name='%s'",
+ dev->action, class_dev->name);
+ if (strcmp_pattern(dev->action, udev->action) != 0) {
+ dbg(FIELD_ACTION " is not matching");
+ goto exit;
+ }
+ dbg(FIELD_ACTION " matches");
+ }
+
/* walk up the chain of physical devices and find a match */
while (1) {
/* check for matching driver */
@@ -689,13 +699,13 @@ exit:
return -1;
}
-int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev)
+int rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev)
{
struct sysfs_class_device *class_dev_parent;
struct sysfs_device *sysfs_device = NULL;
struct config_device *dev;
- dbg("class_dev->name='%s'", class_dev->name);
+ dbg("udev->devpath='%s'", udev->devpath);
/* Figure out where the "device"-symlink is at. For char devices this will
* always be in the class_dev->path. On block devices, only the main block
@@ -722,7 +732,6 @@ int namedev_name_device(struct udevice *
list_for_each_entry(dev, &config_device_list, node) {
dbg("process rule");
if (match_rule(udev, dev, class_dev, sysfs_device) = 0) {
-
/* apply options */
if (dev->ignore_device) {
info("configured rule in '%s[%i]' applied, '%s' is ignored",
@@ -730,7 +739,7 @@ int namedev_name_device(struct udevice *
return -1;
}
if (dev->ignore_remove) {
- udev->ignore_remove = dev->ignore_remove;
+ udev->ignore_remove = 1;
dbg_parse("remove event should be ignored");
}
/* apply all_partitions option only at a main block device */
@@ -738,6 +747,10 @@ int namedev_name_device(struct udevice *
udev->partitions = dev->partitions;
dbg("creation of partition nodes requested");
}
+ if (dev->no_hotplug) {
+ udev->no_hotplug = 1;
+ dbg_parse("supress hotplug program execution");
+ }
/* apply permissions */
if (dev->mode != 0000) {
@@ -768,6 +781,17 @@ int namedev_name_device(struct udevice *
strfieldcat(udev->symlink, temp);
}
+ /* collect hotplug programs */
+ if (dev->hotplug[0] != '\0') {
+ char temp[NAME_SIZE];
+
+ dbg("configured rule in '%s[%i]' added hotplug program '%s'",
+ dev->config_file, dev->config_line, dev->hotplug);
+ strfieldcpy(temp, dev->hotplug);
+ apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device);
+ name_list_add(&udev->hotplug_list, temp, 0);
+ }
+
/* rule matches */
if (dev->name[0] != '\0') {
info("configured rule in '%s[%i]' applied, '%s' becomes '%s'",
@@ -796,6 +820,70 @@ exit:
dbg("removing temporary device node");
unlink_secure(udev->tmp_node);
udev->tmp_node[0] = '\0';
+ }
+
+ return 0;
+}
+
+int rules_get_hotplug(struct udevice *udev)
+{
+ struct config_device *dev;
+ char temp[NAME_SIZE];
+
+ /* look for a matching rule to apply */
+ list_for_each_entry(dev, &config_device_list, node) {
+ dbg("process rule");
+
+ /* skip rules that can't match */
+ if (dev->bus[0] != '\0' || dev->id[0] != '\0' ||
+ dev->place[0] != '\0' || dev->sysfs_pair[0].file[0] != '\0' ||
+ dev->program[0] != '\0' || dev->result[0] != '\0' ||
+ dev->driver[0] != '\0')
+ continue;
+
+ if (dev->action[0] != '\0') {
+ dbg("check for " FIELD_ACTION " dev->action='%s' udev->action='%s'",
+ dev->action, udev->action);
+ if (strcmp(dev->action, udev->action) != 0) {
+ dbg(FIELD_ACTION " is not matching");
+ continue;
+ }
+ dbg(FIELD_ACTION " matches");
+ }
+
+ if (dev->subsystem[0] != '\0') {
+ dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' udev->subsystem='%s'",
+ dev->subsystem, udev->subsystem);
+ if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) {
+ dbg(FIELD_SUBSYSTEM " is not matching");
+ continue;
+ }
+ dbg(FIELD_SUBSYSTEM " matches");
+ }
+
+ if (dev->kernel[0] != '\0') {
+ dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'",
+ dev->kernel, udev->kernel_name);
+ if (strcmp_pattern(dev->kernel, udev->kernel_name) != 0) {
+ dbg(FIELD_KERNEL " is not matching");
+ continue;
+ }
+ dbg(FIELD_KERNEL " matches");
+ }
+
+ /* rule matches, see if hotplug programs should run*/
+ if (dev->no_hotplug) {
+ udev->no_hotplug = 1;
+ dbg_parse("supress hotplug program execution");
+ return -1;
+ }
+
+ if (dev->hotplug[0] = '\0')
+ continue;
+
+ strfieldcpy(temp, dev->hotplug);
+ apply_format(udev, temp, sizeof(temp), NULL, NULL);
+ name_list_add(&udev->hotplug_list, temp, 0);
}
return 0;
=== namedev.h 1.40 vs edited ==--- 1.40/namedev.h 2005-02-21 06:48:12 +01:00
+++ edited/namedev.h 2005-02-21 17:29:11 +01:00
@@ -34,10 +34,10 @@ struct sysfs_class_device;
#define ID_SIZE 64
#define PLACE_SIZE 64
#define DRIVER_SIZE 64
-#define PROGRAM_SIZE 128
#define FIELD_KERNEL "KERNEL"
#define FIELD_SUBSYSTEM "SUBSYSTEM"
+#define FIELD_ACTION "ACTION"
#define FIELD_BUS "BUS"
#define FIELD_SYSFS "SYSFS"
#define FIELD_ID "ID"
@@ -51,9 +51,11 @@ struct sysfs_class_device;
#define FIELD_GROUP "GROUP"
#define FIELD_MODE "MODE"
#define FIELD_OPTIONS "OPTIONS"
+#define FIELD_HOTPLUG "HOTPLUG"
#define ATTR_IGNORE_DEVICE "ignore_device"
#define ATTR_IGNORE_REMOVE "ignore_remove"
+#define ATTR_NO_HOTPLUG "no_hotplug"
#define ATTR_PARTITIONS "all_partitions"
#define MAX_SYSFS_PAIRS 5
@@ -70,6 +72,7 @@ struct config_device {
char kernel[NAME_SIZE];
char subsystem[SUBSYSTEM_SIZE];
+ char action[ACTION_SIZE];
char bus[BUS_SIZE];
char id[ID_SIZE];
char place[PLACE_SIZE];
@@ -87,6 +90,9 @@ struct config_device {
int partitions;
int ignore_device;
int ignore_remove;
+ int no_hotplug;
+
+ char hotplug[PROGRAM_SIZE];
char config_file[NAME_SIZE];
int config_line;
@@ -94,9 +100,11 @@ struct config_device {
extern struct list_head config_device_list;
-extern int namedev_init(void);
-extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev);
-extern void namedev_close(void);
+extern int rules_init(void);
+extern void rules_close(void);
+
+extern int rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev);
+extern int rules_get_hotplug(struct udevice *udev);
extern void dump_config_dev(struct config_device *dev);
extern void dump_config_dev_list(void);
=== namedev_parse.c 1.51 vs edited ==--- 1.51/namedev_parse.c 2005-02-21 06:05:51 +01:00
+++ edited/namedev_parse.c 2005-02-21 17:29:12 +01:00
@@ -98,7 +98,7 @@ static char *get_key_attribute(char *str
return NULL;
}
-static int namedev_parse(const char *filename, void *data)
+static int rules_parse(const char *filename, void *data)
{
char line[LINE_SIZE];
char *bufline;
@@ -183,6 +183,12 @@ static int namedev_parse(const char *fil
continue;
}
+ if (strcasecmp(temp2, FIELD_ACTION) = 0) {
+ strfieldcpy(dev.action, temp3);
+ valid = 1;
+ continue;
+ }
+
if (strcasecmp(temp2, FIELD_BUS) = 0) {
strfieldcpy(dev.bus, temp3);
valid = 1;
@@ -304,6 +310,16 @@ static int namedev_parse(const char *fil
dbg_parse("creation of partition nodes requested");
dev.partitions = DEFAULT_PARTITIONS_COUNT;
}
+ if (strstr(temp3, ATTR_NO_HOTPLUG) != NULL) {
+ dbg_parse("execution of hotplug programs supressed");
+ dev.no_hotplug = 1;
+ }
+ valid = 1;
+ continue;
+ }
+
+ if (strcasecmp(temp2, FIELD_HOTPLUG) = 0) {
+ strfieldcpy(dev.hotplug, temp3);
valid = 1;
continue;
}
@@ -345,7 +361,7 @@ error:
return retval;
}
-int namedev_init(void)
+int rules_init(void)
{
struct stat stats;
int retval;
@@ -354,14 +370,14 @@ int namedev_init(void)
return -1;
if ((stats.st_mode & S_IFMT) != S_IFDIR)
- retval = namedev_parse(udev_rules_filename, NULL);
+ retval = rules_parse(udev_rules_filename, NULL);
else
- retval = call_foreach_file(namedev_parse, udev_rules_filename, RULEFILE_SUFFIX, NULL);
+ retval = call_foreach_file(rules_parse, udev_rules_filename, RULEFILE_SUFFIX, NULL);
return retval;
}
-void namedev_close(void)
+void rules_close(void)
{
struct config_device *dev;
=== udev.8.in 1.78 vs edited ==--- 1.78/udev.8.in 2005-02-13 22:03:06 +01:00
+++ edited/udev.8.in 2005-02-21 17:29:12 +01:00
@@ -98,9 +98,8 @@ Every rule consists of a list of comma s
.sp
where fields are:
.TP
-.B BUS
-Match the bus type of the device.
-(The sysfs device bus must be able to be determined by a "device" symlink.)
+.B ACTION
+Match the event type.
.TP
.B KERNEL
Match the kernel device name.
@@ -108,9 +107,16 @@ Match the kernel device name.
.B SUBSYSTEM
Match the kernel subsystem name.
.TP
+.B ACTION
+Match the event action string.
+.TP
.B DRIVER
Match the kernel driver name.
.TP
+.B BUS
+Match the bus type of the device.
+(The sysfs device bus must be able to be determined by a "device" symlink.)
+.TP
.B ID
Match the device number on the bus, like PCI bus id.
.TP
@@ -178,6 +184,10 @@ This may be useful for removable media d
change.
.sp
Multiple attributes may be separated by comma.
+.TP
+.B HOTPLUG
+programs to be added to a list to be excuted after node creation or removal.
+Identical keys will only be added once.
.P
.RB "The " NAME ", " SYMLINK ", " PROGRAM ", " OWNER " and " GROUP
fields support simple printf-like string substitutions:
@@ -301,15 +311,7 @@ is set if udev is configured to use the
want to follow that setting.
.B DEVNAME
is exported to make the name of the created node, or the name the network
-device is renamed to, available to the executed program. The programs in every
-directory are sorted in lexical order, while the directories are searched in
-the following order:
-.sp
-.nf
-/etc/dev.d/$(DEVNAME)/*.dev
-/etc/dev.d/$(SUBSYSTEM)/*.dev
-/etc/dev.d/default/*.dev
-.fi
+device is renamed to, available to the executed program.
.SH "ENVIRONMENT"
.P
The following variables are read from the environment:
@@ -330,20 +332,11 @@ Overrides the default location of the
.B udev
config file.
.TP
-.B UDEV_NO_DEVD
-The default behavior of
-.B udev
-is to execute programs in the
-.I /etc/dev.d/
-directory after device handling. If set,
-.B udev
-will skip this step.
.SH "FILES"
.nf
/sbin/udev udev program
/etc/udev/* udev config files
/etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program
-/etc/dev.d/* programs invoked by udev
.fi
.SH "SEE ALSO"
.BR udevinfo (8),
=== udev.c 1.104 vs edited ==--- 1.104/udev.c 2005-02-21 07:01:52 +01:00
+++ edited/udev.c 2005-02-21 18:19:33 +01:00
@@ -136,7 +136,7 @@ int main(int argc, char *argv[], char *e
/* disable all logging, as it's much too slow on some facilities */
udev_log = 0;
- namedev_init();
+ rules_init();
retval = udev_start();
goto exit;
}
@@ -170,58 +170,72 @@ int main(int argc, char *argv[], char *e
if (udev_log)
setenv("UDEV_LOG", "1", 1);
- udev_init_device(&udev, devpath, subsystem);
+ udev_init_device(&udev, devpath, subsystem, action);
if (udev.type = BLOCK || udev.type = CLASS || udev.type = NET) {
- if (strcmp(action, "add") = 0) {
- /* wait for sysfs and possibly add node */
- dbg("udev add");
+ rules_init();
- /* skip subsystems without "dev", but handle net devices */
- if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) {
- dbg("don't care about '%s' devices", udev.subsystem);
- goto hotplug;
- }
+ if (strcmp(udev.action, "add") = 0) {
+ dbg("udev add");
+ /* wait for sysfs to populate */
snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath);
+ path[SYSFS_PATH_MAX-1] = '\0';
class_dev = wait_class_device_open(path);
if (class_dev = NULL) {
dbg ("open class device failed");
goto hotplug;
}
dbg("opened class_dev->name='%s'", class_dev->name);
-
wait_for_class_device(class_dev, &error);
- /* init rules */
- namedev_init();
+ /* create a node for devices with a "dev" file */
+ if (!subsystem_expect_no_dev(udev.subsystem)) {
+ udev.devt = get_devt(class_dev);
+ if (!udev.devt) {
+ dbg("dev file expected, but not found");
+ sysfs_close_class_device(class_dev);
+ goto hotplug;
+ }
+ }
- /* name, create node, store in db */
- retval = udev_add_device(&udev, class_dev);
+ /* name device or possibly ignore event */
+ if (rules_get_name(&udev, class_dev) != 0) {
+ sysfs_close_class_device(class_dev);
+ goto hotplug;
+ }
+ udev_add_device(&udev, class_dev);
sysfs_close_class_device(class_dev);
- } else if (strcmp(action, "remove") = 0) {
- /* possibly remove a node */
+
+ } else if (strcmp(udev.action, "remove") = 0) {
dbg("udev remove");
/* skip subsystems without "dev" */
if (subsystem_expect_no_dev(udev.subsystem)) {
- dbg("don't care about '%s' devices", udev.subsystem);
+ dbg("'%s' devices don't have device nodes", udev.subsystem);
goto hotplug;
}
+ /* get hotplug scripts or possibly ignore event */
+ if (rules_get_hotplug(&udev) != 0)
+ goto hotplug;
+
/* get node from db, remove db-entry, delete created node */
retval = udev_remove_device(&udev);
}
- /* run dev.d/ scripts if we created/deleted a node or changed a netif name */
- if (udev.devname[0] != '\0') {
+ /* execute hotplug scripts */
+ if (udev.devname[0] != '\0' && !udev.no_hotplug) {
+ struct name_entry *name_loop;
+
setenv("DEVNAME", udev.devname, 1);
- if (udev_dev_d)
- udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX);
+ list_for_each_entry(name_loop, &udev.hotplug_list, node)
+ execute_command(&udev, name_loop->name);
}
+
} else if (udev.type = PHYSDEV) {
- if (strcmp(action, "add") = 0) {
+ if (strcmp(udev.action, "add") = 0) {
/* wait for sysfs */
dbg("devices add");
@@ -236,12 +250,11 @@ int main(int argc, char *argv[], char *e
wait_for_devices_device(devices_dev, &error);
sysfs_close_device(devices_dev);
- } else if (strcmp(action, "remove") = 0) {
+ } else if (strcmp(action, "remove") = 0)
dbg("devices remove");
- }
- } else {
- dbg("unhandled");
- }
+
+ } else
+ dbg("don't care");
hotplug:
if (udev_hotplug_d && managed_event)
=== udev.h 1.87 vs edited ==--- 1.87/udev.h 2005-02-21 06:48:12 +01:00
+++ edited/udev.h 2005-02-21 17:29:12 +01:00
@@ -4,6 +4,7 @@
* Userspace devfs
*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2003-2005 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
@@ -31,7 +32,9 @@
#define ALARM_TIMEOUT 120
#define COMMENT_CHARACTER '#'
+#define LINE_SIZE 512
#define NAME_SIZE 256
+#define PROGRAM_SIZE 128
#define USER_SIZE 32
#define ACTION_SIZE 32
@@ -39,16 +42,16 @@
#define SUBSYSTEM_SIZE 32
#define SEQNUM_SIZE 32
-#define LINE_SIZE 512
-
-#define DEVD_DIR "/etc/dev.d"
-#define DEVD_SUFFIX ".dev"
-
#define HOTPLUGD_DIR "/etc/hotplug.d"
#define HOTPLUG_SUFFIX ".hotplug"
#define DEFAULT_PARTITIONS_COUNT 15
+struct name_entry {
+ struct list_head node;
+ char name[NAME_SIZE];
+};
+
enum device_type {
UNKNOWN,
CLASS,
@@ -58,22 +61,27 @@ enum device_type {
};
struct udevice {
+ char action[ACTION_SIZE];
char devpath[DEVPATH_SIZE];
char subsystem[SUBSYSTEM_SIZE];
char name[NAME_SIZE];
+ char devname[NAME_SIZE];
char symlink[NAME_SIZE];
char owner[USER_SIZE];
char group[USER_SIZE];
mode_t mode;
- char type;
+ enum device_type type ;
dev_t devt;
- char devname[NAME_SIZE];
char tmp_node[NAME_SIZE];
int partitions;
int ignore_remove;
- int config_line;
+ int no_hotplug;
+
+ struct list_head hotplug_list;
+
+ unsigned int config_line;
char config_file[NAME_SIZE];
char bus_id[SYSFS_NAME_LEN];
char program_result[NAME_SIZE];
@@ -95,7 +103,6 @@ extern char udev_db_path[PATH_MAX+NAME_M
extern char udev_config_filename[PATH_MAX+NAME_MAX];
extern char udev_rules_filename[PATH_MAX+NAME_MAX];
extern int udev_log;
-extern int udev_dev_d;
extern int udev_hotplug_d;
#endif
=== udev_add.c 1.95 vs edited ==--- 1.95/udev_add.c 2005-02-21 05:45:03 +01:00
+++ edited/udev_add.c 2005-02-21 17:29:12 +01:00
@@ -39,7 +39,6 @@
#include "libsysfs/sysfs/libsysfs.h"
#include "udev.h"
#include "udev_utils.h"
-#include "udev_sysfs.h"
#include "udev_version.h"
#include "logging.h"
#include "namedev.h"
@@ -272,17 +271,6 @@ int udev_add_device(struct udevice *udev
{
char *pos;
int retval = 0;
-
- if (udev->type = BLOCK || udev->type = CLASS) {
- udev->devt = get_devt(class_dev);
- if (!udev->devt) {
- dbg("no dev-file found, do nothing");
- return 0;
- }
- }
-
- if (namedev_name_device(udev, class_dev) != 0)
- return 0;
dbg("adding name='%s'", udev->name);
=== udev_config.c 1.31 vs edited ==--- 1.31/udev_config.c 2005-01-04 21:37:01 +01:00
+++ edited/udev_config.c 2005-02-21 17:29:12 +01:00
@@ -46,7 +46,6 @@ char udev_db_path[PATH_MAX+NAME_MAX];
char udev_rules_filename[PATH_MAX+NAME_MAX];
char udev_config_filename[PATH_MAX+NAME_MAX];
int udev_log;
-int udev_dev_d;
int udev_hotplug_d;
@@ -72,11 +71,6 @@ static void init_variables(void)
strcpy(udev_rules_filename, UDEV_RULES_FILE);
udev_log = string_is_true(UDEV_LOG_DEFAULT);
-
- udev_dev_d = 1;
- env = getenv("UDEV_NO_DEVD");
- if (env && string_is_true(env))
- udev_dev_d = 0;
udev_hotplug_d = 1;
env = getenv("UDEV_NO_HOTPLUGD");
=== udev_start.c 1.29 vs edited ==--- 1.29/udev_start.c 2005-02-10 10:26:09 +01:00
+++ edited/udev_start.c 2005-02-21 18:24:41 +01:00
@@ -35,6 +35,8 @@
#include <unistd.h>
#include "libsysfs/sysfs/libsysfs.h"
+#include "namedev.h"
+#include "udev_sysfs.h"
#include "logging.h"
#include "udev_utils.h"
#include "list.h"
@@ -96,7 +98,7 @@ static int add_device(const char *path,
devpath = &path[strlen(sysfs_path)];
- /* set environment for callouts and dev.d/ */
+ /* set environment for callouts and hotplug programs */
setenv("DEVPATH", devpath, 1);
setenv("SUBSYSTEM", subsystem, 1);
@@ -108,15 +110,32 @@ static int add_device(const char *path,
return -ENODEV;
}
- udev_init_device(&udev, devpath, subsystem);
+ udev_init_device(&udev, devpath, subsystem, "add");
+
+ /* create a node for devices with a "dev" file */
+ if (!subsystem_expect_no_dev(udev.subsystem)) {
+ udev.devt = get_devt(class_dev);
+ if (!udev.devt) {
+ dbg("dev file expected, but not found");
+ goto exit;
+ }
+ }
+
+ if (rules_get_name(&udev, class_dev) != 0)
+ goto exit;
+
udev_add_device(&udev, class_dev);
- /* run dev.d/ scripts if we created a node or changed a netif name */
- if (udev_dev_d && udev.devname[0] != '\0') {
+ /* execute hotplug scripts */
+ if (udev.devname[0] != '\0' && !udev.no_hotplug) {
+ struct name_entry *name_loop;
+
setenv("DEVNAME", udev.devname, 1);
- udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX);
+ list_for_each_entry(name_loop, &udev.hotplug_list, node)
+ execute_command(&udev, name_loop->name);
}
+exit:
sysfs_close_class_device(class_dev);
return 0;
@@ -280,7 +299,7 @@ static void udev_scan_class(void)
int udev_start(void)
{
- /* set environment for callouts and dev.d/ */
+ /* set environment for callouts and hotplug programs */
setenv("ACTION", "add", 1);
setenv("UDEV_START", "1", 1);
=== udev_utils.c 1.32 vs edited ==--- 1.32/udev_utils.c 2005-02-21 07:01:52 +01:00
+++ edited/udev_utils.c 2005-02-21 17:29:13 +01:00
@@ -29,6 +29,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sys/wait.h>
#include <sys/utsname.h>
#include "udev.h"
@@ -37,11 +38,12 @@
#include "list.h"
-int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem)
+int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action)
{
char *pos;
memset(udev, 0x00, sizeof(struct udevice));
+ INIT_LIST_HEAD(&udev->hotplug_list);
if (devpath) {
strfieldcpy(udev->devpath, devpath);
@@ -49,6 +51,8 @@ int udev_init_device(struct udevice *ude
}
if (subsystem)
strfieldcpy(udev->subsystem, subsystem);
+ if (action)
+ strfieldcpy(udev->action, action);
if (strcmp(udev->subsystem, "block") = 0)
udev->type = BLOCK;
@@ -262,13 +266,7 @@ void no_trailing_slash(char *path)
path[--len] = '\0';
}
-struct name_entry {
- struct list_head node;
- char name[NAME_SIZE];
-};
-
-/* sort files in lexical order */
-static int name_list_add(struct list_head *name_list, const char *name, int sort)
+int name_list_add(struct list_head *name_list, const char *name, int sort)
{
struct name_entry *loop_name;
struct name_entry *new_name;
@@ -291,6 +289,69 @@ static int name_list_add(struct list_hea
strfieldcpy(new_name->name, name);
list_add_tail(&new_name->node, &loop_name->node);
+
+ return 0;
+}
+
+int execute_command(struct udevice *udev, const char *command)
+{
+ int retval;
+ pid_t pid;
+ char arg[PROGRAM_SIZE];
+ char *argv[(PROGRAM_SIZE / 2) + 1];
+ char *pos;
+ int fd;
+ int i;
+
+ strfieldcpy(arg, command);
+ i = 0;
+ if (strchr(command, ' ')) {
+ pos = arg;
+ while (pos != NULL) {
+ if (pos[0] = '\'') {
+ /* don't separate if in apostrophes */
+ pos++;
+ argv[i] = strsep(&pos, "\'");
+ while (pos && pos[0] = ' ')
+ pos++;
+ } else {
+ argv[i] = strsep(&pos, " ");
+ }
+ dbg("arg[%i] '%s'", i, argv[i]);
+ i++;
+ }
+ argv[i] = NULL;
+ dbg("execute '%s' with parsed arguments", arg);
+ } else {
+ argv[0] = arg;
+ argv[1] = udev->subsystem;
+ argv[2] = NULL;
+ dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]);
+ }
+
+ pid = fork();
+ switch (pid) {
+ case 0:
+ /* child */
+ fd = open("/dev/null", O_RDWR);
+ if ( fd >= 0) {
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDERR_FILENO);
+ }
+ close(fd);
+
+ retval = execv(arg, argv);
+ dbg("exec of child failed");
+ _exit(1);
+ case -1:
+ dbg("fork of child failed");
+ break;
+ return -1;
+ default:
+ waitpid(pid, NULL, 0);
+ }
+
return 0;
}
=== udev_utils.h 1.23 vs edited ==--- 1.23/udev_utils.h 2005-02-21 06:48:12 +01:00
+++ edited/udev_utils.h 2005-02-21 17:29:13 +01:00
@@ -76,7 +76,7 @@ do { \
# define asmlinkage /* nothing */
#endif
-extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem);
+extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action);
extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel);
extern int create_path(const char *path);
extern int parse_get_pair(char **orig_string, char **left, char **right);
@@ -86,6 +86,8 @@ extern void file_unmap(char *buf, size_t
extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur);
extern void no_trailing_slash(char *path);
typedef int (*file_fnct_t)(const char *filename, void *data);
+extern int execute_command(struct udevice *udev, const char *command);
+extern int name_list_add(struct list_head *name_list, const char *name, int sort);
extern int call_foreach_file(file_fnct_t fnct, const char *dirname,
const char *suffix, void *data);
=== udevtest.c 1.24 vs edited ==--- 1.24/udevtest.c 2005-02-21 05:45:04 +01:00
+++ edited/udevtest.c 2005-02-21 17:29:13 +01:00
@@ -85,13 +85,13 @@ int main(int argc, char *argv[], char *e
info("looking at '%s'", devpath);
/* initialize the naming deamon */
- namedev_init();
+ rules_init();
if (argc = 3)
subsystem = argv[2];
/* fill in values and test_run flag*/
- udev_init_device(&udev, devpath, subsystem);
+ udev_init_device(&udev, devpath, subsystem, "add");
/* skip subsystems without "dev", but handle net devices */
if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) {
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
@ 2005-02-22 8:08 ` Hannes Reinecke
2005-02-22 17:53 ` Harald Hoyer
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Hannes Reinecke @ 2005-02-22 8:08 UTC (permalink / raw)
To: linux-hotplug
Kay Sievers wrote:
> Here is an experimental patch to replace the brute-force dev.d/ script
> execution by a rule based model, with the same logic we currently use to
> name a device. While searching for a rule to apply, we collect programs
> to execute after node creation/removal.
>
> This makes it possible to gain complete control of the execution of programs
> for a specific device instead of letting the programs exit if they don't
> want to handle the device.
>
> We apply the rule on device remove events too. A ACTION="<value>" match can
> be used to write rules that are only applied on a specific action.
>
> I've replaced the following:
> [kay@pim ~]$ tree /etc/dev.d/
> /etc/dev.d/
> |-- default
> | |-- 00-log.dev
> | |-- 05-pam_console.dev -> ../../udev/scripts/pam_console.dev
> | `-- 10-hal.dev -> /usr/libexec/hal.dev
> |-- fd0
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd1
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd2
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd3
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> `-- sound
> `-- alsa.dev
>
> With these rules:
> KERNEL="ttyUSB*", HOTPLUG="<usb-serial-device program>"
> SUBSYSTEM="tty", OPTIONS="no_hotplug"
> SUBSYSTEM="vc", OPTIONS="no_hotplug"
>
> ACTION="add", SUBSYSTEM="sound", HOTPLUG="/etc/dev.d/sound/alsa.dev"
> ACTION="add", KERNEL="fd*", HOTPLUG="/etc/udev/scripts/MAKEDEV.dev"
> ACTION="add", HOTPLUG="/etc/udev/scripts/pam_console.dev"
>
> HOTPLUG="/usr/libexec/hal.dev"
> HOTPLUG="/etc/dev.d/default/00-log.dev"
>
> On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
> my default setup. Mainly because it will not run anything for all the virtual
> tty devices. Any tty device which should be catched, needs a rule before the
> "no_hotplug" option.
>
> It is also possible to pass arguments to the scripts, which sometimes
> makes it no longer necessary to wrap a program with a shell script.
>
> We could also remove all the hardcoded knowledge about sysfs in the
> wait_for_sysfs logic and replace it by a few simple ignore_device rules.
>
> The same model could easily replace the whole hotplug.d/ multiplexing and
> give use an efficient rule based event management with a single source of
> policy.
>
> What do you think?
>
YES. This is a Good Thing (tm).
Go for it.
Otherwise udevstart performance is basically killed by tty events.
And vc events, but this is another story.
Too sad we've already entered feature freeze ...
Cheers,
Hannes
--
Dr. Hannes Reinecke hare@suse.de
SuSE Linux AG S390 & zSeries
Maxfeldstraße 5 +49 911 74053 688
90409 Nürnberg http://www.suse.de
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&opÌk
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
2005-02-22 8:08 ` Hannes Reinecke
@ 2005-02-22 17:53 ` Harald Hoyer
2005-02-23 1:08 ` Marco d'Itri
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Harald Hoyer @ 2005-02-22 17:53 UTC (permalink / raw)
To: linux-hotplug
Kay Sievers wrote:
...
> I've replaced the following:
> [kay@pim ~]$ tree /etc/dev.d/
> /etc/dev.d/
> |-- default
> | |-- 00-log.dev
> | |-- 05-pam_console.dev -> ../../udev/scripts/pam_console.dev
> | `-- 10-hal.dev -> /usr/libexec/hal.dev
> |-- fd0
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd1
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd2
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd3
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> `-- sound
> `-- alsa.dev
>
> With these rules:
> KERNEL="ttyUSB*", HOTPLUG="<usb-serial-device program>"
> SUBSYSTEM="tty", OPTIONS="no_hotplug"
> SUBSYSTEM="vc", OPTIONS="no_hotplug"
>
> ACTION="add", SUBSYSTEM="sound", HOTPLUG="/etc/dev.d/sound/alsa.dev"
> ACTION="add", KERNEL="fd*", HOTPLUG="/etc/udev/scripts/MAKEDEV.dev"
> ACTION="add", HOTPLUG="/etc/udev/scripts/pam_console.dev"
>
> HOTPLUG="/usr/libexec/hal.dev"
> HOTPLUG="/etc/dev.d/default/00-log.dev"
>
> On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
> my default setup. Mainly because it will not run anything for all the virtual
> tty devices. Any tty device which should be catched, needs a rule before the
> "no_hotplug" option.
Very nice! I like that :)
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
2005-02-22 8:08 ` Hannes Reinecke
2005-02-22 17:53 ` Harald Hoyer
@ 2005-02-23 1:08 ` Marco d'Itri
2005-02-24 20:15 ` David Zeuthen
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Marco d'Itri @ 2005-02-23 1:08 UTC (permalink / raw)
To: linux-hotplug
[-- Attachment #1: Type: text/plain, Size: 544 bytes --]
On Feb 21, Kay Sievers <kay.sievers@vrfy.org> wrote:
I think it looks good, except that the non-terminal semantic of HOTPLUG
rules basically makes them hard to mix with NAME rules (which instead
I understand would prevent the following HOTPLUG rules from being
processed).
Not that this is a bad idea in itself, but it should be clarified in the
documentation and possibly enforced by the code if it does not already
do it.
Also, maybe a flag to make an HOTPLUG rule terminal could be useful in
some situation.
--
ciao,
Marco
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (2 preceding siblings ...)
2005-02-23 1:08 ` Marco d'Itri
@ 2005-02-24 20:15 ` David Zeuthen
2005-02-24 20:34 ` Kay Sievers
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: David Zeuthen @ 2005-02-24 20:15 UTC (permalink / raw)
To: linux-hotplug
On Mon, 2005-02-21 at 19:12 +0100, Kay Sievers wrote:
<snip>
>On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
>my default setup.
Sweet.
>What do you think?
I think it's really nice. I have an additional feature request; it would
be really nice to split udevinfo into a library too; that would give us
the following benefits
1. Things like hald doesn't need to spawn a gazillion copies of
udevinfo when doing it's coldplug thing; I think this was asked
for earlier too. It sure beats reading the udev database directly
which seems error prone at best, and it would be much much faster.
2. If you do changes to udevinfo it pretty much right now screws
things depending on udev (we saw that around udev-013 IIRC);
with a library you would bump the soname and depsolvers will refuse
to upgrade.
What do you think?
Thanks,
David
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (3 preceding siblings ...)
2005-02-24 20:15 ` David Zeuthen
@ 2005-02-24 20:34 ` Kay Sievers
2005-02-24 20:45 ` David Zeuthen
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-24 20:34 UTC (permalink / raw)
To: linux-hotplug
On Thu, 2005-02-24 at 15:15 -0500, David Zeuthen wrote:
>On Mon, 2005-02-21 at 19:12 +0100, Kay Sievers wrote:
>I have an additional feature request; it would
>be really nice to split udevinfo into a library too; that would give us
>the following benefits
>
> 1. Things like hald doesn't need to spawn a gazillion copies of
> udevinfo when doing it's coldplug thing; I think this was asked
> for earlier too. It sure beats reading the udev database directly
> which seems error prone at best, and it would be much much faster.
HAL needs this only in the coldplug case, so what about letting udevinfo
dumping a list of _all_ devpath -> node matches with a single call and
HAL can merge all the names in one go into the device objects?
Thanks,
Kay
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (4 preceding siblings ...)
2005-02-24 20:34 ` Kay Sievers
@ 2005-02-24 20:45 ` David Zeuthen
2005-02-24 21:04 ` Kay Sievers
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: David Zeuthen @ 2005-02-24 20:45 UTC (permalink / raw)
To: linux-hotplug
On Thu, 2005-02-24 at 21:34 +0100, Kay Sievers wrote:
>HAL needs this only in the coldplug case, so what about letting udevinfo
>dumping a list of _all_ devpath -> node matches with a single call and
>HAL can merge all the names in one go into the device objects?
That would work, yeah.
Cheers,
David
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (5 preceding siblings ...)
2005-02-24 20:45 ` David Zeuthen
@ 2005-02-24 21:04 ` Kay Sievers
2005-02-24 21:52 ` Kay Sievers
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-24 21:04 UTC (permalink / raw)
To: linux-hotplug
On Thu, 2005-02-24 at 15:45 -0500, David Zeuthen wrote:
>On Thu, 2005-02-24 at 21:34 +0100, Kay Sievers wrote:
>>HAL needs this only in the coldplug case, so what about letting udevinfo
>>dumping a list of _all_ devpath -> node matches with a single call and
>>HAL can merge all the names in one go into the device objects?
>
>That would work, yeah.
So we should go for it? What format? Any options needed?
$ udevinfo -d
/block/fd0:/dev/fd0
/block/hda:/dev/hda
/class/input/mice:/dev/input/mice
/class/mem/null:/dev/null
...
Thanks,
Kay
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (6 preceding siblings ...)
2005-02-24 21:04 ` Kay Sievers
@ 2005-02-24 21:52 ` Kay Sievers
2005-02-24 22:03 ` David Zeuthen
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-24 21:52 UTC (permalink / raw)
To: linux-hotplug
[-- Attachment #1: Type: text/plain, Size: 692 bytes --]
On Thu, 2005-02-24 at 22:04 +0100, Kay Sievers wrote:
>On Thu, 2005-02-24 at 15:45 -0500, David Zeuthen wrote:
>>On Thu, 2005-02-24 at 21:34 +0100, Kay Sievers wrote:
>>>HAL needs this only in the coldplug case, so what about letting udevinfo
>>>dumping a list of _all_ devpath -> node matches with a single call and
>>>HAL can merge all the names in one go into the device objects?
>>
>>That would work, yeah.
>
>So we should go for it? What format? Any options needed?
>
> $ udevinfo -d
> /block/fd0:/dev/fd0
> /block/hda:/dev/hda
> /class/input/mice:/dev/input/mice
> /class/mem/null:/dev/null
> ...
Something stupid like this? It dumps all my ~700 devices in 0.02
seconds. :)
Kay
[-- Attachment #2: udev-dump-db-01.patch --]
[-- Type: text/x-patch, Size: 2919 bytes --]
===== udev_db.c 1.45 vs edited =====
--- 1.45/udev_db.c 2005-02-24 12:13:24 +01:00
+++ edited/udev_db.c 2005-02-24 22:26:41 +01:00
@@ -239,3 +239,38 @@
return 0;
}
+
+int udev_db_call_foreach(int (*handler_function)(struct udevice *udev))
+{
+ struct dirent *ent;
+ DIR *dir;
+ char filename[NAME_SIZE];
+ struct udevice db_udev;
+
+ dir = opendir(udev_db_path);
+ if (dir == NULL) {
+ dbg("unable to udev db '%s'", udev_db_path);
+ return -1;
+ }
+
+ while (1) {
+ ent = readdir(dir);
+ if (ent == NULL || ent->d_name[0] == '\0')
+ break;
+
+ if (ent->d_name[0] == '.')
+ continue;
+
+ snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name);
+ filename[NAME_SIZE-1] = '\0';
+
+ memset(&db_udev, 0x00, sizeof(struct udevice));
+ if (parse_db_file(&db_udev, filename) == 0) {
+ if (handler_function(&db_udev) != 0)
+ break;
+ }
+ }
+
+ closedir(dir);
+ return 0;
+}
===== udev_db.h 1.20 vs edited =====
--- 1.20/udev_db.h 2005-02-24 12:13:24 +01:00
+++ edited/udev_db.h 2005-02-24 22:26:10 +01:00
@@ -30,5 +30,6 @@
extern int udev_db_get_device_by_devpath(struct udevice *dev, const char *devpath);
extern int udev_db_get_device_by_name(struct udevice *udev, const char *name);
+extern int udev_db_call_foreach(int (*handler_function)(struct udevice *udev));
#endif /* _UDEV_DB_H_ */
===== udevinfo.8 1.16 vs edited =====
--- 1.16/udevinfo.8 2005-02-23 04:21:38 +01:00
+++ edited/udevinfo.8 2005-02-24 22:44:05 +01:00
@@ -47,6 +47,10 @@
unique attributes to compose a rule.
.RB Needs " \-p " specified.
.TP
+.B \-d
+Print the relationship between the devpath and the node name for all devices
+currently available in the database.
+.TP
.B \-h
Print help text.
.SH "FILES"
===== udevinfo.c 1.44 vs edited =====
--- 1.44/udevinfo.c 2005-02-24 12:13:24 +01:00
+++ edited/udevinfo.c 2005-02-24 22:43:27 +01:00
@@ -178,9 +178,14 @@
return retval;
}
+static int print_dump(struct udevice *udev) {
+ printf("%s:%s/%s\n", udev->devpath, udev_root, udev->name);
+ return 0;
+}
+
static int process_options(int argc, char *argv[])
{
- static const char short_options[] = "an:p:q:rVh";
+ static const char short_options[] = "adn:p:q:rVh";
int option;
int retval = 1;
struct udevice udev;
@@ -245,6 +250,10 @@
attributes = 1;
break;
+ case 'd':
+ udev_db_call_foreach(print_dump);
+ exit(0);
+
case 'V':
printf("udevinfo, version %s\n", UDEV_VERSION);
exit(0);
@@ -384,7 +393,8 @@
"\n"
" -r print udev root\n"
" -a print all SYSFS_attributes along the device chain\n"
- " -s print all sysfs devices with major/minor, physical device and bus\n"
+ " -d print the relationship of devpath and the node name for all\n"
+ " devices available in the database\n"
" -V print udev version\n"
" -h print this help text\n"
"\n");
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (7 preceding siblings ...)
2005-02-24 21:52 ` Kay Sievers
@ 2005-02-24 22:03 ` David Zeuthen
2005-02-25 23:26 ` Greg KH
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: David Zeuthen @ 2005-02-24 22:03 UTC (permalink / raw)
To: linux-hotplug
On Thu, 2005-02-24 at 22:52 +0100, Kay Sievers wrote:
>On Thu, 2005-02-24 at 22:04 +0100, Kay Sievers wrote:
>>On Thu, 2005-02-24 at 15:45 -0500, David Zeuthen wrote:
>>>On Thu, 2005-02-24 at 21:34 +0100, Kay Sievers wrote:
>>>>HAL needs this only in the coldplug case, so what about letting udevinfo
>>>>dumping a list of _all_ devpath -> node matches with a single call and
>>>>HAL can merge all the names in one go into the device objects?
>>>
>>>That would work, yeah.
>>
>>So we should go for it? What format? Any options needed?
>>
>> $ udevinfo -d
>> /block/fd0:/dev/fd0
>> /block/hda:/dev/hda
>> /class/input/mice:/dev/input/mice
>> /class/mem/null:/dev/null
>> ...
>
>Something stupid like this? It dumps all my ~700 devices in 0.02
>seconds. :)
Looks good to me; thanks a lot!
Cheers,
David
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (8 preceding siblings ...)
2005-02-24 22:03 ` David Zeuthen
@ 2005-02-25 23:26 ` Greg KH
2005-02-26 0:28 ` Kay Sievers
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Greg KH @ 2005-02-25 23:26 UTC (permalink / raw)
To: linux-hotplug
On Mon, Feb 21, 2005 at 07:12:42PM +0100, Kay Sievers wrote:
> Here is an experimental patch to replace the brute-force dev.d/ script
> execution by a rule based model, with the same logic we currently use to
> name a device. While searching for a rule to apply, we collect programs
> to execute after node creation/removal.
>
> This makes it possible to gain complete control of the execution of programs
> for a specific device instead of letting the programs exit if they don't
> want to handle the device.
>
> We apply the rule on device remove events too. A ACTION="<value>" match can
> be used to write rules that are only applied on a specific action.
>
> I've replaced the following:
> [kay@pim ~]$ tree /etc/dev.d/
> /etc/dev.d/
> |-- default
> | |-- 00-log.dev
> | |-- 05-pam_console.dev -> ../../udev/scripts/pam_console.dev
> | `-- 10-hal.dev -> /usr/libexec/hal.dev
> |-- fd0
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd1
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd2
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> |-- fd3
> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
> `-- sound
> `-- alsa.dev
>
> With these rules:
> KERNEL="ttyUSB*", HOTPLUG="<usb-serial-device program>"
> SUBSYSTEM="tty", OPTIONS="no_hotplug"
> SUBSYSTEM="vc", OPTIONS="no_hotplug"
>
> ACTION="add", SUBSYSTEM="sound", HOTPLUG="/etc/dev.d/sound/alsa.dev"
> ACTION="add", KERNEL="fd*", HOTPLUG="/etc/udev/scripts/MAKEDEV.dev"
> ACTION="add", HOTPLUG="/etc/udev/scripts/pam_console.dev"
>
> HOTPLUG="/usr/libexec/hal.dev"
> HOTPLUG="/etc/dev.d/default/00-log.dev"
>
> On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
> my default setup. Mainly because it will not run anything for all the virtual
> tty devices. Any tty device which should be catched, needs a rule before the
> "no_hotplug" option.
>
> It is also possible to pass arguments to the scripts, which sometimes
> makes it no longer necessary to wrap a program with a shell script.
I like the general idea, but we can't break the /etc/dev.d/ functionalty
so much.
If we just add a udev option (like you show above) for "no_dev.d", we
could still have the massive udevstart speedups, right? So this is ok
with me.
Remember, it's easier for a package to drop a symlink into the
/etc/dev.d/ directory tree, than it is for it to modify / add a udev
rule.
> We could also remove all the hardcoded knowledge about sysfs in the
> wait_for_sysfs logic and replace it by a few simple ignore_device rules.
How would that happen?
> The same model could easily replace the whole hotplug.d/ multiplexing and
> give use an efficient rule based event management with a single source of
> policy.
See my previous response as to why we can't do this.
thanks,
greg k-h
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (9 preceding siblings ...)
2005-02-25 23:26 ` Greg KH
@ 2005-02-26 0:28 ` Kay Sievers
2005-02-26 0:57 ` Marco d'Itri
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-26 0:28 UTC (permalink / raw)
To: linux-hotplug
On Fri, 2005-02-25 at 15:26 -0800, Greg KH wrote:
>On Mon, Feb 21, 2005 at 07:12:42PM +0100, Kay Sievers wrote:
>> Here is an experimental patch to replace the brute-force dev.d/ script
>> execution by a rule based model, with the same logic we currently use to
>> name a device. While searching for a rule to apply, we collect programs
>> to execute after node creation/removal.
>>
>> This makes it possible to gain complete control of the execution of programs
>> for a specific device instead of letting the programs exit if they don't
>> want to handle the device.
>>
>> We apply the rule on device remove events too. A ACTION="<value>" match can
>> be used to write rules that are only applied on a specific action.
>>
>> I've replaced the following:
>> [kay@pim ~]$ tree /etc/dev.d/
>> /etc/dev.d/
>> |-- default
>> | |-- 00-log.dev
>> | |-- 05-pam_console.dev -> ../../udev/scripts/pam_console.dev
>> | `-- 10-hal.dev -> /usr/libexec/hal.dev
>> |-- fd0
>> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
>> |-- fd1
>> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
>> |-- fd2
>> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
>> |-- fd3
>> | `-- 10-MAKEDEV.dev -> ../../udev/scripts/MAKEDEV.dev
>> `-- sound
>> `-- alsa.dev
>>
>> With these rules:
>> KERNEL="ttyUSB*", HOTPLUG="<usb-serial-device program>"
>> SUBSYSTEM="tty", OPTIONS="no_hotplug"
>> SUBSYSTEM="vc", OPTIONS="no_hotplug"
>>
>> ACTION="add", SUBSYSTEM="sound", HOTPLUG="/etc/dev.d/sound/alsa.dev"
>> ACTION="add", KERNEL="fd*", HOTPLUG="/etc/udev/scripts/MAKEDEV.dev"
>> ACTION="add", HOTPLUG="/etc/udev/scripts/pam_console.dev"
>>
>> HOTPLUG="/usr/libexec/hal.dev"
>> HOTPLUG="/etc/dev.d/default/00-log.dev"
>>
>> On my box, udevstart takes 2.1 seconds instead of 8.6 seconds to run with
>> my default setup. Mainly because it will not run anything for all the virtual
>> tty devices. Any tty device which should be catched, needs a rule before the
>> "no_hotplug" option.
>>
>> It is also possible to pass arguments to the scripts, which sometimes
>> makes it no longer necessary to wrap a program with a shell script.
>
>I like the general idea, but we can't break the /etc/dev.d/ functionalty
>so much.
>
>If we just add a udev option (like you show above) for "no_dev.d", we
>could still have the massive udevstart speedups, right? So this is ok
>with me.
We should plug that in with a external program called by a rule.
>Remember, it's easier for a package to drop a symlink into the
>/etc/dev.d/ directory tree, than it is for it to modify / add a udev
>rule.
Packages should drop a single rules file instead.
>> We could also remove all the hardcoded knowledge about sysfs in the
>> wait_for_sysfs logic and replace it by a few simple ignore_device rules.
>
>How would that happen?
We match against the SUBSYSTEM and KERNEL and request a specific sysfs
value, which will wait until it appears. That is generic, nice,
configurable, elegant and users can tweak it for their needs.
>> The same model could easily replace the whole hotplug.d/ multiplexing and
>> give use an efficient rule based event management with a single source of
>> policy.
>
>See my previous response as to why we can't do this.
Just let the users decide. We would ship a backwards compatible default
setup, but the user can remove the multiplex emulation rule and has a
nice, clean rule-based solution without all that crap compiled in.
Thanks,
Kay
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (10 preceding siblings ...)
2005-02-26 0:28 ` Kay Sievers
@ 2005-02-26 0:57 ` Marco d'Itri
2005-02-26 1:04 ` Kay Sievers
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Marco d'Itri @ 2005-02-26 0:57 UTC (permalink / raw)
To: linux-hotplug
[-- Attachment #1: Type: text/plain, Size: 427 bytes --]
On Feb 26, Greg KH <greg@kroah.com> wrote:
> Remember, it's easier for a package to drop a symlink into the
> /etc/dev.d/ directory tree, than it is for it to modify / add a udev
> rule.
True, but creating a symlink in /etc/udev/rules.d/ is as easy (as long
as distribution maintainers have discipline and properly document how
new files should be named to have them processed at the right time).
--
ciao,
Marco
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (11 preceding siblings ...)
2005-02-26 0:57 ` Marco d'Itri
@ 2005-02-26 1:04 ` Kay Sievers
2005-02-26 1:06 ` Marco d'Itri
2005-02-26 2:22 ` Kay Sievers
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-26 1:04 UTC (permalink / raw)
To: linux-hotplug
On Sat, 2005-02-26 at 01:57 +0100, Marco d'Itri wrote:
>On Feb 26, Greg KH <greg@kroah.com> wrote:
>
>> Remember, it's easier for a package to drop a symlink into the
>> /etc/dev.d/ directory tree, than it is for it to modify / add a udev
>> rule.
>True, but creating a symlink in /etc/udev/rules.d/ is as easy (as long
>as distribution maintainers have discipline and properly document how
>new files should be named to have them processed at the right time).
Sure, it may be easier, but dropping brute-force executed programs to a
directory _is_ the current problem we need to address, and what all the
discussion is about, right?
Kay
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (12 preceding siblings ...)
2005-02-26 1:04 ` Kay Sievers
@ 2005-02-26 1:06 ` Marco d'Itri
2005-02-26 2:22 ` Kay Sievers
14 siblings, 0 replies; 16+ messages in thread
From: Marco d'Itri @ 2005-02-26 1:06 UTC (permalink / raw)
To: linux-hotplug
[-- Attachment #1: Type: text/plain, Size: 835 bytes --]
On Feb 26, Kay Sievers <kay.sievers@vrfy.org> wrote:
> >> Remember, it's easier for a package to drop a symlink into the
> >> /etc/dev.d/ directory tree, than it is for it to modify / add a udev
> >> rule.
> >True, but creating a symlink in /etc/udev/rules.d/ is as easy (as long
> >as distribution maintainers have discipline and properly document how
> >new files should be named to have them processed at the right time).
> Sure, it may be easier, but dropping brute-force executed programs to a
> directory _is_ the current problem we need to address, and what all the
> discussion is about, right?
Yes, what I am saying is that it will not be a problem if packages
will need to provide udev rules instead of a dev.d/ script.
And if we keep dev.d/ we are left with the issue of making it scale.
--
ciao,
Marco
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: replace dev.d/ with a rule based program execution
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
` (13 preceding siblings ...)
2005-02-26 1:06 ` Marco d'Itri
@ 2005-02-26 2:22 ` Kay Sievers
14 siblings, 0 replies; 16+ messages in thread
From: Kay Sievers @ 2005-02-26 2:22 UTC (permalink / raw)
To: linux-hotplug
On Sat, 2005-02-26 at 02:06 +0100, Marco d'Itri wrote:
>On Feb 26, Kay Sievers <kay.sievers@vrfy.org> wrote:
>
>> >> Remember, it's easier for a package to drop a symlink into the
>> >> /etc/dev.d/ directory tree, than it is for it to modify / add a udev
>> >> rule.
>> >True, but creating a symlink in /etc/udev/rules.d/ is as easy (as long
>> >as distribution maintainers have discipline and properly document how
>> >new files should be named to have them processed at the right time).
>> Sure, it may be easier, but dropping brute-force executed programs to a
>> directory _is_ the current problem we need to address, and what all the
>> discussion is about, right?
>Yes, what I am saying is that it will not be a problem if packages
>will need to provide udev rules instead of a dev.d/ script.
>And if we keep dev.d/ we are left with the issue of making it scale.
Yes, I'm all for going that way. We may use Greg's tiny multiplexer to
emulate the current behavior and systems who don't depend on it can just
remove the rule for it and on event time no directory needs to be
examined.
If we ever get too much rule files, we may even write the parsed rules
out as a binary array and just mmap() it with any later udev event
process, so we would have the best possible performance.
Kay
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click
_______________________________________________
Linux-hotplug-devel mailing list http://linux-hotplug.sourceforge.net
Linux-hotplug-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2005-02-26 2:22 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-21 18:12 replace dev.d/ with a rule based program execution Kay Sievers
2005-02-22 8:08 ` Hannes Reinecke
2005-02-22 17:53 ` Harald Hoyer
2005-02-23 1:08 ` Marco d'Itri
2005-02-24 20:15 ` David Zeuthen
2005-02-24 20:34 ` Kay Sievers
2005-02-24 20:45 ` David Zeuthen
2005-02-24 21:04 ` Kay Sievers
2005-02-24 21:52 ` Kay Sievers
2005-02-24 22:03 ` David Zeuthen
2005-02-25 23:26 ` Greg KH
2005-02-26 0:28 ` Kay Sievers
2005-02-26 0:57 ` Marco d'Itri
2005-02-26 1:04 ` Kay Sievers
2005-02-26 1:06 ` Marco d'Itri
2005-02-26 2:22 ` Kay Sievers
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).