linux-hotplug.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* udev - question about current config format
@ 2004-01-09 14:21 Kay Sievers
  2004-01-10  1:30 ` Greg KH
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Kay Sievers @ 2004-01-09 14:21 UTC (permalink / raw)
  To: linux-hotplug

Hi Greg,
I want to ask if we shouldn't change the namedev logic and
make the rules generic and drop the different methods, cause
the name for the method is mostly redundant.
All what namedev does is applying a name when all device attributes
are matching. It's not neccessary to to tell namedev to REPLACE,
cause we always replace :)
And why shouldn't we be able to combine a SYSFS_ attribute with the
KERNEL name?


So here is a first idea:

  Every line in udev.rules consists only of a number of <key>="<value>"

    BUS           match with bus type
    SYSFS_<file>  match with device attribute
    ID/PLACE      match with bus "number" or "id"
    KERNEL        match with kernel device name
    RESULT        match with string returned by executed PROGRAM
    PROGRAM       program to execute (true if exec returned with 0)

    NAME          name for the device node
    SYMLINK       one or more symlinks to NAME

  The rules are processed in the order they are given in the file.
  Every configured KEY must match to apply the rule.
  It would be more flexible cause we may use all possible keys in a rule.
  It would be possible to exec the external program only for one specific
  device to get its name.
  We would be able to skip the expensive execution of the external
  program if one of the other keys doesn't match.

    KERNEL="video*", PROGRAM="script.sh", NAME="%c"
    SYSFS_model="V0815", PROGRAM="script.sh", NAME="%c"
    SYSFS_model="V0815", KERNEL="video*", NAME="video/%n"

Do we need a bus PLACE? In current udev it seems we have the same
processing for TOPOLOGY and NUMBER.


What do you think?
Do I miss something?

thanks,
Kay



-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
@ 2004-01-10  1:30 ` Greg KH
  2004-01-10  1:38 ` Kay Sievers
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2004-01-10  1:30 UTC (permalink / raw)
  To: linux-hotplug

On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> Hi Greg,
> I want to ask if we shouldn't change the namedev logic and
> make the rules generic and drop the different methods, cause
> the name for the method is mostly redundant.
> All what namedev does is applying a name when all device attributes
> are matching. It's not neccessary to to tell namedev to REPLACE,
> cause we always replace :)
> And why shouldn't we be able to combine a SYSFS_ attribute with the
> KERNEL name?

Hm, this sounds like a good idea...

> So here is a first idea:
> 
>   Every line in udev.rules consists only of a number of <key>="<value>"
> 
>     BUS           match with bus type
>     SYSFS_<file>  match with device attribute
>     ID/PLACE      match with bus "number" or "id"
>     KERNEL        match with kernel device name
>     RESULT        match with string returned by executed PROGRAM
>     PROGRAM       program to execute (true if exec returned with 0)

So don't match on a string value here?  Hm, would that make writing
programs easier?  At first glance it might.  It also might be a bit
easier to understand.

>     NAME          name for the device node
>     SYMLINK       one or more symlinks to NAME
> 
>   The rules are processed in the order they are given in the file.
>   Every configured KEY must match to apply the rule.
>   It would be more flexible cause we may use all possible keys in a rule.
>   It would be possible to exec the external program only for one specific
>   device to get its name.
>   We would be able to skip the expensive execution of the external
>   program if one of the other keys doesn't match.
> 
>     KERNEL="video*", PROGRAM="script.sh", NAME="%c"
>     SYSFS_model="V0815", PROGRAM="script.sh", NAME="%c"
>     SYSFS_model="V0815", KERNEL="video*", NAME="video/%n"
> 
> Do we need a bus PLACE? In current udev it seems we have the same
> processing for TOPOLOGY and NUMBER.

We do have the same processing, as I've never gotten around to fixing up
the topology logic.  I think we now have enough info in libsysfs to do
this, I just need to get the time...

But it might be redundant, as some buses (like usb) encode their
topology information in the bus number.  I don't know, what do other
people think about this?

At first glance, this is a big simplification, and yet is more flexible,
I like it :)

Due to your reorganization of the parser, it's not that hard to do this
either...

Any other people's opinions?

Have a patch to play with?

thanks,

greg k-h


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
  2004-01-10  1:30 ` Greg KH
@ 2004-01-10  1:38 ` Kay Sievers
  2004-01-10  3:52 ` Greg KH
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2004-01-10  1:38 UTC (permalink / raw)
  To: linux-hotplug

On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> >   Every line in udev.rules consists only of a number of <key>="<value>"
> > 
> >     BUS           match with bus type
> >     SYSFS_<file>  match with device attribute
> >     ID/PLACE      match with bus "number" or "id"
> >     KERNEL        match with kernel device name
> >     RESULT        match with string returned by executed PROGRAM
> >     PROGRAM       program to execute (true if exec returned with 0)
> 
> So don't match on a string value here?  Hm, would that make writing
> programs easier?  At first glance it might.  It also might be a bit
> easier to understand.

What kind of string value do you mean?


> At first glance, this is a big simplification, and yet is more flexible,
> I like it :)
> 
> Have a patch to play with?

Wait a few days :)


Kay


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
  2004-01-10  1:30 ` Greg KH
  2004-01-10  1:38 ` Kay Sievers
@ 2004-01-10  3:52 ` Greg KH
  2004-01-10  4:01 ` Kay Sievers
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2004-01-10  3:52 UTC (permalink / raw)
  To: linux-hotplug

On Sat, Jan 10, 2004 at 02:38:50AM +0100, Kay Sievers wrote:
> On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> > On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> > >   Every line in udev.rules consists only of a number of <key>="<value>"
> > > 
> > >     BUS           match with bus type
> > >     SYSFS_<file>  match with device attribute
> > >     ID/PLACE      match with bus "number" or "id"
> > >     KERNEL        match with kernel device name
> > >     RESULT        match with string returned by executed PROGRAM
> > >     PROGRAM       program to execute (true if exec returned with 0)
> > 
> > So don't match on a string value here?  Hm, would that make writing
> > programs easier?  At first glance it might.  It also might be a bit
> > easier to understand.
> 
> What kind of string value do you mean?

Sorry, I meant the string return value of the script.  Like I had to
hack "good" and "bad" as return values of the name_cd script.  The IDstuff.

thanks,

greg k-h


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
                   ` (2 preceding siblings ...)
  2004-01-10  3:52 ` Greg KH
@ 2004-01-10  4:01 ` Kay Sievers
  2004-01-10  4:03 ` Greg KH
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2004-01-10  4:01 UTC (permalink / raw)
  To: linux-hotplug

On Fri, Jan 09, 2004 at 07:52:43PM -0800, Greg KH wrote:
> On Sat, Jan 10, 2004 at 02:38:50AM +0100, Kay Sievers wrote:
> > On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> > > On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> > > >   Every line in udev.rules consists only of a number of <key>="<value>"
> > > > 
> > > >     BUS           match with bus type
> > > >     SYSFS_<file>  match with device attribute
> > > >     ID/PLACE      match with bus "number" or "id"
> > > >     KERNEL        match with kernel device name
> > > >     RESULT        match with string returned by executed PROGRAM
> > > >     PROGRAM       program to execute (true if exec returned with 0)
> > > 
> > > So don't match on a string value here?  Hm, would that make writing
> > > programs easier?  At first glance it might.  It also might be a bit
> > > easier to understand.
> > 
> > What kind of string value do you mean?
> 
> Sorry, I meant the string return value of the script.  Like I had to
> hack "good" and "bad" as return values of the name_cd script.  The ID> stuff.

I'm thinking of:

PROGRAM= is true when it exits successful
RESULT= is compared with the returned string, but it is not neccessary
like todays ID= if the exit code it enough.
Just exit with nonzero in your name_cd - no "good" or "bad" :)

Kay


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
                   ` (3 preceding siblings ...)
  2004-01-10  4:01 ` Kay Sievers
@ 2004-01-10  4:03 ` Greg KH
  2004-01-10  5:27 ` Kay Sievers
  2004-01-10  5:39 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Greg KH @ 2004-01-10  4:03 UTC (permalink / raw)
  To: linux-hotplug

