linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] multple rules files support/symlink rules support
@ 2004-01-17 20:13 Andrey Borzenkov
  2004-01-20 17:09 ` Andrey Borzenkov
                   ` (14 more replies)
  0 siblings, 15 replies; 16+ messages in thread
From: Andrey Borzenkov @ 2004-01-17 20:13 UTC (permalink / raw)
  To: linux-hotplug

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

Attached patch adds support for

- multiple rules files. You can now do

udev_rules="file1 dir2 file3 ..."

directory is scanned and all files are read. Currently it does not descend 
into subdirs.

- to make the above really useful it allows multiple rules with symlinks; all 
rules are collected and applied (note 100 characters limit for total names 
length currently). It still takes the first found name and warns if more were 
seen.

The multiple files support for rules file is actually for the case when you 
need be sure about ordering; sorting readdir results was too clumsy.

The patch allows easy local customization without any need to edit existing 
rules. It is expected that distributions will ship basic rules (based on 
required policy or compatibility or whatever) and users will create extra 
rules to name some devices to taste. E.g. I currently have basic Mandrake 
config that creates compatible devfs names and local rules to name some local 
devices. Ie.

udev_rules="/etc/udev/conf.d"

with

{pts/0}% LC_ALL=C ll /etc/udev/conf.d
total 8
-rw-r--r--    1 root     root          142 Jan 17 22:07 bor
-rwxr-xr-x    1 root     root         3848 Jan 17 22:58 udev.rules.devfs*

where

{pts/0}% cat /etc/udev/conf.d/bor
KERNEL="hd*" PROGRAM="/etc/udev/scripts/removables %k" SYMLINK="%c/%D"
KERNEL="sd*" PROGRAM="/etc/udev/scripts/removables %k" SYMLINK="%c/%D"

and I get 

{pts/0}% LC_ALL=C ll /udev/flash0
total 1
lrwxrwxrwx    1 root     root            6 Jan 17 22:59 disc -> ../sdb
lrwxrwxrwx    1 root     root            7 Jan 17 22:59 part1 -> ../sdb1

for USB stick (upper one :)

(not that interesting because currently SCSI devfs names are missing, but that 
would create them as well just fine).

regards

-andrey

