1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-23 21:35:11 +03:00

warn when renaming kernel-provided nodes instead of adding symlinks

This commit is contained in:
Kay Sievers 2010-05-05 11:14:50 +02:00
parent 2d01980f1a
commit 75cb1ac51e
5 changed files with 70 additions and 76 deletions

11
NEWS
View File

@ -1,5 +1,16 @@
udev 154 udev 154
======== ========
Bugfixes.
Udev now gradually starts to pass control over the primary device nodes
and their names to the kernel, and will in the end only manage the
permissions of the node, and possibly create additional symlinks.
As a first step NAME="" will be ignored, and NAME= setings with names
other than the kernel provided name will result in a logged warning.
Kernels that don't provide device names, or devtmpfs is not used, will
still work as they did before, but it is strongly recommended to use
only the same names for the primary device node as the recent kernel
provides for all devices.
udev 153 udev 153
======== ========

View File

@ -1263,17 +1263,6 @@ EOF
KERNEL=="ttyACM[0-9]*", SYMLINK+="one" KERNEL=="ttyACM[0-9]*", SYMLINK+="one"
KERNEL=="ttyACM[0-9]*", SYMLINK+="two" KERNEL=="ttyACM[0-9]*", SYMLINK+="two"
KERNEL=="ttyACM[0-9]*", SYMLINK="three" KERNEL=="ttyACM[0-9]*", SYMLINK="three"
EOF
},
{
desc => "test empty NAME",
subsys => "tty",
devpath => "/devices/pci0000:00/0000:00:1d.7/usb5/5-2/5-2:1.0/tty/ttyACM0",
exp_name => "<none>",
not_exp_name => "ttyACM0",
exp_add_error => "yes",
rules => <<EOF
KERNEL=="ttyACM[0-9]*", NAME=""
EOF EOF
}, },
{ {

View File

@ -617,15 +617,20 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
} }
} }
if (event->name == NULL) { if (event->name == NULL || event->name[0] == '\0') {
/* things went wrong */
udev_device_delete_db(dev); udev_device_delete_db(dev);
udev_device_tag_index(dev, NULL, false); udev_device_tag_index(dev, NULL, false);
udev_device_unref(event->dev_db); udev_device_unref(event->dev_db);
err = -ENOMEM; err = -ENOMEM;
err(event->udev, "no node name, something went wrong, ignoring\n");
goto out; goto out;
} }
if (udev_device_get_knodename(dev) != NULL && strcmp(udev_device_get_knodename(dev), event->name) != 0)
err(event->udev, "kernel-provided name '%s' and NAME= '%s' disagree, "
"please use SYMLINK+= or change the kernel to provide the proper name\n",
udev_device_get_knodename(dev), event->name);
/* set device node name */ /* set device node name */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", event->name, NULL); util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", event->name, NULL);
udev_device_set_devnode(dev, filename); udev_device_set_devnode(dev, filename);
@ -639,23 +644,7 @@ int udev_event_execute_rules(struct udev_event *event, struct udev_rules *rules)
if (event->dev_db != NULL) if (event->dev_db != NULL)
udev_node_update_old_links(dev, event->dev_db); udev_node_update_old_links(dev, event->dev_db);
if (event->name[0] != '\0') err = udev_node_add(dev, event->mode, event->uid, event->gid);
err = udev_node_add(dev, event->mode, event->uid, event->gid);
else
info(event->udev, "device node creation suppressed\n");
/* remove kernel-created node, if needed */
if (udev_device_get_knodename(dev) != NULL && strcmp(event->name, udev_device_get_knodename(dev)) != 0) {
struct stat stats;
char filename[UTIL_PATH_SIZE];
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", udev_device_get_knodename(dev), NULL);
if (lstat(filename, &stats) == 0 && stats.st_rdev == udev_device_get_devnum(dev)) {
info(event->udev, "remove kernel created node '%s'\n", udev_device_get_knodename(dev));
util_unlink_secure(event->udev, filename);
util_delete_path(event->udev, filename);
}
}
} }
udev_device_unref(event->dev_db); udev_device_unref(event->dev_db);

View File

@ -1468,9 +1468,13 @@ static int add_rule(struct udev_rules *rules, char *line,
if (op < OP_MATCH_MAX) { if (op < OP_MATCH_MAX) {
rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL); rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
} else { } else {
if (strcmp(value, "%k") == 0) if (strcmp(value, "%k") == 0) {
err(rules->udev, "NAME=\"%%k\" is superfluous and breaks " err(rules->udev, "NAME=\"%%k\" is ignored because it breaks kernel supplied names, "
"kernel supplied names, please remove it from %s:%u\n", filename, lineno); "please remove it from %s:%u\n", filename, lineno);
continue;
}
if (value[0] == '\0')
continue;
rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL); rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
} }
rule_tmp.rule.rule.flags = 1; rule_tmp.rule.rule.flags = 1;

View File