On Sat, Jan 10, 2004 at 05:01:31AM +0100, Kay Sievers wrote:
> On Fri, Jan 09, 2004 at 07:52:43PM -0800, Greg KH wrote:
> > On Sat, Jan 10, 2004 at 02:38:50AM +0100, Kay Sievers wrote:
> > > On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> > > > On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> > > > >   Every line in udev.rules consists only of a number of <key>="<value>"
> > > > > 
> > > > >     BUS           match with bus type
> > > > >     SYSFS_<file>  match with device attribute
> > > > >     ID/PLACE      match with bus "number" or "id"
> > > > >     KERNEL        match with kernel device name
> > > > >     RESULT        match with string returned by executed PROGRAM
> > > > >     PROGRAM       program to execute (true if exec returned with 0)
> > > > 
> > > > So don't match on a string value here?  Hm, would that make writing
> > > > programs easier?  At first glance it might.  It also might be a bit
> > > > easier to understand.
> > > 
> > > What kind of string value do you mean?
> > 
> > Sorry, I meant the string return value of the script.  Like I had to
> > hack "good" and "bad" as return values of the name_cd script.  The ID> > stuff.
> 
> I'm thinking of:
> 
> PROGRAM= is true when it exits successful
> RESULT= is compared with the returned string, but it is not neccessary
> like todays ID= if the exit code it enough.
> Just exit with nonzero in your name_cd - no "good" or "bad" :)

Ah, that's much nicer, and pretty sane.

greg k-h


-------------------------------------------------------
This SF.net email is sponsored by: Perforce Software.
Perforce is the Fast Software Configuration Management System offering
advanced branching capabilities and atomic changes on 50+ platforms.
Free Eval! http://www.perforce.com/perforce/loadprog.html
_______________________________________________
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] 8+ messages in thread

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
                   ` (4 preceding siblings ...)
  2004-01-10  4:03 ` Greg KH