[-- Attachment #2: udev013_multi.patch --]
[-- Type: text/x-diff, Size: 5691 bytes --]

--- udev-013/namedev.c.multi	2004-01-14 03:21:03.000000000 +0300
+++ udev-013/namedev.c	2004-01-17 22:55:20.955272056 +0300
@@ -602,6 +602,7 @@ int namedev_name_device(struct sysfs_cla
 	struct config_device *dev;
 	struct perm_device *perm;
 	char *pos;
+	int found = 0;
 
 	udev->mode = 0;
 
@@ -714,29 +715,46 @@ int namedev_name_device(struct sysfs_cla
 			}
 		}
 
-		/* check if we are instructed to ignore this device */
-		if (dev->name[0] == '\0') {
-			dbg("instructed to ignore this device");
-			return -1;
+		/* if everything matched add symlink to list of aliases */
+		if (dev->symlink[0] != '\0') {
+			char temp[NAME_MAX];
+
+			/* do not clobber dev */
+			strfieldcpy(temp, dev->symlink);
+			apply_format(udev, temp);
+			if (strlen(udev->symlink) + strlen(temp) + 2 > sizeof(udev->symlink))
+				dbg("could not append symlink %s for %s",
+				    dev->symlink, udev->kernel_name);
+			else {
+				strfieldcat(udev->symlink, temp);
+				strfieldcat(udev->symlink, " ");
+			}
 		}
 
-		/* Yup, this rule belongs to us! */
-		dbg("found matching rule, '%s' becomes '%s'", dev->kernel, dev->name);
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		goto found;
+		/* is this symlink only rule? */
+		if (dev->name[0] == '\0')
+			continue;
+
+		/* Yup, this rule belongs to us!
+		 * but continue to collect symlinks */
+		if (!found) {
+			dbg("found matching rule, '%s' becomes '%s'",
+			    dev->kernel, dev->name);
+			strfieldcpy(udev->name, dev->name);
+
+			/* substitute placeholder */
+			apply_format(udev, udev->name);
+			found = 1;
+		} else
+			dbg("conflicting rule for '%s' would become '%s'",
+			    dev->kernel, dev->name);
 	}
 
 	/* no rule was found so we use the kernel name */
-	strfieldcpy(udev->name, class_dev->name);
-	goto done;
-
-found:
-	/* substitute placeholder */
-	apply_format(udev, udev->name);
-	apply_format(udev, udev->symlink);
+	if (!found)
+		strfieldcpy(udev->name, class_dev->name);
+	dbg("symlinks for '%s' are: '%s'", udev->name, udev->symlink);
 
-done:
 	perm = find_perm(udev->name);
 	if (perm) {
 		udev->mode = perm->mode;
--- udev-013/namedev_parse.c.multi	2004-01-13 03:09:55.000000000 +0300
+++ udev-013/namedev_parse.c	2004-01-17 22:25:43.000000000 +0300
@@ -34,6 +34,8 @@
 #include <ctype.h>
 #include <unistd.h>
 #include <errno.h>
+#include <dirent.h>
+#include <sys/stat.h>
 
 #include "udev.h"
 #include "namedev.h"
@@ -120,7 +122,7 @@ void dump_perm_dev_list(void)
 }
 
 
-int namedev_init_rules(void)
+static int parse_rules_file(const char *file)
 {
 	char line[255];
 	int lineno;
@@ -132,11 +134,11 @@ int namedev_init_rules(void)
 	int retval = 0;
 	struct config_device dev;
 
-	fd = fopen(udev_rules_filename, "r");
+	fd = fopen(file, "r");
 	if (fd != NULL) {
-		dbg("reading '%s' as rules file", udev_rules_filename);
+		dbg("reading '%s' as rules file", file);
 	} else {
-		dbg("can't open '%s' as a rules file", udev_rules_filename);
+		dbg("can't open '%s' as a rules file", file);
 		return -ENODEV;
 	}
 
@@ -263,7 +265,7 @@ exit:
 	return retval;
 }
 
-int namedev_init_permissions(void)
+static int parse_permissions_file(const char *file)
 {
 	char line[255];
 	char *temp;
@@ -272,11 +274,11 @@ int namedev_init_permissions(void)
 	int retval = 0;
 	struct perm_device dev;
 
-	fd = fopen(udev_permissions_filename, "r");
+	fd = fopen(file, "r");
 	if (fd != NULL) {
-		dbg("reading '%s' as permissions file", udev_permissions_filename);
+		dbg("reading '%s' as permissions file", file);
 	} else {
-		dbg("can't open '%s' as permissions file", udev_permissions_filename);
+		dbg("can't open '%s' as permissions file", file);
 		return -ENODEV;
 	}
 
@@ -345,4 +347,67 @@ exit:
 	return retval;
 }	
 
+static int parse_rules(char *var, int (*func)(const char *))
+{
+	static char temp[PATH_MAX + NAME_MAX];
+	static char temp1[PATH_MAX + NAME_MAX];
+	char *p = temp, *file;
+	struct stat buf;
+	int err = 0;
+
+	strfieldcpy(temp, var);
+	while ((file = strsep(&p, " ")) != NULL) {
+		dbg("parse_rules: looking at file %s", file);
+
+		if (stat(file, &buf) == -1) {
+			err = errno;
+			dbg("parse_rules: can't stat %s", file);
+			goto out;
+		}
+
+		if (S_ISREG(buf.st_mode)) {
+			err = (*func)(file);
+			if (err)
+				goto out;
+		} else if (S_ISDIR(buf.st_mode)) {
+			DIR *dir;
+			struct dirent *dirent;
+
+			if ((dir = opendir(file)) == NULL) {
+				err = errno;
+				dbg("parse_rules: can't open directory %s", file);
+				goto out;
+			}
+
+			/* FIXME: This does not check for errors */
+			while ((dirent = readdir(dir)) != NULL) {
+				if (dirent->d_name[0] == '.')
+					continue;
+
+				dbg("parse_rules: for direntry %s", dirent->d_name);
+				strfieldcpy(temp1, file);
+				strfieldcat(temp1, "/");
+				strfieldcat(temp1, dirent->d_name);
+				err = (*func)(temp1);
+				/* do not skip remaining files */
+			}
+		} else {
+			dbg("parse_rules: unknown file type %s", file);
+			err = -EINVAL;
+			goto out;
+		}
+	}
 
+out:
+	return err;
+}
+
+int namedev_init_rules(void)
+{
+	return parse_rules(udev_rules_filename, parse_rules_file);
+}
+
+int namedev_init_permissions(void)
+{
+	return parse_rules(udev_permissions_filename, parse_permissions_file);
+}
--- udev-013/udev.h.multi	2004-01-13 03:09:55.000000000 +0300
+++ udev-013/udev.h	2004-01-17 22:25:43.000000000 +0300
@@ -80,6 +80,13 @@ do { \
 	strncpy(to, from, sizeof(to)-1); \
 } while (0)
 
+#define strfieldcat(to, from) \
+do { \
+	to[sizeof(to)-1] = '\0'; \
+	strncat(to, from, sizeof(to)-1); \
+} while (0)
+
+
 extern int udev_add_device(char *path, char *subsystem);
 extern int udev_remove_device(char *path, char *subsystem);
 extern void udev_init_config(void);

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2004-02-17 17:29 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-17 20:13 [PATCH] multple rules files support/symlink rules support Andrey Borzenkov
2004-01-20 17:09 ` Andrey Borzenkov
2004-01-20 17:57 ` Svetoslav Slavtchev
2004-01-20 18:45 ` Andrey Borzenkov
2004-01-20 23:10 ` Svetoslav Slavtchev
2004-01-21 23:51 ` Greg KH
2004-01-22 17:44 ` Svetoslav Slavtchev
2004-01-26 17:31 ` Andrey Borzenkov
2004-01-26 23:42 ` Kay Sievers
2004-01-27  9:54 ` "Andrey Borzenkov" 
2004-01-27 11:43 ` Marco d'Itri
2004-02-03  1:04 ` Greg KH
2004-02-03 11:25 ` Gioele Barabucci
2004-02-16 22:34 ` Greg KH
2004-02-17  7:29 ` "Andrey Borzenkov" 
2004-02-17 17:29 ` Greg KH

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).