@ -18,23 +18,28 @@
<refnamediv> <refnamediv>
<refname>udev</refname> <refname>udev</refname>
<refpurpose>dynamic device management</refpurpose> <refpurpose>Linux dynamic device management</refpurpose>
</refnamediv> </refnamediv>
<refsect1><title>DESCRIPTION</title> <refsect1><title>DESCRIPTION</title>
<para>udev provides a dynamic device directory containing only the files for <para>udev supplies the system software with device events, manages permissions
actually present devices. It creates or removes device node files in the of device nodes and may create additional symlinks in the <filename>/dev</filename>
<filename>/dev</filename> directory, or it renames network interfaces.</para> directory, or renames network interfaces. The kernel usually just assigns unpredictable
device names based on the order of discovery. Meaningful symlinks or network device
names provide a way to reliably identify devices based on their properties or
current configuration.</para>
<para>Usually udev runs as <citerefentry><refentrytitle>udevd</refentrytitle> <para>The udev daemon <citerefentry><refentrytitle>udevd</refentrytitle>
<manvolnum>8</manvolnum></citerefentry> and receives uevents directly from the <manvolnum>8</manvolnum></citerefentry> receives device uevents directly from
kernel if a device is added or removed from the system.</para> the kernel whenever a device is added or removed from the system, or it changes its
state. When udev receives a device event, it matches its configured set of rules
against various device attributes to identify the device. Rules that match, may
provide additional device information to be stored in the udev database, or information
to be used to create meaningful symlink names.</para>
<para>If udev receives a device event, it matches its configured rules <para>All device information udev processes, is stored in the udev database and
against the available device attributes provided in sysfs to identify the device. sent out to possible event subscribers. Access to all stored data and the event
Rules that match may provide additional device information or specify a device sources are provided by the library libudev.</para>
node name and multiple symlink names and instruct udev to run additional programs
as part of the device event handling.</para>
</refsect1> </refsect1>
<refsect1><title>CONFIGURATION</title> <refsect1><title>CONFIGURATION</title>
@ -84,9 +89,9 @@
If all match keys are matching against its value, the rule gets applied and the If all match keys are matching against its value, the rule gets applied and the
assign keys get the specified value assigned.</para> assign keys get the specified value assigned.</para>
<para>A matching rule may specify the name of the device node, add a symlink <para>A matching rule may rename a network interface, add symlinks
pointing to the node, or run a specified program as part of the event handling. pointing to the device node, or run a specified program as part of
If no matching rule is found, the default device node name is used.</para> the event handling.</para>
<para>A rule consists of a list of one or more key value pairs separated by <para>A rule consists of a list of one or more key value pairs separated by
a comma. Each key has a distinct operation, depending on the used operator. Valid a comma. Each key has a distinct operation, depending on the used operator. Valid
@ -304,13 +309,17 @@
<varlistentry> <varlistentry>
<term><option>NAME</option></term> <term><option>NAME</option></term>
<listitem> <listitem>
<para>The name, a network interface should be renamed to, or the name <para>The name, a network interface should be renamed to. Or as
a device node should be named. Usually the kernel provides the defined a temporary workaraound, the name a device node should be named.
node name, or even creates and removes the node before udev receives Usually the kernel provides the defined node name, or even creates
any event. Changing the node name from the kernel's default may result and removes the node before udev even receives any event. Changing
in unexpected behavior and is not supported. Udev is only expected to the node name from the kernel's default creates inconsistencies
handle device node permissions and to create additional symlinks, which and is not supported. If the kernel and NAME specify different names,
do not conflict with the kernel device node names.</para> an error will be logged. Udev is only expected to handle device node
permissions and to create additional symlinks, not to change
kernel-provided device node names. Instead of renaming a device node,
SYMLINK should be used. Symlink names must never conflict with
device node names, it will result in unpredictable behavior.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -318,15 +327,15 @@
<term><option>SYMLINK</option></term> <term><option>SYMLINK</option></term>
<listitem> <listitem>
<para>The name of a symlink targeting the node. Every matching rule will add <para>The name of a symlink targeting the node. Every matching rule will add
this value to the list of symlinks to be created along with the device node. this value to the list of symlinks to be created. Multiple symlinks may be
Multiple symlinks may be specified by separating the names by the space specified by separating the names by the space character. In case multiple
character. In case multiple devices claim the same name, the link will devices claim the same name, the link will always point to the device with
always point to the device with the highest link_priority. If the current device the highest link_priority. If the current device goes away, the links will
goes away, the links will be re-evaluated and the device with the next highest be re-evaluated and the device with the next highest link_priority will own
link_priority will own the link. If no link_priority is specified, the order the link. If no link_priority is specified, the order of the devices, and
of the devices, and which of them will own the link, is undefined. Claiming which one of them will own the link, is undefined. Claiming the same name for
the same name for a node and links may result in unexpected behavior and is a symlink, which is or might be used for a device node, may result in
not supported. unexpected behavior and is not supported.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -379,18 +388,10 @@
<option>RUN{<replaceable>fail_event_on_error</replaceable>}</option> is <option>RUN{<replaceable>fail_event_on_error</replaceable>}</option> is
specified, and the executed program returns non-zero, the event will be specified, and the executed program returns non-zero, the event will be
marked as failed for a possible later handling.</para> marked as failed for a possible later handling.</para>
<para>If no path is given, the program must be in <para>If no absolute path is given, the program is expected to live in
<filename>/lib/udev</filename>, otherwise the full path must be <filename>/lib/udev</filename>, otherwise the absolute path must be
specified.</para> specified. Program name and arguments are separated by spaces. Single quotes
<para>If the specified string starts with can be used to specify arguments with spaces.</para>
<option>socket:<replaceable>path</replaceable></option>, all current event
values will be passed to the specified socket, as a message in the same
format the kernel sends an uevent. If the first character of the specified path
is an @ character, an abstract namespace socket is used, instead of an existing
socket file.</para>
<para>Program name and arguments are separated with spaces. To
include spaces in an argument, use single quotes. Please note
that this does not run through a shell.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>