All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kay Sievers <kay.sievers@vrfy.org>
To: linux-hotplug@vger.kernel.org
Subject: Re: [udev] don't rely on field order in namedev_parse
Date: Tue, 16 Dec 2003 01:36:25 +0000	[thread overview]
Message-ID: <marc-linux-hotplug-107153877206763@msgid-missing> (raw)
In-Reply-To: <marc-linux-hotplug-107152798528161@msgid-missing>

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

On Mon, Dec 15, 2003 at 04:27:59PM -0800, Greg KH wrote:
> On Tue, Dec 16, 2003 at 01:21:58AM +0100, Kay Sievers wrote:
> > o prepend SYSFS_ to the match, like:
> >   LABEL, BUS="usb", SYSFS_model="Creative Labs WebCam*", NAME="video%n"
> >   This is my favorite. It's close to the current and says clearly what it does.
> 
> Yeah, I like this one too.

Here is a try.
Please have a look at it.

My motto of the day: Try to attach the patch before hitting the 'y'-key :)

Kay


01-remove-field-ordering.diff
  o change the parsing to get a key from the rule and sort it
    into our list of known keys instead of expecting a special order
  o the key to match a sysfs file must be prependend by 'SYSFS_' now
    to match with the new parsing.
    (The config must be changed, but it's a bit more descriptive too.)
  o put names of fields in define's, like the name of the methods
  o update all tests and the man page


[-- Attachment #2: 01-remove-field-ordering.diff --]
[-- Type: text/plain, Size: 14381 bytes --]

diff -Nru a/namedev.h b/namedev.h
--- a/namedev.h	Tue Dec 16 02:26:49 2003
+++ b/namedev.h	Tue Dec 16 02:26:49 2003
@@ -49,6 +49,16 @@
 #define TYPE_TOPOLOGY	"TOPOLOGY"
 #define TYPE_REPLACE	"REPLACE"
 #define TYPE_CALLOUT	"CALLOUT"
+
+#define FIELD_BUS	"BUS"
+#define FIELD_ID	"ID"
+#define FIELD_SYSFS	"SYSFS_"
+#define FIELD_PLACE	"PLACE"
+#define FIELD_PROGRAM	"PROGRAM"
+#define FIELD_KERNEL	"KERNEL"
+#define FIELD_NAME	"NAME"
+#define FIELD_SYMLINK	"SYMLINK"
+
 #define CALLOUT_MAXARG	8
 
 struct config_device {
diff -Nru a/namedev_parse.c b/namedev_parse.c
--- a/namedev_parse.c	Tue Dec 16 02:26:49 2003
+++ b/namedev_parse.c	Tue Dec 16 02:26:49 2003
@@ -45,7 +45,7 @@
 		return -ENODEV;
 
 	/* eat any whitespace */
-	while (isspace(*string))
+	while (isspace(*string) || *string == ',')
 		++string;
 
 	/* split based on '=' */
@@ -71,19 +71,6 @@
 	return 0;
 }
 
-static int get_value(const char *left, char **orig_string, char **ret_string)
-{
-	int retval;
-	char *left_string;
-
-	retval = get_pair(orig_string, &left_string, ret_string);
-	if (retval)
-		return retval;
-	if (strcasecmp(left_string, left) != 0)
-		return -ENODEV;
-	return 0;
-}
-
 void dump_config_dev(struct config_device *dev)
 {
 	switch (dev->type) {
@@ -169,13 +156,8 @@
 		if (temp == NULL)
 			goto exit;
 		lineno++;
-
 		dbg_parse("read '%s'", temp);
 
-		/* eat the whitespace at the beginning of the line */
-		while (isspace(*temp))
-			++temp;
-
 		/* empty line? */
 		if (*temp == 0x00)
 			continue;
@@ -184,199 +166,160 @@
 		if (*temp == COMMENT_CHARACTER)
 			continue;
 
+		/* eat the whitespace */
+		while (isspace(*temp))
+			++temp;
+
 		memset(&dev, 0x00, sizeof(struct config_device));
 
-		/* parse the line */
+		/* get the method */
 		temp2 = strsep(&temp, ",");
+
 		if (strcasecmp(temp2, TYPE_LABEL) == 0) {
-			/* label type */
 			dev.type = LABEL;
-
-			/* BUS="bus" */
-			retval = get_value("BUS", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.bus, temp3);
-
-			/* file="value" */
-			temp2 = strsep(&temp, ",");
-			retval = get_pair(&temp, &temp2, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.sysfs_file, temp2);
-			strfieldcpy(dev.sysfs_value, temp3);
-
-			/* NAME="new_name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("NAME", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.name, temp3);
-
-			/* SYMLINK="name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("SYMLINK", &temp, &temp3);
-			if (retval == 0)
-				strfieldcpy(dev.symlink, temp3);
-
-			dbg_parse("LABEL name='%s', bus='%s', "
-				  "sysfs_file='%s', sysfs_value='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.sysfs_file,
-				  dev.sysfs_value, dev.symlink);
+			goto keys;
 		}
 
 		if (strcasecmp(temp2, TYPE_NUMBER) == 0) {
-			/* number type */
 			dev.type = NUMBER;
-
-			/* BUS="bus" */
-			retval = get_value("BUS", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.bus, temp3);
-
-			/* ID="id" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("ID", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.id, temp3);
-
-			/* NAME="new_name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("NAME", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.name, temp3);
-
-			/* SYMLINK="name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("SYMLINK", &temp, &temp3);
-			if (retval == 0)
-				strfieldcpy(dev.symlink, temp3);
-
-			dbg_parse("NUMBER name='%s', bus='%s', id='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.id, dev.symlink);
+			goto keys;
 		}
 
 		if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) {
-			/* number type */
 			dev.type = TOPOLOGY;
-
-			/* BUS="bus" */
-			retval = get_value("BUS", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.bus, temp3);
-
-			/* PLACE="place" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("PLACE", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.place, temp3);
-
-			/* NAME="new_name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("NAME", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.name, temp3);
-
-			/* SYMLINK="name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("SYMLINK", &temp, &temp3);
-			if (retval == 0)
-				strfieldcpy(dev.symlink, temp3);
-
-			dbg_parse("TOPOLOGY name='%s', bus='%s', "
-				  "place='%s', symlink='%s'",
-				  dev.name, dev.bus, dev.place, dev.symlink);
+			goto keys;
 		}
 
 		if (strcasecmp(temp2, TYPE_REPLACE) == 0) {
-			/* number type */
 			dev.type = REPLACE;
-
-			/* KERNEL="kernel_name" */
-			retval = get_value("KERNEL", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.kernel_name, temp3);
-
-			/* NAME="new_name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("NAME", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.name, temp3);
-
-			/* SYMLINK="name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("SYMLINK", &temp, &temp3);
-			if (retval == 0)
-				strfieldcpy(dev.symlink, temp3);
-
-			dbg_parse("REPLACE name='%s', kernel_name='%s', symlink='%s'",
-				  dev.name, dev.kernel_name, dev.symlink);
+			goto keys;
 		}
 
 		if (strcasecmp(temp2, TYPE_CALLOUT) == 0) {
-			/* number type */
 			dev.type = CALLOUT;
+			goto keys;
+		}
 
-			/* BUS="bus" */
-			retval = get_value("BUS", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.bus, temp3);
-
-			/* PROGRAM="executable" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("PROGRAM", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.exec_program, temp3);
-
-			/* ID="id" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("ID", &temp, &temp3);
+		dbg_parse("unknown type of method '%s'", temp2);
+		goto error;
+keys:
+		/* get all known keys */
+		while (1) {
+			retval = get_pair(&temp, &temp2, &temp3);
 			if (retval)
 				break;
-			strfieldcpy(dev.id, temp3);
 
-			/* NAME="new_name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("NAME", &temp, &temp3);
-			if (retval)
-				break;
-			strfieldcpy(dev.name, temp3);
+			if (strcasecmp(temp2, FIELD_BUS) == 0) {
+				strfieldcpy(dev.bus, temp3);
+				continue;
+			}
+
+			if (strcasecmp(temp2, FIELD_ID) == 0) {
+				strfieldcpy(dev.id, temp3);
+				continue;
+			}
+
+			if (strcasecmp(temp2, FIELD_PLACE) == 0) {
+				strfieldcpy(dev.place, temp3);
+				continue;
+			}
+
+			if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) {
+				/* remove prepended 'SYSFS_' */
+				strfieldcpy(dev.sysfs_file, temp2 + sizeof(FIELD_SYSFS)-1);
+				strfieldcpy(dev.sysfs_value, temp3);
+				continue;
+			}
+
+			if (strcasecmp(temp2, FIELD_KERNEL) == 0) {
+				strfieldcpy(dev.kernel_name, temp3);
+				continue;
+			}
+
+			if (strcasecmp(temp2, FIELD_PROGRAM) == 0) {
+				strfieldcpy(dev.exec_program, temp3);
+				continue;
+			}
+
+			if (strcasecmp(temp2, FIELD_NAME) == 0) {
+				strfieldcpy(dev.name, temp3);
+				continue;
+			}
 
-			/* SYMLINK="name" */
-			temp2 = strsep(&temp, ",");
-			retval = get_value("SYMLINK", &temp, &temp3);
-			if (retval == 0)
+			if (strcasecmp(temp2, FIELD_SYMLINK) == 0) {
 				strfieldcpy(dev.symlink, temp3);
+				continue;
+			}
+
+			dbg_parse("unknown type of field '%s'", temp2);
+		}
 
+		/* check presence of keys according to method type */
+		switch (dev.type) {
+		case LABEL:
+			dbg_parse("LABEL name='%s', bus='%s', "
+				  "sysfs_file='%s', sysfs_value='%s', symlink='%s'",
+				  dev.name, dev.bus, dev.sysfs_file,
+				  dev.sysfs_value, dev.symlink);
+			if ((*dev.name == '\0') ||
+			    (*dev.bus == '\0') ||
+			    (*dev.sysfs_file == '\0') ||
+			    (*dev.sysfs_value == '\0'))
+				goto error;
+			break;
+		case NUMBER:
+			dbg_parse("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("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("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("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.bus == '\0') ||
+			    (*dev.id == '\0') ||
+			    (*dev.exec_program == '\0'))
+				goto error;
+			break;
+		default:
+			dbg_parse("xxx default method");
+			goto error;
 		}
 
 		retval = add_config_dev(&dev);
 		if (retval) {
 			dbg("add_config_dev returned with error %d", retval);
-			goto exit;
+			continue;
 		}
 	}
-	dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_rules_filename,
-		  lineno, temp - line, temp);
+error:
+	dbg_parse("%s:%d:%Zd: field missing or parse error", udev_rules_filename,
+		  lineno, temp - line);
 exit:
 	fclose(fd);
 	return retval;
-}	
-
+}
 
 int namedev_init_permissions(void)
 {
diff -Nru a/test/label_test b/test/label_test
--- a/test/label_test	Tue Dec 16 02:26:49 2003
+++ b/test/label_test	Tue Dec 16 02:26:49 2003
@@ -8,7 +8,7 @@
 export UDEV_CONFIG_FILE=$PWD/$CONFIG
 
 cat > $RULES << EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
 EOF
 
 cat > $CONFIG << EOF
diff -Nru a/test/udev-test.pl b/test/udev-test.pl
--- a/test/udev-test.pl	Tue Dec 16 02:26:49 2003
+++ b/test/udev-test.pl	Tue Dec 16 02:26:49 2003
@@ -38,7 +38,7 @@
 		devpath  => "block/sda",
 		expected => "boot_disk" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n"
 REPLACE, KERNEL="ttyUSB0", NAME="visor"
 EOF
 	},
