mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #19312 from yuwata/udev-escape-slash-nvme
udev: make OPTIONS="string_escape=replace" take effect on ENV{key}= assiginment
This commit is contained in:
commit
157306439e
11
man/udev.xml
11
man/udev.xml
@ -117,7 +117,7 @@
|
||||
<varlistentry>
|
||||
<term><literal>:=</literal></term>
|
||||
<listitem>
|
||||
<para>Assign a value to a key finally; disallow any later changes.</para>
|
||||
<para>Assign a value to a key finally; disallow any later changes.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
@ -607,9 +607,12 @@
|
||||
<varlistentry>
|
||||
<term><option>string_escape=<replaceable>none|replace</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>Usually, control and other possibly unsafe characters are replaced
|
||||
in strings used for device naming. The mode of replacement can be specified
|
||||
with this option.</para>
|
||||
<para>When <literal>replace</literal>, possibly unsafe characters in strings
|
||||
assigned to <varname>NAME</varname>, <varname>SYMLINK</varname>, and
|
||||
<varname>ENV{<replaceable>key</replaceable>}</varname> are replaced. When
|
||||
<literal>none</literal>, no replacement is performed. When unset, the replacement
|
||||
is performed for <varname>NAME</varname>, <varname>SYMLINK</varname>, but not for
|
||||
<varname>ENV{<replaceable>key</replaceable>}</varname>. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
|
@ -38,13 +38,13 @@ KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{wwid}=="?*", ENV{ID_WWN
|
||||
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
|
||||
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ATTRS{firmware_rev}=="?*", ENV{ID_REVISION}="$attr{firmware_rev}"
|
||||
KERNEL=="nvme*[0-9]n*[0-9]", ENV{DEVTYPE}=="disk", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", \
|
||||
ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}"
|
||||
OPTIONS="string_escape=replace", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}"
|
||||
|
||||
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{serial}=="?*", ENV{ID_SERIAL_SHORT}="$attr{serial}"
|
||||
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{model}=="?*", ENV{ID_MODEL}="$attr{model}"
|
||||
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ATTRS{firmware_rev}=="?*", ENV{ID_REVISION}="$attr{firmware_rev}"
|
||||
KERNEL=="nvme*[0-9]n*[0-9]p*[0-9]", ENV{DEVTYPE}=="partition", ENV{ID_MODEL}=="?*", ENV{ID_SERIAL_SHORT}=="?*", \
|
||||
ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n"
|
||||
OPTIONS="string_escape=replace", ENV{ID_SERIAL}="$env{ID_MODEL}_$env{ID_SERIAL_SHORT}", SYMLINK+="disk/by-id/nvme-$env{ID_SERIAL}-part%n"
|
||||
|
||||
# virtio-blk
|
||||
KERNEL=="vd*[!0-9]", ATTRS{serial}=="?*", ENV{ID_SERIAL}="$attr{serial}", SYMLINK+="disk/by-id/virtio-$env{ID_SERIAL}"
|
||||
|
@ -748,6 +748,22 @@ static const char* const ip_tos_table[] = {
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
|
||||
|
||||
bool ifname_valid_char(char a) {
|
||||
if ((unsigned char) a >= 127U)
|
||||
return false;
|
||||
|
||||
if ((unsigned char) a <= 32U)
|
||||
return false;
|
||||
|
||||
if (IN_SET(a,
|
||||
':', /* colons are used by the legacy "alias" interface logic */
|
||||
'/', /* slashes cannot work, since we need to use network interfaces in sysfs paths, and in paths slashes are separators */
|
||||
'%')) /* %d is used in the kernel's weird foo%d format string naming feature which we really really don't want to ever run into by accident */
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
|
||||
bool numeric = true;
|
||||
|
||||
@ -781,16 +797,7 @@ bool ifname_valid_full(const char *p, IfnameValidFlags flags) {
|
||||
return false;
|
||||
|
||||
for (const char *t = p; *t; t++) {
|
||||
if ((unsigned char) *t >= 127U)
|
||||
return false;
|
||||
|
||||
if ((unsigned char) *t <= 32U)
|
||||
return false;
|
||||
|
||||
if (IN_SET(*t,
|
||||
':', /* colons are used by the legacy "alias" interface logic */
|
||||
'/', /* slashes cannot work, since we need to use network interfaces in sysfs paths, and in paths slashes are separators */
|
||||
'%')) /* %d is used in the kernel's weird foo%d format string naming feature which we really really don't want to ever run into by accident */
|
||||
if (!ifname_valid_char(*t))
|
||||
return false;
|
||||
|
||||
numeric = numeric && (*t >= '0' && *t <= '9');
|
||||
|
@ -139,6 +139,7 @@ typedef enum {
|
||||
IFNAME_VALID_NUMERIC = 1 << 1,
|
||||
_IFNAME_VALID_ALL = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC,
|
||||
} IfnameValidFlags;
|
||||
bool ifname_valid_char(char a);
|
||||
bool ifname_valid_full(const char *p, IfnameValidFlags flags);
|
||||
static inline bool ifname_valid(const char *p) {
|
||||
return ifname_valid_full(p, 0);
|
||||
|
@ -34,6 +34,7 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
|
||||
NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
|
||||
NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */
|
||||
NAMING_REPLACE_STRICTLY = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
|
||||
|
||||
/* And now the masks that combine the features above */
|
||||
NAMING_V238 = 0,
|
||||
@ -43,7 +44,7 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
|
||||
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
|
||||
NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
|
||||
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX,
|
||||
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
|
||||
|
||||
_NAMING_SCHEME_FLAGS_INVALID = -EINVAL,
|
||||
} NamingSchemeFlags;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "strxcpyx.h"
|
||||
@ -436,6 +437,22 @@ size_t udev_replace_whitespace(const char *str, char *to, size_t len) {
|
||||
return j;
|
||||
}
|
||||
|
||||
size_t udev_replace_ifname(char *str) {
|
||||
size_t replaced = 0;
|
||||
|
||||
assert(str);
|
||||
|
||||
/* See ifname_valid_full(). */
|
||||
|
||||
for (char *p = str; *p != '\0'; p++)
|
||||
if (!ifname_valid_char(*p)) {
|
||||
*p = '_';
|
||||
replaced++;
|
||||
}
|
||||
|
||||
return replaced;
|
||||
}
|
||||
|
||||
size_t udev_replace_chars(char *str, const char *allow) {
|
||||
size_t i = 0, replaced = 0;
|
||||
|
||||
|
@ -46,6 +46,7 @@ void log_device_uevent(sd_device *device, const char *str);
|
||||
|
||||
int udev_rule_parse_value(char *str, char **ret_value, char **ret_endpos);
|
||||
size_t udev_replace_whitespace(const char *str, char *to, size_t len);
|
||||
size_t udev_replace_ifname(char *str);
|
||||
size_t udev_replace_chars(char *str, const char *allow);
|
||||
int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, bool read_value);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "format-util.h"
|
||||
#include "netif-naming-scheme.h"
|
||||
#include "netlink-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
@ -848,6 +849,12 @@ static int rename_netif(UdevEvent *event) {
|
||||
if (r < 0)
|
||||
return log_device_error_errno(dev, r, "Failed to get ifindex: %m");
|
||||
|
||||
if (naming_scheme_has(NAMING_REPLACE_STRICTLY) &&
|
||||
!ifname_valid(event->name)) {
|
||||
log_device_warning(dev, "Invalid network interface name, ignoring: %s", event->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set ID_RENAMING boolean property here, and drop it in the corresponding move uevent later. */
|
||||
r = device_add_property(dev, "ID_RENAMING", "1");
|
||||
if (r < 0)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "glob-util.h"
|
||||
#include "list.h"
|
||||
#include "mkdir.h"
|
||||
#include "netif-naming-scheme.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
@ -2023,6 +2024,12 @@ static int udev_rule_apply_token_to_event(
|
||||
l = strpcpyl(&p, l, val, " ", NULL);
|
||||
|
||||
(void) udev_event_apply_format(event, token->value, p, l, false);
|
||||
if (event->esc == ESCAPE_REPLACE) {
|
||||
count = udev_replace_chars(buf, NULL);
|
||||
if (count > 0)
|
||||
log_rule_debug(dev, rules, "Replaced %zu slash(es) from result of ENV{%s}%s=\"%s\"",
|
||||
count, name, token->op == OP_ADD ? "+" : "", token->value);
|
||||
}
|
||||
|
||||
r = device_add_property(dev, name, value_new);
|
||||
if (r < 0)
|
||||
@ -2053,21 +2060,23 @@ static int udev_rule_apply_token_to_event(
|
||||
if (token->op == OP_ASSIGN_FINAL)
|
||||
event->name_final = true;
|
||||
|
||||
if (sd_device_get_ifindex(dev, NULL) < 0) {
|
||||
log_rule_error(dev, rules,
|
||||
"Only network interface can be renamed, ignoring NAME=\"%s\"; please fix it.",
|
||||
token->value);
|
||||
break;
|
||||
}
|
||||
|
||||
(void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false);
|
||||
if (IN_SET(event->esc, ESCAPE_UNSET, ESCAPE_REPLACE)) {
|
||||
count = udev_replace_chars(buf, "/");
|
||||
if (naming_scheme_has(NAMING_REPLACE_STRICTLY))
|
||||
count = udev_replace_ifname(buf);
|
||||
else
|
||||
count = udev_replace_chars(buf, "/");
|
||||
if (count > 0)
|
||||
log_rule_debug(dev, rules, "Replaced %zu character(s) from result of NAME=\"%s\"",
|
||||
count, token->value);
|
||||
}
|
||||
if (sd_device_get_devnum(dev, NULL) >= 0 &&
|
||||
(sd_device_get_devname(dev, &val) < 0 ||
|
||||
!streq_ptr(buf, path_startswith(val, "/dev/")))) {
|
||||
log_rule_error(dev, rules,
|
||||
"Kernel device nodes cannot be renamed, ignoring NAME=\"%s\"; please fix it.",
|
||||
token->value);
|
||||
break;
|
||||
}
|
||||
r = free_and_strdup_warn(&event->name, buf);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2096,7 +2105,8 @@ static int udev_rule_apply_token_to_event(
|
||||
else
|
||||
count = 0;
|
||||
if (count > 0)
|
||||
log_rule_debug(dev, rules, "Replaced %zu character(s) from result of LINK", count);
|
||||
log_rule_debug(dev, rules, "Replaced %zu character(s) from result of SYMLINK=\"%s\"",
|
||||
count, token->value);
|
||||
|
||||
p = skip_leading_chars(buf, NULL);
|
||||
while (!isempty(p)) {
|
||||
|
Loading…
Reference in New Issue
Block a user