diff options
-rw-r--r-- | namedev.c | 38 | ||||
-rw-r--r-- | namedev.h | 8 | ||||
-rw-r--r-- | namedev_parse.c | 19 | ||||
-rw-r--r-- | test/udev-test.pl | 35 | ||||
-rw-r--r-- | udev.8.in | 29 | ||||
-rw-r--r-- | udev_add.c | 2 |
6 files changed, 98 insertions, 33 deletions
@@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com> + * Copyright (C) 2003-2005 Kay Sievers <kay.sievers@vrfy.org> * * * This program is free software; you can redistribute it and/or modify it @@ -749,14 +750,31 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("process rule"); if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { - /* empty name, symlink and perms will not create any node */ + /* FIXME: remove old style ignore rule and make OPTION="ignore" mandatory */ if (dev->name[0] == '\0' && dev->symlink[0] == '\0' && - dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0') { + dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0' && + !dev->ignore_device && !dev->partitions && !dev->ignore_remove) { info("configured rule in '%s[%i]' applied, '%s' is ignored", dev->config_file, dev->config_line, udev->kernel_name); return -1; } + /* apply options */ + if (dev->ignore_device) { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + dev->config_file, dev->config_line, udev->kernel_name); + return -1; + } + if (dev->ignore_remove) { + udev->ignore_remove = dev->ignore_remove; + dbg_parse("remove event should be ignored"); + } + /* apply all_partitions option only at a main block device */ + if (dev->partitions && udev->type == 'b' && udev->kernel_number[0] == '\0') { + udev->partitions = dev->partitions; + dbg("creation of partition nodes requested"); + } + /* apply permissions */ if (dev->mode != 0000) { udev->mode = dev->mode; @@ -788,11 +806,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d /* rule matches */ if (dev->name[0] != '\0') { - /* apply all_partitions flag only at a main block device */ - if (dev->partitions > 0 && - (udev->type != 'b' || udev->kernel_number[0] != '\0')) - continue; - info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); @@ -800,15 +813,10 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; - udev->ignore_remove = dev->ignore_remove; - - if (udev->type == 'n') - goto exit; - - udev->partitions = dev->partitions; - dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", - udev->name, udev->owner, udev->group, udev->mode, udev->partitions); + if (udev->type != 'n') + dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", + udev->name, udev->owner, udev->group, udev->mode, udev->partitions); goto exit; } @@ -50,9 +50,11 @@ struct sysfs_class_device; #define FIELD_OWNER "OWNER" #define FIELD_GROUP "GROUP" #define FIELD_MODE "MODE" +#define FIELD_OPTIONS "OPTIONS" -#define ATTR_PARTITIONS "all_partitions" +#define ATTR_IGNORE_DEVICE "ignore_device" #define ATTR_IGNORE_REMOVE "ignore_remove" +#define ATTR_PARTITIONS "all_partitions" #define MAX_SYSFS_PAIRS 5 @@ -77,11 +79,15 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; + int partitions; + int ignore_device; int ignore_remove; + char config_file[NAME_SIZE]; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index 7b5b963020..981daa7b3b 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003,2004 Greg Kroah-Hartman <greg@kroah.com> + * Copyright (C) 2003-2005 Kay Sievers <kay.sievers@vrfy.org> * * * This program is free software; you can redistribute it and/or modify it @@ -247,6 +248,7 @@ static int namedev_parse(const char *filename, void *data) if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); + /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, ATTR_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); @@ -286,6 +288,23 @@ static int namedev_parse(const char *filename, void *data) continue; } + if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { + if (strstr(temp3, ATTR_IGNORE_DEVICE) != NULL) { + dbg_parse("device should be ignored"); + dev.ignore_device = 1; + } + if (strstr(temp3, ATTR_IGNORE_REMOVE) != NULL) { + dbg_parse("remove event should be ignored"); + dev.ignore_remove = 1; + } + if (strstr(temp3, ATTR_PARTITIONS) != NULL) { + dbg_parse("creation of partition nodes requested"); + dev.partitions = DEFAULT_PARTITIONS_COUNT; + } + valid = 1; + continue; + } + dbg("unknown type of field '%s'", temp2); goto error; } diff --git a/test/udev-test.pl b/test/udev-test.pl index fc0e89eeb3..5f9c0cb9c5 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1021,13 +1021,44 @@ KERNEL="sda", NAME="cdrom%e" EOF }, { + desc => "ignore rule test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_error => "yes", + conf => <<EOF +BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore" +EOF + }, + { + desc => "all_partitions, option-only rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "node6", + conf => <<EOF +SUBSYSTEM="block", OPTIONS="all_partitions" +BUS="scsi", KERNEL="sda", NAME="node" +EOF + }, + { + desc => "all_partitions, option-only rule (fail on partition)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "node6", + exp_error => "yes", + conf => <<EOF +SUBSYSTEM="block", OPTIONS="all_partitions" +BUS="scsi", KERNEL="sda", NAME="node" +EOF + }, + { desc => "ignore remove event test", subsys => "block", devpath => "/block/sda", exp_name => "node", exp_error => "yes", conf => <<EOF -BUS="scsi", KERNEL="sda", NAME{ignore_remove}="node" +BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove" EOF }, { @@ -1038,7 +1069,7 @@ EOF exp_error => "yes", option => "clear", conf => <<EOF -BUS="scsi", KERNEL="sda", NAME{ignore_remove, all_partitions}="node" +BUS="scsi", KERNEL="sda", NAME="node", OPTIONS="ignore_remove, all_partitions" EOF }, { @@ -145,20 +145,6 @@ call. .B NAME The name of the node to be created, or the name, the network interface should be renamed to. -.br -If given with the attribute -.BR NAME{ all_partitions } -.B udev -will create device nodes for all 15 partitions of a blockdevice. -This may be useful for removable media devices. -.br -If given with the attribute -.BR NAME{ ignore_remove } -.B udev -will ignore any later remove event for this device. -This may be useful as a workaround for broken device drivers. -.sp -Multiple attributes may be separated by comma. .TP .B SYMLINK The name of a symlink targeting the node. Multiple symlinks may be @@ -177,6 +163,21 @@ distribution provided rules file. .B OWNER, GROUP, MODE The permissions for the device node. Every specified value overwrites the compiled-in default value. +.TP +.B OPTIONS +.B ignore_device +will ignore this device. No node will be created. +.sp +.B ignore_remove +will ignore any later remove event for this device. +This may be useful as a workaround for broken device drivers. +.sp +.B all_partitions +will create device nodes for all available partitions of a blockdevice. +This may be useful for removable media devices which do not detect a media +change. +.sp +Multiple attributes may be separated by comma. .P .RB "The " NAME ", " SYMLINK ", " PROGRAM ", " OWNER " and " GROUP fields support simple printf-like string substitutions: diff --git a/udev_add.c b/udev_add.c index be62e130ab..f384ea96e5 100644 --- a/udev_add.c +++ b/udev_add.c @@ -194,7 +194,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de } /* create all_partitions if requested */ - if (udev->partitions > 0) { + if (udev->partitions) { struct sysfs_attribute *attr; int range; |