@ 2004-01-10  5:27 ` Kay Sievers
  2004-01-10  5:39 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2004-01-10  5:27 UTC (permalink / raw)
  To: linux-hotplug

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

On Fri, Jan 09, 2004 at 08:03:42PM -0800, Greg KH wrote:
> On Sat, Jan 10, 2004 at 05:01:31AM +0100, Kay Sievers wrote:
> > On Fri, Jan 09, 2004 at 07:52:43PM -0800, Greg KH wrote:
> > > On Sat, Jan 10, 2004 at 02:38:50AM +0100, Kay Sievers wrote:
> > > > On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> > > > > On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> > > > > >   Every line in udev.rules consists only of a number of <key>="<value>"
> > > > > > 
> > > > > >     BUS           match with bus type
> > > > > >     SYSFS_<file>  match with device attribute
> > > > > >     ID/PLACE      match with bus "number" or "id"
> > > > > >     KERNEL        match with kernel device name
> > > > > >     RESULT        match with string returned by executed PROGRAM
> > > > > >     PROGRAM       program to execute (true if exec returned with 0)
> > > > > 
> > > > > So don't match on a string value here?  Hm, would that make writing
> > > > > programs easier?  At first glance it might.  It also might be a bit
> > > > > easier to understand.
> > > > 
> > > > What kind of string value do you mean?
> > > 
> > > Sorry, I meant the string return value of the script.  Like I had to
> > > hack "good" and "bad" as return values of the name_cd script.  The ID=
> > > stuff.
> > 
> > I'm thinking of:
> > 
> > PROGRAM= is true when it exits successful
> > RESULT= is compared with the returned string, but it is not neccessary
> > like todays ID= if the exit code it enough.
> > Just exit with nonzero in your name_cd - no "good" or "bad" :)
> 
> Ah, that's much nicer, and pretty sane.

Oh, it needed only a few hours, not days :)
First look at the new config. Just to get a idea.
I will cleanup the beast tomorrow, it's 6am now.

The udev-test.pl runs with 0 errors :)

thanks,
Kay


[-- Attachment #2: 00-config-change.diff --]
[-- Type: text/plain, Size: 19867 bytes --]

===== namedev.c 1.83 vs edited =====
--- 1.83/namedev.c	Thu Jan  8 20:05:25 2004
+++ edited/namedev.c	Sat Jan 10 06:18:42 2004
@@ -298,27 +298,6 @@
 	return; /* here to prevent compiler warning... */
 }
 
-static int do_ignore(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-	struct list_head *tmp;
-
-	list_for_each(tmp, &config_device_list) {
-		dev = list_entry(tmp, struct config_device, node);
-		if (dev->type != IGNORE)
-			continue;
-
-		dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
-		if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0)
-			continue;
-
-		dbg("found name, '%s' will be ignored", dev->kernel_name);
-
-		return 0;
-	}
-	return -ENODEV;
-}
-
 static int exec_program(char *path, char *value, int len)
 {
 	int retval;
@@ -332,7 +311,7 @@
 	char *args[CALLOUT_MAXARG];
 	int i;
 
-	dbg("callout to '%s'", path);
+	dbg("executing '%s'", path);
 	retval = pipe(fds);
 	if (retval != 0) {
 		dbg("pipe failed");
@@ -349,7 +328,7 @@
 		close(STDOUT_FILENO);
 		dup(fds[1]);	/* dup write side of pipe to STDOUT */
 		if (strchr(path, ' ')) {
-			/* callout with arguments */
+			/* exec with arguments */
 			pos = path;
 			for (i=0; i < CALLOUT_MAXARG-1; i++) {
 				args[i] = strsep(&pos, " ");
@@ -379,11 +358,11 @@
 				break;
 			buffer[res] = '\0';
 			if (res > len) {
-				dbg("callout len %d too short", len);
+				dbg("result len %d too short", len);
 				retval = -1;
 			}
 			if (value_set) {
-				dbg("callout value already set");
+				dbg("result value already set");
 				retval = -1;
 			} else {
 				value_set = 1;
@@ -391,7 +370,7 @@
 				pos = value + strlen(value)-1;
 				if (pos[0] == '\n')
 				pos[0] = '\0';
-				dbg("callout returned '%s'", value);
+				dbg("result is '%s'", value);
 			}
 		}
 		close(fds[0]);
@@ -402,46 +381,14 @@
 		}
 
 		if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
-			dbg("callout program status 0x%x", status);
+			dbg("exec program status 0x%x", status);
 			retval = -1;
 		}
 	}
 	return retval;
 }
 
-static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != CALLOUT)
-			continue;
-
-		if (dev->bus[0] != '\0') {
-			/* as the user specified a bus, we must match it up */
-			if (!sysfs_device)
-				continue;
-			dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-			if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-				continue;
-		}
-
-		/* substitute anything that needs to be in the program name */
-		apply_format(udev, dev->exec_program);
-		if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE))
-			continue;
-		if (strcmp_pattern(dev->id, udev->callout_value) != 0)
-			continue;
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("callout returned matching value '%s', '%s' becomes '%s'",
-		    dev->id, class_dev->name, udev->name);
-		return 0;
-	}
-	return -ENODEV;
-}
-
-static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
+static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
 {
 	struct sysfs_attribute *tmpattr = NULL;
 	char *c;
@@ -461,7 +408,6 @@
 		if (tmpattr)
 			goto label_found;
 	}
-
 	return -ENODEV;
 
 label_found:
@@ -478,53 +424,26 @@
 	return 0;
 }
 
-static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
 	struct sysfs_pair *pair;
-	struct config_device *dev;
 	int i;
-	int match;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != LABEL)
-			continue;
-
-		if (dev->bus[0] != '\0') {
-			/* as the user specified a bus, we must match it up */
-			if (!sysfs_device)
-				continue;
-			dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-			if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-				continue;
-		}
 
-		match = 1;
-		for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
-			pair = &dev->sysfs_pair[i];
-			if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
-				break;
-			if (match_pair(class_dev, sysfs_device, pair) != 0) {
-				match = 0;
-				break;
-			}
+	for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
+		pair = &dev->sysfs_pair[i];
+		if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
+			break;
+		if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
+			dbg("sysfs attribute doesn't match");
+			return -ENODEV;
 		}
-		if (match == 0)
-			continue;
-
-		/* found match */
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching attribute, '%s' becomes '%s' ",
-		    class_dev->name, udev->name);
-
-		return 0;
 	}
-	return -ENODEV;
+
+	return 0;
 }
 
-static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
-	struct config_device *dev;
 	char path[SYSFS_PATH_MAX];
 	int found;
 	char *temp = NULL;
@@ -533,107 +452,56 @@
 	if (!sysfs_device)
 		return -ENODEV;
 
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != NUMBER)
-			continue;
-
-		dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-		if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-			continue;
-
-		found = 0;
-		strfieldcpy(path, sysfs_device->path);
+	found = 0;
+	strfieldcpy(path, sysfs_device->path);
+	temp = strrchr(path, '/');
+	dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
+	if (strstr(temp, dev->id) != NULL) {
+		found = 1;
+	} else {
+		*temp = 0x00;
 		temp = strrchr(path, '/');
 		dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
-		if (strstr(temp, dev->id) != NULL) {
+		if (strstr(temp, dev->id) != NULL)
 			found = 1;
-		} else {
-			*temp = 0x00;
-			temp = strrchr(path, '/');
-			dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
-			if (strstr(temp, dev->id) != NULL)
-				found = 1;
-		}
-		if (!found)
-			continue;
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching id '%s', '%s' becomes '%s'",
-		    dev->id, class_dev->name, udev->name);
-		return 0;
 	}
-	return -ENODEV;
+	if (!found) {
+		dbg("id doesn't match");
+		return -ENODEV;
+	}
+
+	return 0;
 }
 
-static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
-	struct config_device *dev;
 	char path[SYSFS_PATH_MAX];
 	int found;
 	char *temp = NULL;
 
-	/* we have to have a sysfs device for TOPOLOGY to work */
+	/* we have to have a sysfs device for NUMBER to work */
 	if (!sysfs_device)
 		return -ENODEV;
 
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != TOPOLOGY)
-			continue;
-
-		dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-		if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-			continue;
-
-		found = 0;
-		strfieldcpy(path, sysfs_device->path);
+	found = 0;
+	strfieldcpy(path, sysfs_device->path);
+	temp = strrchr(path, '/');
+	dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
+	if (strstr(temp, dev->place) != NULL) {
+		found = 1;
+	} else {
+		*temp = 0x00;
 		temp = strrchr(path, '/');
 		dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
-		if (strstr(temp, dev->place) != NULL) {
+		if (strstr(temp, dev->place) != NULL)
 			found = 1;
-		} else {
-			*temp = 0x00;
-			temp = strrchr(path, '/');
-			dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
-			if (strstr(temp, dev->place) != NULL)
-				found = 1;
-		}
-		if (!found)
-			continue;
-
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching place '%s', '%s' becomes '%s'",
-		    dev->place, class_dev->name, udev->name);
-		return 0;
 	}
-	return -ENODEV;
-}
-
-static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != REPLACE)
-			continue;
-
-		dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
-		if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0)
-			continue;
-
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name);
-		
-		return 0;
+	if (!found) {
+		dbg("place doesn't match");
+		return -ENODEV;
 	}
-	return -ENODEV;
-}
 
-static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev)
-{
-	/* heh, this is pretty simple... */
-	strfieldcpy(udev->name, class_dev->name);
+	return 0;
 }
 
 static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev)
@@ -725,7 +593,7 @@
 int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev)
 {
 	struct sysfs_device *sysfs_device = NULL;
-	int retval = 0;
+	struct config_device *dev;
 	struct perm_device *perm;
 	char *pos;
 
@@ -752,34 +620,107 @@
 	strfieldcpy(udev->kernel_number, pos);
 	dbg("kernel_number='%s'", udev->kernel_number);
 
-	/* rules are looked at in priority order */
-	retval = do_ignore(class_dev, udev, sysfs_device);
-	if (retval == 0) {
-		dbg("name, '%s' is being ignored", class_dev->name);
-		return 1;
-	}
+	/* look for a matching rule to apply */
+	list_for_each_entry(dev, &config_device_list, node) {
 
-	retval = do_callout(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching bus value */
+		if (dev->bus[0] != '\0') {
+			if (sysfs_device == NULL) {
+				dbg("device has no bus");
+				continue;
+			}
+			dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
+			if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) {
+				dbg(FIELD_BUS " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_BUS " matches");
+			}
+		}
 
-	retval = do_label(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching kernel name*/
+		if (dev->kernel_name[0] != '\0') {
+			dbg("check for " FIELD_KERNEL " dev->kernel_name='%s' class_dev->name='%s'", dev->kernel_name, class_dev->name);
+			if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) {
+				dbg(FIELD_KERNEL " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_KERNEL " matches");
+			}
+		}
 
-	retval = do_number(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching sysfs pairs */
+		if (dev->sysfs_pair != NULL) {
+			dbg("check " FIELD_SYSFS " pairs");
+			if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_SYSFS " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_SYSFS " matches");
+			}
+		}
 
-	retval = do_topology(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching bus id */
+		if (dev->id[0] != '\0') {
+			dbg("check " FIELD_ID);
+			if (match_id(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_ID " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_ID " matches");
+			}
+		}
+
+		/* check for matching place of device */
+		if (dev->place[0] != '\0') {
+			dbg("check " FIELD_PLACE);
+			if (match_place(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_PLACE " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_PLACE " matches");
+			}
+		}
 
-	retval = do_replace(class_dev, udev, sysfs_device);
-	if (retval == 0)
+		/* execute external program */
+		if (dev->exec_program[0] != '\0') {
+			dbg("check " FIELD_PROGRAM);
+			if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE) != 0) {
+				dbg(FIELD_PROGRAM " returned nozero");
+				continue;
+			} else {
+				dbg(FIELD_PROGRAM " returned successful");
+			}
+		}
+
+		/* check for matching result of external program */
+		if (dev->exec_result[0] != '\0') {
+			dbg("check for " FIELD_RESULT
+			    " dev->exec_result='%s', udev->callout_value='%s'",
+			    dev->exec_result, udev->callout_value);
+			if (strcmp_pattern(dev->exec_result, udev->callout_value) != 0) {
+				dbg(FIELD_RESULT " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_RESULT " matches");
+			}
+		}
+
+		/* check if we are instructed to ignore this device */
+		if (dev->name[0] == '\0') {
+			dbg("instructed to ignore this device");
+			return -1;
+		}
+
+		/* Yup, this rule belongs to us! */
+		dbg("found matching rule, '%s' becomes '%s'", dev->kernel_name, udev->name);
+		strfieldcpy(udev->name, dev->name);
+		strfieldcpy(udev->symlink, dev->symlink);
 		goto found;
+	}
 
-	do_kernelname(class_dev, udev);
+	/* no rule was found so we use the kernel name */
+	strfieldcpy(udev->name, class_dev->name);
 	goto done;
 
 found:
===== namedev.h 1.18 vs edited =====
--- 1.18/namedev.h	Wed Dec 31 22:31:19 2003
+++ edited/namedev.h	Sat Jan 10 05:10:05 2004
@@ -28,17 +28,6 @@
 
 struct sysfs_class_device;
 
-
-enum config_type {
-	KERNEL_NAME	= 0,	/* must be 0 to let memset() default to this value */
-	LABEL		= 1,
-	NUMBER		= 2,
-	TOPOLOGY	= 3,
-	REPLACE		= 4,
-	CALLOUT		= 5,
-	IGNORE		= 6,
-};
-
 #define BUS_SIZE	30
 #define FILE_SIZE	50
 #define VALUE_SIZE	100
@@ -46,23 +35,17 @@
 #define PLACE_SIZE	50
 #define PROGRAM_SIZE	100
 
-#define TYPE_LABEL	"LABEL"
-#define TYPE_NUMBER	"NUMBER"
-#define TYPE_TOPOLOGY	"TOPOLOGY"
-#define TYPE_REPLACE	"REPLACE"
-#define TYPE_CALLOUT	"CALLOUT"
-#define TYPE_IGNORE	"IGNORE"
-
 #define FIELD_BUS	"BUS"
-#define FIELD_ID	"ID"
 #define FIELD_SYSFS	"SYSFS_"
+#define FIELD_ID	"ID"
 #define FIELD_PLACE	"PLACE"
 #define FIELD_PROGRAM	"PROGRAM"
+#define FIELD_RESULT	"RESULT"
 #define FIELD_KERNEL	"KERNEL"
 #define FIELD_NAME	"NAME"
 #define FIELD_SYMLINK	"SYMLINK"
 
-#define CALLOUT_MAXARG	8
+#define CALLOUT_MAXARG	10
 #define MAX_SYSFS_PAIRS	5
 
 struct sysfs_pair {
@@ -73,12 +56,12 @@
 struct config_device {
 	struct list_head node;
 
-	enum config_type type;
 	char bus[BUS_SIZE];
 	char id[ID_SIZE];
 	char place[PLACE_SIZE];
 	char kernel_name[NAME_SIZE];
 	char exec_program[PROGRAM_SIZE];
+	char exec_result[PROGRAM_SIZE];
 	char name[NAME_SIZE];
 	char symlink[NAME_SIZE];
 	struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
===== namedev_parse.c 1.18 vs edited =====
--- 1.18/namedev_parse.c	Wed Dec 31 22:30:55 2003
+++ edited/namedev_parse.c	Sat Jan 10 05:23:27 2004
@@ -23,6 +23,7 @@
 
 /* define this to enable parsing debugging */
 /* #define DEBUG_PARSER */
+#define DEBUG_PARSER
 
 #include <stddef.h>
 #include <stdlib.h>
@@ -86,37 +87,13 @@
 
 void dump_config_dev(struct config_device *dev)
 {
-	switch (dev->type) {
-	case KERNEL_NAME:
-		dbg_parse("KERNEL name='%s'", dev->name);
-		break;
-	case LABEL:
-		dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'",
-			  dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value);
-		break;
-	case NUMBER:
-		dbg_parse("NUMBER name='%s', bus='%s', id='%s'",
-			  dev->name, dev->bus, dev->id);
-		break;
-	case TOPOLOGY:
-		dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'",
-			  dev->name, dev->bus, dev->place);
-		break;
-	case REPLACE:
-		dbg_parse("REPLACE name='%s', kernel_name='%s'",
-			  dev->name, dev->kernel_name);
-		break;
-	case CALLOUT:
-		dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s'",
-			  dev->name, dev->bus, dev->exec_program, dev->id);
-		break;
-	case IGNORE:
-		dbg_parse("IGNORE name='%s', kernel_name='%s'",
-			  dev->name, dev->kernel_name);
-		break;
-	default:
-		dbg_parse("unknown type of method");
-	}
+	/*FIXME dump all sysfs's */
+	dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', "
+		  "sysfs_file[0]='%s', sysfs_value[0]='%s', "
+		  "kernel_name='%s', program='%s', result='%s'",
+		  dev->name, dev->symlink, dev->bus, dev->place, dev->id,
+		  dev->sysfs_pair[0].file, dev->sysfs_pair[0].value,
+		  dev->kernel_name, dev->exec_program, dev->exec_result);
 }
 
 void dump_config_dev_list(void)
@@ -185,42 +162,6 @@
 
 		memset(&dev, 0x00, sizeof(struct config_device));
 
-		/* get the method */
-		temp2 = strsep(&temp, ",");
-
-		if (strcasecmp(temp2, TYPE_LABEL) == 0) {
-			dev.type = LABEL;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_NUMBER) == 0) {
-			dev.type = NUMBER;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) {
-			dev.type = TOPOLOGY;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_REPLACE) == 0) {
-			dev.type = REPLACE;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_CALLOUT) == 0) {
-			dev.type = CALLOUT;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_IGNORE) == 0) {
-			dev.type = IGNORE;
-			goto keys;
-		}
-
-		dbg_parse("unknown type of method '%s'", temp2);
-		goto error;
-keys:
 		/* get all known keys */
 		while (1) {
 			retval = get_pair(&temp, &temp2, &temp3);
@@ -273,6 +214,11 @@
 				continue;
 			}
 
+			if (strcasecmp(temp2, FIELD_RESULT) == 0) {
+				strfieldcpy(dev.exec_result, temp3);
+				continue;
+			}
+
 			if (strcasecmp(temp2, FIELD_NAME) == 0) {
 				strfieldcpy(dev.name, temp3);
 				continue;
@@ -286,60 +232,16 @@
 			dbg_parse("unknown type of field '%s'", temp2);
 		}
 
-		/* check presence of keys according to method type */
-		switch (dev.type) {
-		case LABEL:
-			dbg_parse(TYPE_LABEL " name='%s', bus='%s', "
-				  "sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.sysfs_pair[0].file,
-				  dev.sysfs_pair[0].value, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.sysfs_pair[0].file == '\0') ||
-			    (*dev.sysfs_pair[0].value == '\0'))
-				goto error;
-			break;
-		case NUMBER:
-			dbg_parse(TYPE_NUMBER " name='%s', bus='%s', id='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.id, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.bus == '\0') ||
-			    (*dev.id == '\0'))
-				goto error;
-			break;
-		case TOPOLOGY:
-			dbg_parse(TYPE_TOPOLOGY " name='%s', bus='%s', "
-				  "place='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.place, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.bus == '\0') ||
-			    (*dev.place == '\0'))
-				goto error;
-			break;
-		case REPLACE:
-			dbg_parse(TYPE_REPLACE " name='%s', kernel_name='%s', symlink='%s'",
-				  dev.name, dev.kernel_name, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.kernel_name == '\0'))
-				goto error;
-			break;
-		case CALLOUT:
-			dbg_parse(TYPE_CALLOUT " name='%s', bus='%s', program='%s', "
-				  "id='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.exec_program,
-				  dev.id, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.id == '\0') ||
-			    (*dev.exec_program == '\0'))
-				goto error;
-			break;
-		case IGNORE:
-			dbg_parse(TYPE_IGNORE "name='%s', kernel_name='%s'",
-				  dev.name, dev.kernel_name);
-			if ((*dev.kernel_name == '\0'))
-				goto error;
-			break;
-		default:
-			dbg_parse("unknown type of method");
+		/* simple key plausibility check for given keys */
+		if ((dev.sysfs_pair[0].file[0] == '\0') ^
+		    (dev.sysfs_pair[0].value[0] == '\0')) {
+			dbg("inconsistency in SYSFS_ key");
+			goto error;
+		}
+
+		if ((dev.exec_result[0] != '\0') &&
+		    (dev.exec_program[0] == '\0')) {
+			dbg("RESULT is only useful when PROGRAM is set");
 			goto error;
 		}
 

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

* Re: udev - question about current config format
  2004-01-09 14:21 udev - question about current config format Kay Sievers
                   ` (5 preceding siblings ...)
  2004-01-10  5:27 ` Kay Sievers
@ 2004-01-10  5:39 ` Kay Sievers
  6 siblings, 0 replies; 8+ messages in thread
