udev - drop all methods :)
PATCH 1/1 udev - drop all methods :)
Hi,
as promised yesterday, here is a patch that drops the explicit methods given in the udev config and implement only one type of rule.
A rule now consists only of a number of keys to match. All known keys are valid in any combination. The former configs should work with a few changes:
o the "<METHOD>, " at the beginning of the line should be removed
o the result of the externel program is matched with RESULT= instead if ID= the PROGRAM= key is only valid if the program exits with zero (just exit with nozero in a script if the rule should not match)
o rules are processed in order they appear in the file, no priority
o if NAME="" is given, udev is instructed to ignore this device, no node will be created
EXAMPLE:
# combined BUS, SYSFS and KERNEL BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n"
# exec script only for the first ide drive (hda), all other will be skipped BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c"
The udev-test.pl and test.block works fine here.
Please adapt your config and give it a try.
thanks,
Kay
namedev.c +151 -209
@@ -213,27 +213,27 @@dbg ("substitute major number '%u'" , udev->major);break ;case 'c' : -if (strlen (udev->callout_value) ==0 ) +if (strlen (udev->program_result) ==0 )break ;if (num) {/* get part of return string */ -strncpy (temp, udev->callout_value,sizeof (temp)); +strncpy (temp, udev->program_result,sizeof (temp)); pos2 = temp;while (num) { num--; pos3 =strsep (&pos2," " );if (pos3 ==NULL ) { -dbg ("requested part of callout string not found" ); +dbg ("requested part of result string not found" );break ; } }if (pos3) {strcat (pos, pos3); -dbg ("substitute partial callout output '%s'" , pos3); +dbg ("substitute part of result string '%s'" , pos3); } }else { -strcat (pos, udev->callout_value); -dbg ("substitute callout output '%s'" , udev->callout_value); +strcat (pos, udev->program_result); +dbg ("substitute result string '%s'" , udev->program_result); }break ;default :
@@ -298,28 +298,7 @@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) +static int execute_program (char *path,char *value,int len) {int retval;int res;
@@ -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,108 @@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[0 ] !='\0' ) { +dbg ("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'" , dev->kernel, class_dev->name); +if (strcmp_pattern (dev->kernel, 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->program[0 ] !='\0' ) { +dbg ("check " FIELD_PROGRAM ); +apply_format (udev, dev->program); +if (execute_program (dev->program, udev->program_result,NAME_SIZE ) !=0 ) { +dbg (FIELD_PROGRAM " returned nozero" ); +continue ; + }else { +dbg (FIELD_PROGRAM " returned successful" ); + } + } + +/* check for matching result of external program */ +if (dev->result[0 ] !='\0' ) { +dbg ("check for " FIELD_RESULT +" dev->result='%s', udev->program_result='%s'" , + dev->result, udev->program_result); +if (strcmp_pattern (dev->result, udev->program_result) !=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, 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 +6 -23
@@ -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 5struct 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 kernel[NAME_SIZE ]; +char program[PROGRAM_SIZE ]; +char result[PROGRAM_SIZE ];char name[NAME_SIZE ];char symlink[NAME_SIZE ];struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS ];
namedev_parse.c +26 -123
179 lines not on this page · raw message
test/udev-test.pl +57 -60
310 lines not on this page · raw message
udev.h +1 -1
@@ -68,7 +68,7 @@/* fields that help us in building strings */ unsigned char bus_id[SYSFS_NAME_LEN ]; -unsigned char callout_value[NAME_SIZE ]; +unsigned char program_result[NAME_SIZE ];unsigned char kernel_number[NAME_SIZE ];unsigned char kernel_name[NAME_SIZE ];
On Sat, Jan 10, 2004 at 07:15:07PM +0100, Kay Sievers wrote:
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM and also match in all following rules with the RESULT value from this exec.
EXAMPLE:
We have 7 rules with RESULT and 2 with PROGRAM.
Only the 5th rule matches with the callout result from the exec in the 4th rule.
RULES:
PROGRAM="/bin/echo abc", RESULT="no_match", NAME="web-no-2"¶ KERNEL="video*", RESULT="123", NAME="web-no-3"¶ KERNEL="video*", RESULT="123", NAME="web-no-4"¶ PROGRAM="/bin/echo 123", RESULT="no_match", NAME="web-no-5"¶ KERNEL="video*", RESULT="123", NAME="web-yes"¶
RESULT:
Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo abc' Jan 11 23:36:52 pim udev[26050]: execute_program: result is 'abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo 123' Jan 11 23:36:52 pim udev[26050]: execute_program: result is '123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: found matching rule, 'video*' becomes '' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: name, 'web-yes' is going to have owner='', group='', mode = 0600
Quoted 29 lines
Hi,
as promised yesterday, here is a patch that drops the explicit methods given in the udev config and implement only one type of rule.A rule now consists only of a number of keys to match. All known keys are valid in any combination. The former configs should work with a few changes:
o the "<METHOD>, " at the beginning of the line should be removed
o the result of the externel program is matched with RESULT= instead if ID= the PROGRAM= key is only valid if the program exits with zero (just exit with nozero in a script if the rule should not match)
o rules are processed in order they appear in the file, no priority
o if NAME="" is given, udev is instructed to ignore this device, no node will be created
EXAMPLE:
# combined BUS, SYSFS and KERNEL BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n"# exec script only for the first ide drive (hda), all other will be skipped BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c"
Quoted 5 lines
The udev-test.pl and test.block works fine here.
Please adapt your config and give it a try.thanks,
Kay
namedev.c +152 -209
@@ -213,27 +213,27 @@dbg ("substitute major number '%u'" , udev->major);break ;case 'c' : -if (strlen (udev->callout_value) ==0 ) +if (strlen (udev->program_result) ==0 )break ;if (num) {/* get part of return string */ -strncpy (temp, udev->callout_value,sizeof (temp)); +strncpy (temp, udev->program_result,sizeof (temp)); pos2 = temp;while (num) { num--; pos3 =strsep (&pos2," " );if (pos3 ==NULL ) { -dbg ("requested part of callout string not found" ); +dbg ("requested part of result string not found" );break ; } }if (pos3) {strcat (pos, pos3); -dbg ("substitute partial callout output '%s'" , pos3); +dbg ("substitute part of result string '%s'" , pos3); } }else { -strcat (pos, udev->callout_value); -dbg ("substitute callout output '%s'" , udev->callout_value); +strcat (pos, udev->program_result); +dbg ("substitute result string '%s'" , udev->program_result); }break ;default :
@@ -298,28 +298,7 @@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) +static int execute_program (char *path,char *value,int len) {int retval;int res;
@@ -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,109 @@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) { +dbg ("process rule" ); - 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[0 ] !='\0' ) { +dbg ("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'" , dev->kernel, class_dev->name); +if (strcmp_pattern (dev->kernel, 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 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" ); + } + } - retval =do_topology (class_dev, udev, sysfs_device); -if (retval ==0 ) - goto found; +/* 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" ); + } + } + +/* check for matching sysfs pairs */ +if (dev->sysfs_pair[0 ].file[0 ] !='\0' ) { +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_replace (class_dev, udev, sysfs_device); -if (retval ==0 ) +/* execute external program */ +if (dev->program[0 ] !='\0' ) { +dbg ("check " FIELD_PROGRAM ); +apply_format (udev, dev->program); +if (execute_program (dev->program, udev->program_result,NAME_SIZE ) !=0 ) { +dbg (FIELD_PROGRAM " returned nozero" ); +continue ; + }else { +dbg (FIELD_PROGRAM " returned successful" ); + } + } + +/* check for matching result of external program */ +if (dev->result[0 ] !='\0' ) { +dbg ("check for " FIELD_RESULT +" dev->result='%s', udev->program_result='%s'" , + dev->result, udev->program_result); +if (strcmp_pattern (dev->result, udev->program_result) !=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, 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 +6 -23
@@ -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 5struct 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 kernel[NAME_SIZE ]; +char program[PROGRAM_SIZE ]; +char result[PROGRAM_SIZE ];char name[NAME_SIZE ];char symlink[NAME_SIZE ];struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS ];
namedev_parse.c +28 -126
196 lines not on this page · raw message
test/udev-test.pl +57 -60
310 lines not on this page · raw message
udev.h +1 -1
@@ -68,7 +68,7 @@/* fields that help us in building strings */ unsigned char bus_id[SYSFS_NAME_LEN ]; -unsigned char callout_value[NAME_SIZE ]; +unsigned char program_result[NAME_SIZE ];unsigned char kernel_number[NAME_SIZE ];unsigned char kernel_name[NAME_SIZE ];
Quoted 5 lines · Kay Sievers
On Sat, Jan 10, 2004 at 07:15:07PM +0100, Kay Sievers wrote:
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM and also match in all following rules with the RESULT value from this exec.
Thanks a lot. I've applied this patch. I also made a few tweaks to the parsing logic to help catch old rules files properly (otherwise we end up creating rules that the user might not have wanted.) I also cleaned up the other test scripts and the config files.
Care to update the documentation so we can make a release for others 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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
Quoted 7 lines · Greg KH
Quoted 5 lines · Kay Sievers
On Sat, Jan 10, 2004 at 07:15:07PM +0100, Kay Sievers wrote:
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM and also match in all following rules with the RESULT value from this exec.
Quoted 7 lines
Thanks a lot. I've applied this patch. I also made a few tweaks to the parsing logic to help catch old rules files properly (otherwise we end up creating rules that the user might not have wanted.) I also cleaned up the other test scripts and the config files.
Care to update the documentation so we can make a release for others to play with?
Yes, I'll update the man page in the next two hours :)
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel
Quoted 8 lines · Greg KH
Quoted 5 lines · Kay Sievers
On Sat, Jan 10, 2004 at 07:15:07PM +0100, Kay Sievers wrote:
Here is a slightly better version of the patch.
After a conversation with Patrick, we are now able to execute the PROGRAM and also match in all following rules with the RESULT value from this exec.Thanks a lot. I've applied this patch. I also made a few tweaks to the
Nice, that sped things up quite a bit.
Running with PROGRAM="/sbin/scsi_id" with 70 lines each of the form:
BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="SIBM OEM DCHS09X 68136581", NAME="disk-sda"
BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="3600a0b80000b174b000000e83efc5d38", NAME="disk-sdaa"
...
Took 1m16 to run the udev/test/test.block test script (with 70 sd's in /sys/block).
Using the new method, and having only one PROGRAM="/sbin/scsi_id" for the first scsi rule, and just RESULT for the other 69, test.block took 47 seconds.
-- Patrick Mansfield
-------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel