1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-23 17:34:00 +03:00

remove broken %e enumeration

This commit is contained in:
Kay Sievers 2006-07-04 12:27:00 +02:00
parent f1e9ccb94d
commit c8ff4b3db4
5 changed files with 16 additions and 185 deletions

32
FAQ
View File

@ -14,7 +14,7 @@ A: udev works entirely in userspace, using hotplug events the kernel sends
All device naming policy permission control and event handling is done in
userspace. devfs is operated from within the kernel.
Q: Why was devfs marked OBSOLETE/removed if udev can't do everthing devfs did?
Q: Why was devfs removed if udev can't do everthing devfs did?
A: To quote Al Viro (Linux VFS kernel maintainer):
- it was determined that the same thing could be done in userspace
- devfs had been shoved into the tree in hope that its quality will
@ -46,31 +46,25 @@ A: The devfs approach caused a lot of spurious modprobe attempts as
spurious.
Q: I really like the devfs naming scheme, will udev do that?
A: Yes, udev can create /dev nodes using the devfs naming policy. A
configuration file needs to be created to map the kernel default names
to the devfs names. See the udev.rules.devfs file in the udev
release.
Note that the devfs scheme is not recommended or officially supported
because it is a really stupid idea to simply enumerate devices in a world
where devices can come and go at any time. These numbers give you nothing
but problems, and are not useful to identify a device. Have a look at the
persistent disk rules for an example how to do it correctly in userspace
without any stupid device enumeration.
A: Yes, udev can create /dev nodes using the devfs naming policy. But you
will need a custom configuration and scripts that enumerate your devices
sequentially while events run in parallel, without a predictable order.
The devfs scheme is not recommended or supported because it is a stupid
idea to simply enumerate devices in a world where devices can come and go
at any time. These numbers give you nothing but problems, and are not
useful to identify a device. Have a look at the persistent rules for
examples how to create persistent device names in userspace without any
device enumeration depending on the device probing order.
Q: What kinds of devices does udev create nodes for?
A: All devices that are shown in sysfs will work with udev. If more
support is added for devices to the kernel, udev will automatically
start working for them. All block devices are currently supported, and
almost all major char devices are supported. Kernel developers are
working on adding support for all char devices at this time. See the
linux-kernel mailing list for patches and status of these patches.
A: All devices that are shown in the kernel's sysfs tree will work with udev.
Q: Will udev remove the limit on the number of anonymous devices?
A: udev is entirely in userspace. If the kernel supports a greater number
of anonymous devices, udev will support it.
Q: Will udev support symlinks?
A: Yes, It now does. Multiple symlinks per device node are supported.
Q: Does udev support symlinks?
A: Yes, multiple symlinks per device node are supported.
Q: How will udev handle the /dev filesystem?
A: /dev is recomended to be a tmpfs filesystem that is recreated on every reboot.

3
TODO
View File

@ -7,9 +7,6 @@ These things need to be done, or would be nice to have:
These things are deprecated and scheduled for removal in a future
udev version:
o remove broken %e enumeration
(simple enumerations can't work reliably and should go)
o remove udevstart
(we rely on the kernel "uevent" triggers of kernel 2.6.15 and no longer
want to guess event properties from sysfs like udevstart is doing it)

View File

@ -101,7 +101,7 @@ And now for udev:
want to deviate away from this standard (for example when naming
some devices in a persistent manner), it is easily possible to do
so.
3) udev is small (49Kb binary) and is entirely in userspace, which
3) udev is small and is entirely in userspace, which
is swapable, and doesn't have to be running at all times.
Nice, 7 out of 7 for udev. Makes you think the problems and constraints
@ -146,7 +146,7 @@ So, how well does udev solve its goals:
As the above scenarios show, both desktop users and big iron users
both need to not worry about which device is assigned to what
major/minor device.
udev doesn't care what major/minor number is assigned to a device.
It merely takes the numbers that the kernel says it assigned to the
device and creates a device node based on it, which the user can
@ -174,7 +174,7 @@ So, how well does udev solve its goals:
For more information on how to create udev rules to name devices,
please see the udev man page, and look at the example udev rules
that ship with the tarball.
So, convinced already why you should use udev instead of devfs? No.
Ok, fine, I'm not forcing you to abandon your bloated, stifling policy,

View File