From: Kay Sievers @ 2004-01-10  5:39 UTC (permalink / raw)
  To: linux-hotplug

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

On Sat, Jan 10, 2004 at 06:27:24AM +0100, Kay Sievers wrote:
> On Fri, Jan 09, 2004 at 08:03:42PM -0800, Greg KH wrote:
> > On Sat, Jan 10, 2004 at 05:01:31AM +0100, Kay Sievers wrote:
> > > On Fri, Jan 09, 2004 at 07:52:43PM -0800, Greg KH wrote:
> > > > On Sat, Jan 10, 2004 at 02:38:50AM +0100, Kay Sievers wrote:
> > > > > On Fri, Jan 09, 2004 at 05:30:20PM -0800, Greg KH wrote:
> > > > > > On Fri, Jan 09, 2004 at 03:21:12PM +0100, Kay Sievers wrote:
> > > > > > >   Every line in udev.rules consists only of a number of <key>="<value>"
> > > > > > > 
> > > > > > >     BUS           match with bus type
> > > > > > >     SYSFS_<file>  match with device attribute
> > > > > > >     ID/PLACE      match with bus "number" or "id"
> > > > > > >     KERNEL        match with kernel device name
> > > > > > >     RESULT        match with string returned by executed PROGRAM
> > > > > > >     PROGRAM       program to execute (true if exec returned with 0)
> > > > > > 
> > > > > > So don't match on a string value here?  Hm, would that make writing
> > > > > > programs easier?  At first glance it might.  It also might be a bit
> > > > > > easier to understand.
> > > > > 
> > > > > What kind of string value do you mean?
> > > > 
> > > > Sorry, I meant the string return value of the script.  Like I had to
> > > > hack "good" and "bad" as return values of the name_cd script.  The ID=
> > > > stuff.
> > > 
> > > I'm thinking of:
> > > 
> > > PROGRAM= is true when it exits successful
> > > RESULT= is compared with the returned string, but it is not neccessary
> > > like todays ID= if the exit code it enough.
> > > Just exit with nonzero in your name_cd - no "good" or "bad" :)
> > 
> > Ah, that's much nicer, and pretty sane.
> 
> Oh, it needed only a few hours, not days :)
> First look at the new config. Just to get a idea.
> I will cleanup the beast tomorrow, it's 6am now.
> 
> The udev-test.pl runs with 0 errors :)

