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