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"
next prev 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 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).