New patch.
The new udev-test.pl was not included.

thanks,
Kay

[-- Attachment #2: 00-config-change.diff --]
[-- Type: text/plain, Size: 31227 bytes --]

diff -Nru a/namedev.c b/namedev.c
--- a/namedev.c	Sat Jan 10 06:34:21 2004
+++ b/namedev.c	Sat Jan 10 06:34:21 2004
@@ -298,27 +298,6 @@
 	return; /* here to prevent compiler warning... */
 }
 
-static int do_ignore(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-	struct list_head *tmp;
-
-	list_for_each(tmp, &config_device_list) {
-		dev = list_entry(tmp, struct config_device, node);
-		if (dev->type != IGNORE)
-			continue;
-
-		dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
-		if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0)
-			continue;
-
-		dbg("found name, '%s' will be ignored", dev->kernel_name);
-
-		return 0;
-	}
-	return -ENODEV;
-}
-
 static int exec_program(char *path, char *value, int len)
 {
 	int retval;
@@ -332,7 +311,7 @@
 	char *args[CALLOUT_MAXARG];
 	int i;
 
-	dbg("callout to '%s'", path);
+	dbg("executing '%s'", path);
 	retval = pipe(fds);
 	if (retval != 0) {
 		dbg("pipe failed");
@@ -349,7 +328,7 @@
 		close(STDOUT_FILENO);
 		dup(fds[1]);	/* dup write side of pipe to STDOUT */
 		if (strchr(path, ' ')) {
-			/* callout with arguments */
+			/* exec with arguments */
 			pos = path;
 			for (i=0; i < CALLOUT_MAXARG-1; i++) {
 				args[i] = strsep(&pos, " ");
@@ -379,11 +358,11 @@
 				break;
 			buffer[res] = '\0';
 			if (res > len) {
-				dbg("callout len %d too short", len);
+				dbg("result len %d too short", len);
 				retval = -1;
 			}
 			if (value_set) {
-				dbg("callout value already set");
+				dbg("result value already set");
 				retval = -1;
 			} else {
 				value_set = 1;
@@ -391,7 +370,7 @@
 				pos = value + strlen(value)-1;
 				if (pos[0] == '\n')
 				pos[0] = '\0';
-				dbg("callout returned '%s'", value);
+				dbg("result is '%s'", value);
 			}
 		}
 		close(fds[0]);
@@ -402,46 +381,14 @@
 		}
 
 		if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
-			dbg("callout program status 0x%x", status);
+			dbg("exec program status 0x%x", status);
 			retval = -1;
 		}
 	}
 	return retval;
 }
 
-static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != CALLOUT)
-			continue;
-
-		if (dev->bus[0] != '\0') {
-			/* as the user specified a bus, we must match it up */
-			if (!sysfs_device)
-				continue;
-			dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-			if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-				continue;
-		}
-
-		/* substitute anything that needs to be in the program name */
-		apply_format(udev, dev->exec_program);
-		if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE))
-			continue;
-		if (strcmp_pattern(dev->id, udev->callout_value) != 0)
-			continue;
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("callout returned matching value '%s', '%s' becomes '%s'",
-		    dev->id, class_dev->name, udev->name);
-		return 0;
-	}
-	return -ENODEV;
-}
-
-static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
+static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair)
 {
 	struct sysfs_attribute *tmpattr = NULL;
 	char *c;
@@ -461,7 +408,6 @@
 		if (tmpattr)
 			goto label_found;
 	}
-
 	return -ENODEV;
 
 label_found:
@@ -478,53 +424,26 @@
 	return 0;
 }
 
-static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
 	struct sysfs_pair *pair;
-	struct config_device *dev;
 	int i;
-	int match;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != LABEL)
-			continue;
-
-		if (dev->bus[0] != '\0') {
-			/* as the user specified a bus, we must match it up */
-			if (!sysfs_device)
-				continue;
-			dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-			if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-				continue;
-		}
 
-		match = 1;
-		for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
-			pair = &dev->sysfs_pair[i];
-			if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
-				break;
-			if (match_pair(class_dev, sysfs_device, pair) != 0) {
-				match = 0;
-				break;
-			}
+	for (i = 0; i < MAX_SYSFS_PAIRS; ++i) {
+		pair = &dev->sysfs_pair[i];
+		if ((pair->file[0] == '\0') || (pair->value[0] == '\0'))
+			break;
+		if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) {
+			dbg("sysfs attribute doesn't match");
+			return -ENODEV;
 		}
-		if (match == 0)
-			continue;
-
-		/* found match */
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching attribute, '%s' becomes '%s' ",
-		    class_dev->name, udev->name);
-
-		return 0;
 	}
-	return -ENODEV;
+
+	return 0;
 }
 
-static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
-	struct config_device *dev;
 	char path[SYSFS_PATH_MAX];
 	int found;
 	char *temp = NULL;
@@ -533,107 +452,56 @@
 	if (!sysfs_device)
 		return -ENODEV;
 
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != NUMBER)
-			continue;
-
-		dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-		if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-			continue;
-
-		found = 0;
-		strfieldcpy(path, sysfs_device->path);
+	found = 0;
+	strfieldcpy(path, sysfs_device->path);
+	temp = strrchr(path, '/');
+	dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
+	if (strstr(temp, dev->id) != NULL) {
+		found = 1;
+	} else {
+		*temp = 0x00;
 		temp = strrchr(path, '/');
 		dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
-		if (strstr(temp, dev->id) != NULL) {
+		if (strstr(temp, dev->id) != NULL)
 			found = 1;
-		} else {
-			*temp = 0x00;
-			temp = strrchr(path, '/');
-			dbg("search '%s' in '%s', path='%s'", dev->id, temp, path);
-			if (strstr(temp, dev->id) != NULL)
-				found = 1;
-		}
-		if (!found)
-			continue;
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching id '%s', '%s' becomes '%s'",
-		    dev->id, class_dev->name, udev->name);
-		return 0;
 	}
-	return -ENODEV;
+	if (!found) {
+		dbg("id doesn't match");
+		return -ENODEV;
+	}
+
+	return 0;
 }
 
-static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
+static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
 {
-	struct config_device *dev;
 	char path[SYSFS_PATH_MAX];
 	int found;
 	char *temp = NULL;
 
-	/* we have to have a sysfs device for TOPOLOGY to work */
+	/* we have to have a sysfs device for NUMBER to work */
 	if (!sysfs_device)
 		return -ENODEV;
 
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != TOPOLOGY)
-			continue;
-
-		dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
-		if (strcasecmp(dev->bus, sysfs_device->bus) != 0)
-			continue;
-
-		found = 0;
-		strfieldcpy(path, sysfs_device->path);
+	found = 0;
+	strfieldcpy(path, sysfs_device->path);
+	temp = strrchr(path, '/');
+	dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
+	if (strstr(temp, dev->place) != NULL) {
+		found = 1;
+	} else {
+		*temp = 0x00;
 		temp = strrchr(path, '/');
 		dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
-		if (strstr(temp, dev->place) != NULL) {
+		if (strstr(temp, dev->place) != NULL)
 			found = 1;
-		} else {
-			*temp = 0x00;
-			temp = strrchr(path, '/');
-			dbg("search '%s' in '%s', path='%s'", dev->place, temp, path);
-			if (strstr(temp, dev->place) != NULL)
-				found = 1;
-		}
-		if (!found)
-			continue;
-
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found matching place '%s', '%s' becomes '%s'",
-		    dev->place, class_dev->name, udev->name);
-		return 0;
 	}