@ -1008,74 +1008,6 @@ EOF
exp_target => "node",
rules => <<EOF
BUS=="scsi", PROGRAM=="/bin/echo -n node link1 link2 link3 link4", RESULT=="node *", NAME="%c{1}", SYMLINK+="%c{2+}"
EOF
},
{
desc => "enumeration char test (single test)",
subsys => "block",
devpath => "/block/sda",
exp_name => "cdrom",
rules => <<EOF
KERNEL=="sda", NAME="cdrom%e"
EOF
},
{
desc => "enumeration char test sequence 1/5 (keep)",
subsys => "block",
devpath => "/block/sda",
exp_name => "cdrom",
option => "keep",
rules => <<EOF
KERNEL=="sda", NAME="cdrom%e"
EOF
},
{
desc => "enumeration char test sequence 2/5 (keep)",
subsys => "block",
devpath => "/block/sda/sda1",
exp_name => "enum",
option => "keep",
rules => <<EOF
KERNEL=="sda1", NAME="enum%e"
EOF
},
{
desc => "enumeration char test sequence 3/5 (keep)",
subsys => "block",
devpath => "/block/sda/sda2",
exp_name => "cdrom1",
option => "keep",
rules => <<EOF
KERNEL=="sda2", NAME="cdrom%e"
EOF
},
{
desc => "enumeration char test sequence 4/5 (keep)",
subsys => "block",
devpath => "/block/sda/sda3",
exp_name => "enum1",
option => "keep",
rules => <<EOF
KERNEL=="sda3", NAME="enum%e"
EOF
},
{
desc => "enumeration char test sequence 5/5 (clean)",
subsys => "block",
devpath => "/block/sda/sda4",
exp_name => "cdrom2",
option => "clean",
rules => <<EOF
KERNEL=="sda4", NAME="cdrom%e"
EOF
},
{
desc => "enumeration char test after cleanup (single test)",
subsys => "block",
devpath => "/block/sda",
exp_name => "cdrom",
rules => <<EOF
KERNEL=="sda", NAME="cdrom%e"
EOF
},
{

View File

@ -263,88 +263,6 @@ static int import_parent_into_env(struct udevice *udev, const char *filter)
return rc;
}
static int match_name_and_get_number(const char *base, const char *devname)
{
size_t baselen;
char *endptr;
int num;
baselen = strlen(base);
if (strncmp(base, devname, baselen) != 0)
return -1;
if (devname[baselen] == '\0')
return 0;
if (!isdigit(devname[baselen]))
return -1;
num = strtoul(&devname[baselen], &endptr, 10);
if (endptr[0] != '\0')
return -1;
return num;
}
/* finds the lowest positive device number such that <name>N isn't present in the udevdb
* if <name> doesn't exist, 0 is returned, N otherwise */
static int find_free_number(const char *base, const char *devpath)
{
char db_devpath[PATH_SIZE];
char filename[PATH_SIZE];
struct udevice *udev_db;
int num = 0;
static int warn = 1;
if (warn) {
err("%%e is deprecated, will be removed and is unlikely to work correctly. Don't use it.");
warn = 0;
}
/* check if the device already owns a matching name */
udev_db = udev_device_init();
if (udev_db == NULL)
return -1;
if (udev_db_get_device(udev_db, devpath) == 0) {
struct name_entry *name_loop;
int devnum;
devnum = match_name_and_get_number(base, udev_db->name);
if (devnum >= 0) {
num = devnum;
dbg("device '%s', already has the node '%s' with num %u, use it", devpath, base, num);
goto out;
}
list_for_each_entry(name_loop, &udev_db->symlink_list, node) {
devnum = match_name_and_get_number(base, name_loop->name);
if (devnum >= 0) {
num = devnum;
dbg("device '%s', already has a symlink '%s' with num %u, use it", devpath, base, num);
goto out;
}
}
}
/* just search the database again and again until a free name is found */
strlcpy(filename, base, sizeof(filename));
while (1) {
dbg("look for existing node '%s'", filename);
if (udev_db_lookup_name(filename, db_devpath, sizeof(db_devpath)) != 0) {
dbg("free num=%d", num);
break;
}
num++;
if (num > 100000) {
err("find_free_number aborted at num=%d", num);
num = -1;
break;
}
snprintf(filename, sizeof(filename), "%s%d", base, num);
filename[sizeof(filename)-1] = '\0';
}
out:
udev_device_cleanup(udev_db);
return num;
}
#define WAIT_LOOP_PER_SECOND 50
static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
{
@ -386,7 +304,6 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
int len;
int i;
int count;
unsigned int next_free_number;
enum subst_type {
SUBST_UNKNOWN,
SUBST_DEVPATH,
@ -397,7 +314,6 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
SUBST_MINOR,
SUBST_RESULT,
SUBST_SYSFS,
SUBST_ENUM,
SUBST_PARENT,
SUBST_TEMP_NODE,
SUBST_ROOT,
@ -416,7 +332,6 @@ void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
{ .name = "minor", .fmt = 'm', .type = SUBST_MINOR },
{ .name = "result", .fmt = 'c', .type = SUBST_RESULT },
{ .name = "sysfs", .fmt = 's', .type = SUBST_SYSFS },
{ .name = "enum", .fmt = 'e', .type = SUBST_ENUM },
{ .name = "parent", .fmt = 'P', .type = SUBST_PARENT },
{ .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE },
{ .name = "root", .fmt = 'r', .type = SUBST_ROOT },
@ -572,13 +487,6 @@ found:
dbg("substitute sysfs value '%s'", temp2);
}
break;
case SUBST_ENUM:
next_free_number = find_free_number(string, udev->dev->devpath);
if (next_free_number > 0) {
sprintf(temp2, "%d", next_free_number);
strlcat(string, temp2, maxsize);
}
break;
case SUBST_PARENT:
{
struct sysfs_device *dev_parent;