@@ -48,7 +48,7 @@
 		devpath  => "block/sda/sda1",
 		expected => "boot_disk1" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n"
+LABEL, 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", vendor="?IBM-ESXS", NAME="boot_disk%n-1"
-LABEL, BUS="scsi", vendor="IBM-ESXS?", NAME="boot_disk%n-2"
-LABEL, BUS="scsi", vendor="IBM-ES??", NAME="boot_disk%n"
-LABEL, BUS="scsi", vendor="IBM-ESXSS", NAME="boot_disk%n-3"
+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"
 EOF
 	},
 	{
@@ -167,7 +167,7 @@
 		devpath  => "block/sda",
 		expected => "lun0/disc" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="lun0/%D"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
 EOF
 	},
 	{
@@ -176,7 +176,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "lun0/part2" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="lun0/%D"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="lun0/%D"
 EOF
 	},
 	{
@@ -205,7 +205,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/a/b/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/node", SYMLINK="1/2/a/b/symlink"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/node", SYMLINK="1/2/a/b/symlink"
 EOF
 	},
 	{
@@ -214,7 +214,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/symlink"
 EOF
 	},
 	{
@@ -223,7 +223,7 @@
 		devpath  => "block/sda/sda2",
 		expected => "1/2/c/d/symlink" ,
 		conf     => <<EOF
-LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
+LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink"
 EOF
 	},
 	{
diff -Nru a/udev.8 b/udev.8
--- a/udev.8	Tue Dec 16 02:26:49 2003
+++ b/udev.8	Tue Dec 16 02:26:49 2003
@@ -18,7 +18,7 @@
 .B udev
 reads the sysfs directory of the given device to collect device attributes
 like label, serial number or bus device number.
-These attributes are treated as a key 
+These attributes are treated as a key
 to determine a unique name for device file creation.
 .B udev
 maintains a database for devices present on the system.
@@ -87,7 +87,7 @@
 .I /etc/udev/udev.rules
 or specified by the
 .I udev_rules
-value in the 
+value in the
 .I /etc/udev/udev.conf
 file.
 .P
@@ -114,8 +114,7 @@
 device label or serial number, like USB serial number, SCSI UUID or
 file system label
 .br
-.RB "keys: " BUS ", "
-.I sysfs_attribute
+.RB "keys: " BUS ", " SYSFS_
 .TP
 .B NUMBER
 device number on the bus, like PCI bus id
@@ -130,7 +129,7 @@
 .B REPLACE
 string replacement of the kernel device name
 .br
-.RB "key: " KERNEL_NAME
+.RB "key: " KERNEL
 .P
 The methods are applied in the following order:
 .BR CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "."
@@ -167,7 +166,7 @@
 CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1"
 
 # USB printer to be called lp_color
-LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_color"
+LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_color"
 
 # sound card with PCI bus id 00:0b.0 to be called dsp
 NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp"
diff -Nru a/udev.rules.demo b/udev.rules.demo
--- a/udev.rules.demo	Tue Dec 16 02:26:49 2003
+++ b/udev.rules.demo	Tue Dec 16 02:26:49 2003
@@ -1,8 +1,8 @@
 # USB camera from Fuji to be named "camera"
-LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera%n"
+LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", NAME="camera%n"
 
 # USB device plugged into the fourth port of the second hub to be called gps_device
-TOPOLOGY, BUS="usb", place="2.4", NAME="gps_device"
+TOPOLOGY, BUS="usb", PLACE="2.4", NAME="gps_device"
 
 # ttyUSB1 should always be called visor
 REPLACE, KERNEL="ttyUSB1", NAME="visor"

  parent reply	other threads:[~2003-12-16  1:36 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-15 22:36 [udev] don't rely on field order in namedev_parse Greg KH
2003-12-16  0:21 ` Kay Sievers
2003-12-16  0:27 ` Greg KH
2003-12-16  1:36 ` Kay Sievers [this message]
2003-12-16 23:40 ` Greg KH
2003-12-17  0:50 ` Kay Sievers
2003-12-17  0:59 ` Greg KH
2003-12-17 17:04 ` Roman Kagan
2003-12-17 18:26 ` Greg KH
  -- strict thread matches above, loose matches on Subject: below --
2003-12-12 19:36 Kay Sievers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=marc-linux-hotplug-107153877206763@msgid-missing \
    --to=kay.sievers@vrfy.org \
    --cc=linux-hotplug@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.