-	return -ENODEV;
-}
-
-static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device)
-{
-	struct config_device *dev;
-
-	list_for_each_entry(dev, &config_device_list, node) {
-		if (dev->type != REPLACE)
-			continue;
-
-		dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name);
-		if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0)
-			continue;
-
-		strfieldcpy(udev->name, dev->name);
-		strfieldcpy(udev->symlink, dev->symlink);
-		dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name);
-		
-		return 0;
+	if (!found) {
+		dbg("place doesn't match");
+		return -ENODEV;
 	}
-	return -ENODEV;
-}
 
-static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev)
-{
-	/* heh, this is pretty simple... */
-	strfieldcpy(udev->name, class_dev->name);
+	return 0;
 }
 
 static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev)
@@ -725,7 +593,7 @@
 int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev)
 {
 	struct sysfs_device *sysfs_device = NULL;
-	int retval = 0;
+	struct config_device *dev;
 	struct perm_device *perm;
 	char *pos;
 
@@ -752,34 +620,107 @@
 	strfieldcpy(udev->kernel_number, pos);
 	dbg("kernel_number='%s'", udev->kernel_number);
 
-	/* rules are looked at in priority order */
-	retval = do_ignore(class_dev, udev, sysfs_device);
-	if (retval == 0) {
-		dbg("name, '%s' is being ignored", class_dev->name);
-		return 1;
-	}
+	/* look for a matching rule to apply */
+	list_for_each_entry(dev, &config_device_list, node) {
 
-	retval = do_callout(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching bus value */
+		if (dev->bus[0] != '\0') {
+			if (sysfs_device == NULL) {
+				dbg("device has no bus");
+				continue;
+			}
+			dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus);
+			if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) {
+				dbg(FIELD_BUS " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_BUS " matches");
+			}
+		}
 
-	retval = do_label(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching kernel name*/
+		if (dev->kernel_name[0] != '\0') {
+			dbg("check for " FIELD_KERNEL " dev->kernel_name='%s' class_dev->name='%s'", dev->kernel_name, class_dev->name);
+			if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) {
+				dbg(FIELD_KERNEL " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_KERNEL " matches");
+			}
+		}
 
-	retval = do_number(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching sysfs pairs */
+		if (dev->sysfs_pair != NULL) {
+			dbg("check " FIELD_SYSFS " pairs");
+			if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_SYSFS " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_SYSFS " matches");
+			}
+		}
 
-	retval = do_topology(class_dev, udev, sysfs_device);
-	if (retval == 0)
-		goto found;
+		/* check for matching bus id */
+		if (dev->id[0] != '\0') {
+			dbg("check " FIELD_ID);
+			if (match_id(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_ID " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_ID " matches");
+			}
+		}
+
+		/* check for matching place of device */
+		if (dev->place[0] != '\0') {
+			dbg("check " FIELD_PLACE);
+			if (match_place(dev, class_dev, sysfs_device) != 0) {
+				dbg(FIELD_PLACE " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_PLACE " matches");
+			}
+		}
 
-	retval = do_replace(class_dev, udev, sysfs_device);
-	if (retval == 0)
+		/* execute external program */
+		if (dev->exec_program[0] != '\0') {
+			dbg("check " FIELD_PROGRAM);
+			if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE) != 0) {
+				dbg(FIELD_PROGRAM " returned nozero");
+				continue;
+			} else {
+				dbg(FIELD_PROGRAM " returned successful");
+			}
+		}
+
+		/* check for matching result of external program */
+		if (dev->exec_result[0] != '\0') {
+			dbg("check for " FIELD_RESULT
+			    " dev->exec_result='%s', udev->callout_value='%s'",
+			    dev->exec_result, udev->callout_value);
+			if (strcmp_pattern(dev->exec_result, udev->callout_value) != 0) {
+				dbg(FIELD_RESULT " is not matching");
+				continue;
+			} else {
+				dbg(FIELD_RESULT " matches");
+			}
+		}
+
+		/* check if we are instructed to ignore this device */
+		if (dev->name[0] == '\0') {
+			dbg("instructed to ignore this device");
+			return -1;
+		}
+
+		/* Yup, this rule belongs to us! */
+		dbg("found matching rule, '%s' becomes '%s'", dev->kernel_name, udev->name);
+		strfieldcpy(udev->name, dev->name);
+		strfieldcpy(udev->symlink, dev->symlink);
 		goto found;
+	}
 
-	do_kernelname(class_dev, udev);
+	/* no rule was found so we use the kernel name */
+	strfieldcpy(udev->name, class_dev->name);
 	goto done;
 
 found:
diff -Nru a/namedev.h b/namedev.h
--- a/namedev.h	Sat Jan 10 06:34:21 2004
+++ b/namedev.h	Sat Jan 10 06:34:21 2004
@@ -28,17 +28,6 @@
 
 struct sysfs_class_device;
 
-
-enum config_type {
-	KERNEL_NAME	= 0,	/* must be 0 to let memset() default to this value */
-	LABEL		= 1,
-	NUMBER		= 2,
-	TOPOLOGY	= 3,
-	REPLACE		= 4,
-	CALLOUT		= 5,
-	IGNORE		= 6,
-};
-
 #define BUS_SIZE	30
 #define FILE_SIZE	50
 #define VALUE_SIZE	100
@@ -46,23 +35,17 @@
 #define PLACE_SIZE	50
 #define PROGRAM_SIZE	100
 
-#define TYPE_LABEL	"LABEL"
-#define TYPE_NUMBER	"NUMBER"
-#define TYPE_TOPOLOGY	"TOPOLOGY"
-#define TYPE_REPLACE	"REPLACE"
-#define TYPE_CALLOUT	"CALLOUT"
-#define TYPE_IGNORE	"IGNORE"
-
 #define FIELD_BUS	"BUS"
-#define FIELD_ID	"ID"
 #define FIELD_SYSFS	"SYSFS_"
+#define FIELD_ID	"ID"
 #define FIELD_PLACE	"PLACE"
 #define FIELD_PROGRAM	"PROGRAM"
+#define FIELD_RESULT	"RESULT"
 #define FIELD_KERNEL	"KERNEL"
 #define FIELD_NAME	"NAME"
 #define FIELD_SYMLINK	"SYMLINK"
 
-#define CALLOUT_MAXARG	8
+#define CALLOUT_MAXARG	10
 #define MAX_SYSFS_PAIRS	5
 
 struct sysfs_pair {
@@ -73,12 +56,12 @@
 struct config_device {
 	struct list_head node;
 
-	enum config_type type;
 	char bus[BUS_SIZE];
 	char id[ID_SIZE];
 	char place[PLACE_SIZE];
 	char kernel_name[NAME_SIZE];
 	char exec_program[PROGRAM_SIZE];
+	char exec_result[PROGRAM_SIZE];
 	char name[NAME_SIZE];
 	char symlink[NAME_SIZE];
 	struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS];
diff -Nru a/namedev_parse.c b/namedev_parse.c
--- a/namedev_parse.c	Sat Jan 10 06:34:21 2004
+++ b/namedev_parse.c	Sat Jan 10 06:34:21 2004
@@ -23,6 +23,7 @@
 
 /* define this to enable parsing debugging */
 /* #define DEBUG_PARSER */
+#define DEBUG_PARSER
 
 #include <stddef.h>
 #include <stdlib.h>
@@ -86,37 +87,13 @@
 
 void dump_config_dev(struct config_device *dev)
 {
-	switch (dev->type) {
-	case KERNEL_NAME:
-		dbg_parse("KERNEL name='%s'", dev->name);
-		break;
-	case LABEL:
-		dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'",
-			  dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value);
-		break;
-	case NUMBER:
-		dbg_parse("NUMBER name='%s', bus='%s', id='%s'",
-			  dev->name, dev->bus, dev->id);
-		break;
-	case TOPOLOGY:
-		dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'",
-			  dev->name, dev->bus, dev->place);
-		break;
-	case REPLACE:
-		dbg_parse("REPLACE name='%s', kernel_name='%s'",
-			  dev->name, dev->kernel_name);
-		break;
-	case CALLOUT:
-		dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s'",
-			  dev->name, dev->bus, dev->exec_program, dev->id);
-		break;
-	case IGNORE:
-		dbg_parse("IGNORE name='%s', kernel_name='%s'",
-			  dev->name, dev->kernel_name);
-		break;
-	default:
-		dbg_parse("unknown type of method");
-	}
+	/*FIXME dump all sysfs's */
+	dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', "
+		  "sysfs_file[0]='%s', sysfs_value[0]='%s', "
+		  "kernel_name='%s', program='%s', result='%s'",
+		  dev->name, dev->symlink, dev->bus, dev->place, dev->id,
+		  dev->sysfs_pair[0].file, dev->sysfs_pair[0].value,
+		  dev->kernel_name, dev->exec_program, dev->exec_result);
 }
 
 void dump_config_dev_list(void)
@@ -185,42 +162,6 @@
 
 		memset(&dev, 0x00, sizeof(struct config_device));
 
-		/* get the method */
-		temp2 = strsep(&temp, ",");
-
-		if (strcasecmp(temp2, TYPE_LABEL) == 0) {
-			dev.type = LABEL;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_NUMBER) == 0) {
-			dev.type = NUMBER;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) {
-			dev.type = TOPOLOGY;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_REPLACE) == 0) {
-			dev.type = REPLACE;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_CALLOUT) == 0) {
-			dev.type = CALLOUT;
-			goto keys;
-		}
-
-		if (strcasecmp(temp2, TYPE_IGNORE) == 0) {
-			dev.type = IGNORE;
-			goto keys;
-		}
-
-		dbg_parse("unknown type of method '%s'", temp2);
-		goto error;
-keys:
 		/* get all known keys */
 		while (1) {
 			retval = get_pair(&temp, &temp2, &temp3);
@@ -273,6 +214,11 @@
 				continue;
 			}
 
+			if (strcasecmp(temp2, FIELD_RESULT) == 0) {
+				strfieldcpy(dev.exec_result, temp3);
+				continue;
+			}
+
 			if (strcasecmp(temp2, FIELD_NAME) == 0) {
 				strfieldcpy(dev.name, temp3);
 				continue;
@@ -286,60 +232,16 @@
 			dbg_parse("unknown type of field '%s'", temp2);
 		}
 
-		/* check presence of keys according to method type */
-		switch (dev.type) {
-		case LABEL:
-			dbg_parse(TYPE_LABEL " name='%s', bus='%s', "
-				  "sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.sysfs_pair[0].file,
-				  dev.sysfs_pair[0].value, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.sysfs_pair[0].file == '\0') ||
-			    (*dev.sysfs_pair[0].value == '\0'))
-				goto error;
-			break;
-		case NUMBER:
-			dbg_parse(TYPE_NUMBER " name='%s', bus='%s', id='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.id, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.bus == '\0') ||
-			    (*dev.id == '\0'))
-				goto error;
-			break;
-		case TOPOLOGY:
-			dbg_parse(TYPE_TOPOLOGY " name='%s', bus='%s', "
-				  "place='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.place, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.bus == '\0') ||
-			    (*dev.place == '\0'))
-				goto error;
-			break;
-		case REPLACE:
-			dbg_parse(TYPE_REPLACE " name='%s', kernel_name='%s', symlink='%s'",
-				  dev.name, dev.kernel_name, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.kernel_name == '\0'))
-				goto error;
-			break;
-		case CALLOUT:
-			dbg_parse(TYPE_CALLOUT " name='%s', bus='%s', program='%s', "
-				  "id='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.exec_program,
-				  dev.id, dev.symlink);
-			if ((*dev.name == '\0') ||
-			    (*dev.id == '\0') ||
-			    (*dev.exec_program == '\0'))
-				goto error;
-			break;
-		case IGNORE:
-			dbg_parse(TYPE_IGNORE "name='%s', kernel_name='%s'",
-				  dev.name, dev.kernel_name);
-			if ((*dev.kernel_name == '\0'))
-				goto error;
-			break;
-		default:
-			dbg_parse("unknown type of method");
+		/* simple plausibility check for given keys */
+		if ((dev.sysfs_pair[0].file[0] == '\0') ^
+		    (dev.sysfs_pair[0].value[0] == '\0')) {
+			dbg("inconsistency in SYSFS_ key");
+			goto error;
+		}
+
+		if ((dev.exec_result[0] != '\0') &&
+		    (dev.exec_program[0] == '\0')) {
+			dbg("RESULT is only useful when PROGRAM is set");
 			goto error;
 		}
 
diff -Nru a/test/udev-test.pl b/test/udev-test.pl
--- a/test/udev-test.pl	Sat Jan 10 06:34:21 2004
+++ b/test/udev-test.pl	Sat Jan 10 06:34:21 2004
@@ -38,8 +38,8 @@
 		devpath  => "block/sda",
 		expected => "boot_disk" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
-REPLACE, KERNEL="ttyUSB0", NAME="visor"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
+KERNEL="ttyUSB0", NAME="visor"
 EOF
 	},
 	{
@@ -48,7 +48,7 @@
 		devpath  => "block/sda/sda1",
 		expected => "boot_disk1" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
 EOF
 	},
 	{
@@ -57,10 +57,10 @@
 		devpath  => "block/sda/sda1",
 		expected => "boot_disk1" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="?IBM-ESXS", NAME="boot_disk%n-1"
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS?", NAME="boot_disk%n-2"
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ES??", NAME="boot_disk%n"
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXSS", NAME="boot_disk%n-3"
+BUS="scsi", SYSFS_vendor="?IBM-ESXS", NAME="boot_disk%n-1"
+BUS="scsi", SYSFS_vendor="IBM-ESXS?", NAME="boot_disk%n-2"
+BUS="scsi", SYSFS_vendor="IBM-ES??", NAME="boot_disk%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXSS", NAME="boot_disk%n-3"
 EOF
 	},
 	{
@@ -69,8 +69,8 @@
 		devpath  => "block/sda/sda1",
 		expected => "boot_disk1" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW   !#", NAME="boot_diskX%n"
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", NAME="boot_disk%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW   !#", NAME="boot_diskX%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", NAME="boot_disk%n"
 EOF
 	},
 	{
@@ -79,8 +79,8 @@
 		devpath  => "block/sda/sda1",
 		expected => "boot_disk1" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", SYSFS_scsi_level="4", SYSFS_rev="B245", SYSFS_type="2", SYSFS_queue_depth="32", NAME="boot_diskXX%n"
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", SYSFS_scsi_level="4", SYSFS_rev="B245", SYSFS_type="0", NAME="boot_disk%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", SYSFS_scsi_level="4", SYSFS_rev="B245", SYSFS_type="2", SYSFS_queue_depth="32", NAME="boot_diskXX%n"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW    !#", SYSFS_scsi_level="4", SYSFS_rev="B245", SYSFS_type="0", NAME="boot_disk%n"
 EOF
 	},
 	{
@@ -89,7 +89,7 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "visor/0" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB*", NAME="visor/%n"
+KERNEL="ttyUSB*", NAME="visor/%n"
 EOF
 	},
 	{
@@ -98,9 +98,9 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "visor/0" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB??*", NAME="visor/%n-1"
-REPLACE, KERNEL="ttyUSB??", NAME="visor/%n-2"
-REPLACE, KERNEL="ttyUSB?", NAME="visor/%n"
+KERNEL="ttyUSB??*", NAME="visor/%n-1"
+KERNEL="ttyUSB??", NAME="visor/%n-2"
+KERNEL="ttyUSB?", NAME="visor/%n"
 EOF
 	},
 	{
@@ -109,9 +109,9 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "visor/0" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB[A-Z]*", NAME="visor/%n-1"
-REPLACE, KERNEL="ttyUSB?[0-9]", NAME="visor/%n-2"
-REPLACE, KERNEL="ttyUSB[0-9]*", NAME="visor/%n"
+KERNEL="ttyUSB[A-Z]*", NAME="visor/%n-1"
+KERNEL="ttyUSB?[0-9]", NAME="visor/%n-2"
+KERNEL="ttyUSB[0-9]*", NAME="visor/%n"
 EOF
 	},
 	{
@@ -120,7 +120,7 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "visor" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB0", NAME="visor"
+KERNEL="ttyUSB0", NAME="visor"
 EOF
 	},
 	{
@@ -130,7 +130,7 @@
 		expected => "visor" ,
 		conf     => <<EOF
 # this is a comment
-REPLACE, KERNEL="ttyUSB0", NAME="visor"
+KERNEL="ttyUSB0", NAME="visor"
 
 EOF
 	},
@@ -141,7 +141,7 @@
 		expected => "visor" ,
 		conf     => <<EOF
  # this is a comment with whitespace before the comment 
-REPLACE, KERNEL="ttyUSB0", NAME="visor"
+KERNEL="ttyUSB0", NAME="visor"
 
 EOF
 	},
@@ -152,7 +152,7 @@
 		expected => "visor" ,
 		conf     => <<EOF
 
-REPLACE, KERNEL="ttyUSB0", NAME="visor"
+KERNEL="ttyUSB0", NAME="visor"
 
 EOF
 	},
@@ -162,7 +162,7 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "sub/direct/ory/visor" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB0", NAME="sub/direct/ory/visor"
+KERNEL="ttyUSB0", NAME="sub/direct/ory/visor"
 EOF
 	},
 	{
@@ -171,7 +171,7 @@
 		devpath  => "block/sda/sda3",
 		expected => "first_disk3" ,
 		conf     => <<EOF
-TOPOLOGY, BUS="scsi", PLACE="0:0:0:0", NAME="first_disk%n"
+BUS="scsi", PLACE="0:0:0:0", NAME="first_disk%n"
 EOF
 	},
 	{
@@ -180,58 +180,58 @@
 		devpath  => "block/sda/sda3",
 		expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" ,
 		conf     => <<EOF
-TOPOLOGY, BUS="scsi", PLACE="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
+BUS="scsi", PLACE="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b"
 EOF
 	},
 	{
-		desc     => "callout result substitution",
+		desc     => "program result substitution",
 		subsys   => "block",
 		devpath  => "block/sda/sda3",
 		expected => "special-device-3" ,
 		conf     => <<EOF
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="-special-*", NAME="%c-1-%n"
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special--*", NAME="%c-2-%n"
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-device-", NAME="%c-3-%n"
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-devic", NAME="%c-4-%n"
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-*", NAME="%c-%n"
+BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="-special-*", NAME="%c-1-%n"
+BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special--*", NAME="%c-2-%n"
+BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-device-", NAME="%c-3-%n"
+BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-devic", NAME="%c-4-%n"
+BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-*", NAME="%c-%n"
 EOF
 	},
 	{
-		desc     => "callout program substitution",
+		desc     => "program result substitution",
 		subsys   => "block",
 		devpath  => "block/sda/sda3",
 		expected => "test-0:0:0:0" ,
 		conf     => <<EOF
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-*", NAME="%c"
+BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-*", NAME="%c"
 EOF
 	},
 	{
-		desc     => "callout program substitution (numbered part of)",
+		desc     => "program result substitution (numbered part of)",
 		subsys   => "block",
 		devpath  => "block/sda/sda3",
 		expected => "link1" ,
 		conf     => <<EOF
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME="%1c", SYMLINK="%2c %3c"
+BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", RESULT="node *", NAME="%1c", SYMLINK="%2c %3c"
 EOF
 	},
 	{
-		desc     => "invalid callout for device with no bus",
+		desc     => "invalid program for device with no bus",
 		subsys   => "tty",
 		devpath  => "class/tty/console",
 		expected => "TTY" ,
 		conf     => <<EOF
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n foo", ID="foo", NAME="foo"
-REPLACE, KERNEL="console", NAME="TTY"
+BUS="scsi", PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
+KERNEL="console", NAME="TTY"
 EOF
 	},
 	{
-		desc     => "valid callout for device with no bus",
+		desc     => "valid program for device with no bus",
 		subsys   => "tty",
 		devpath  => "class/tty/console",
 		expected => "foo" ,
 		conf     => <<EOF
-CALLOUT, PROGRAM="/bin/echo -n foo", ID="foo", NAME="foo"
-REPLACE, KERNEL="console", NAME="TTY"
+PROGRAM="/bin/echo -n foo", RESULT="foo", NAME="foo"
+KERNEL="console", NAME="TTY"
 EOF
 	},
 	{
@@ -240,8 +240,8 @@
 		devpath  => "class/tty/console",
 		expected => "TTY" ,
 		conf     => <<EOF
-LABEL, BUS="foo", SYSFS_dev="5:1", NAME="foo"
-REPLACE, KERNEL="console", NAME="TTY"
+BUS="foo", SYSFS_dev="5:1", NAME="foo"
+KERNEL="console", NAME="TTY"
 EOF
 	},
 	{
@@ -250,8 +250,8 @@
 		devpath  => "class/tty/console",
 		expected => "foo" ,
 		conf     => <<EOF
-LABEL, SYSFS_dev="5:1", NAME="foo"
-REPLACE, KERNEL="console", NAME="TTY"
+SYSFS_dev="5:1", NAME="foo"
+KERNEL="console", NAME="TTY"
 EOF
 	},
 	{
@@ -260,7 +260,7 @@
 		devpath  => "block/sda",
 		expected => "lun0/disc" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
 EOF
 	},
 	{
@@ -269,18 +269,18 @@
 		devpath  => "block/sda/sda2",
 		expected => "lun0/part2" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
 EOF
 	},
 	{
-		desc     => "callout bus type",
+		desc     => "program and bus type match",
 		subsys   => "block",
 		devpath  => "block/sda",
 		expected => "scsi-0:0:0:0" ,
 		conf     => <<EOF
-CALLOUT, BUS="usb", PROGRAM="/bin/echo -n usb-%b", ID="*", NAME="%c"
-CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n scsi-%b", ID="*", NAME="%c"
-CALLOUT, BUS="foo", PROGRAM="/bin/echo -n foo-%b", ID="*", NAME="%c"
+BUS="usb", PROGRAM="/bin/echo -n usb-%b", NAME="%c"
+BUS="scsi", PROGRAM="/bin/echo -n scsi-%b", NAME="%c"
+BUS="foo", PROGRAM="/bin/echo -n foo-%b", NAME="%c"
 EOF
 	},
 	{
@@ -289,7 +289,7 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "visor0" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="visor%n"
+KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n", SYMLINK="visor%n"
 EOF
 	},
 	{
@@ -298,7 +298,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/a/b/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/node", SYMLINK="1/2/a/b/symlink"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/node", SYMLINK="1/2/a/b/symlink"
 EOF
 	},
 	{
@@ -307,7 +307,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
 EOF
 	},
 	{
@@ -316,7 +316,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/c/d/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
+BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
 EOF
 	},
 	{
@@ -325,7 +325,7 @@
 		devpath  => "class/tty/ttyUSB0",
 		expected => "second-0" ,
 		conf     => <<EOF
-REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
+KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n"
 EOF
 	},
 );
@@ -368,11 +368,8 @@
 close CONF;
 
 foreach my $config (@tests) {
-	$config->{conf} =~ m/([A-Z]+)\s*,/;
-	my $method  = $1;
-
 	print "TEST: $config->{desc}\n";
-	print "method \'$method\' for \'$config->{devpath}\' expecting node \'$config->{expected}\'\n";
+	print "device \'$config->{devpath}\' expecting node \'$config->{expected}\'\n";
 
 	udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf});
 	if (-e "$PWD/$udev_root$config->{expected}") {
@@ -382,6 +379,7 @@
 		system("tree $udev_root");
 		print "\n";
 		$error++;
+		exit;
 	}
 
 	udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf});

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

end of thread, other threads:[~2004-01-10  5:39 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-01-09 14:21 udev - question about current config format Kay Sievers
2004-01-10  1:30 ` Greg KH
2004-01-10  1:38 ` Kay Sievers
2004-01-10  3:52 ` Greg KH
2004-01-10  4:01 ` Kay Sievers
2004-01-10  4:03 ` Greg KH
2004-01-10  5:27 ` Kay Sievers
2004-01-10  5:39 ` 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).