mirror of
https://github.com/systemd/systemd.git
synced 2024-11-24 02:33:36 +08:00
udev: add SYSCTL{} support
This commit is contained in:
parent
88a60da054
commit
f4cf2e5b2f
12
man/udev.xml
12
man/udev.xml
@ -193,6 +193,11 @@
|
||||
value itself contains trailing whitespace.
|
||||
</para>
|
||||
</listitem>
|
||||
<term><varname>SYSCTL{<replaceable>kernel parameter</replaceable>}</varname></term>
|
||||
<listitem>
|
||||
<para>Match a kernel parameter value.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -374,6 +379,13 @@
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>SYSCTL{<replaceable>kernel parameter</replaceable>}</varname></term>
|
||||
<listitem>
|
||||
<para>The value that should be written to kernel parameter.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ENV{<replaceable>key</replaceable>}</varname></term>
|
||||
<listitem>
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "strbuf.h"
|
||||
#include "strv.h"
|
||||
#include "util.h"
|
||||
#include "sysctl-util.h"
|
||||
|
||||
#define PREALLOC_TOKEN 2048
|
||||
|
||||
@ -128,6 +129,7 @@ enum token_type {
|
||||
TK_M_DRIVER, /* val */
|
||||
TK_M_WAITFOR, /* val */
|
||||
TK_M_ATTR, /* val, attr */
|
||||
TK_M_SYSCTL, /* val, attr */
|
||||
|
||||
TK_M_PARENTS_MIN,
|
||||
TK_M_KERNELS, /* val */
|
||||
@ -166,6 +168,7 @@ enum token_type {
|
||||
TK_A_NAME, /* val */
|
||||
TK_A_DEVLINK, /* val */
|
||||
TK_A_ATTR, /* val, attr */
|
||||
TK_A_SYSCTL, /* val, attr */
|
||||
TK_A_RUN_BUILTIN, /* val, bool */
|
||||
TK_A_RUN_PROGRAM, /* val, bool */
|
||||
TK_A_GOTO, /* size_t */
|
||||
@ -262,6 +265,7 @@ static const char *token_str(enum token_type type) {
|
||||
[TK_M_DRIVER] = "M DRIVER",
|
||||
[TK_M_WAITFOR] = "M WAITFOR",
|
||||
[TK_M_ATTR] = "M ATTR",
|
||||
[TK_M_SYSCTL] = "M SYSCTL",
|
||||
|
||||
[TK_M_PARENTS_MIN] = "M PARENTS_MIN",
|
||||
[TK_M_KERNELS] = "M KERNELS",
|
||||
@ -300,6 +304,7 @@ static const char *token_str(enum token_type type) {
|
||||
[TK_A_NAME] = "A NAME",
|
||||
[TK_A_DEVLINK] = "A DEVLINK",
|
||||
[TK_A_ATTR] = "A ATTR",
|
||||
[TK_A_SYSCTL] = "A SYSCTL",
|
||||
[TK_A_RUN_BUILTIN] = "A RUN_BUILTIN",
|
||||
[TK_A_RUN_PROGRAM] = "A RUN_PROGRAM",
|
||||
[TK_A_GOTO] = "A GOTO",
|
||||
@ -363,9 +368,11 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
|
||||
log_debug("%s %i '%s'", token_str(type), token->key.builtin_cmd, value);
|
||||
break;
|
||||
case TK_M_ATTR:
|
||||
case TK_M_SYSCTL:
|
||||
case TK_M_ATTRS:
|
||||
case TK_M_ENV:
|
||||
case TK_A_ATTR:
|
||||
case TK_A_SYSCTL:
|
||||
case TK_A_ENV:
|
||||
log_debug("%s %s '%s' '%s'(%s)",
|
||||
token_str(type), operation_str(op), attr, value, string_glob_str(glob));
|
||||
@ -897,8 +904,10 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
||||
break;
|
||||
case TK_M_ENV:
|
||||
case TK_M_ATTR:
|
||||
case TK_M_SYSCTL:
|
||||
case TK_M_ATTRS:
|
||||
case TK_A_ATTR:
|
||||
case TK_A_SYSCTL:
|
||||
case TK_A_ENV:
|
||||
case TK_A_SECLABEL:
|
||||
attr = data;
|
||||
@ -1135,11 +1144,27 @@ static int add_rule(struct udev_rules *rules, char *line,
|
||||
log_error("invalid ATTR operation");
|
||||
goto invalid;
|
||||
}
|
||||
if (op < OP_MATCH_MAX) {
|
||||
if (op < OP_MATCH_MAX)
|
||||
rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr);
|
||||
} else {
|
||||
else
|
||||
rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (startswith(key, "SYSCTL{")) {
|
||||
attr = get_key_attribute(rules->udev, key + strlen("SYSCTL"));
|
||||
if (attr == NULL) {
|
||||
log_error("error parsing SYSCTL attribute");
|
||||
goto invalid;
|
||||
}
|
||||
if (op == OP_REMOVE) {
|
||||
log_error("invalid SYSCTL operation");
|
||||
goto invalid;
|
||||
}
|
||||
if (op < OP_MATCH_MAX)
|
||||
rule_add_key(&rule_tmp, TK_M_SYSCTL, op, value, attr);
|
||||
else
|
||||
rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1986,6 +2011,23 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
|
||||
if (match_attr(rules, event->dev, event, cur) != 0)
|
||||
goto nomatch;
|
||||
break;
|
||||
case TK_M_SYSCTL: {
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
_cleanup_free_ char *value = NULL;
|
||||
size_t len;
|
||||
|
||||
udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
|
||||
sysctl_normalize(filename);
|
||||
if (sysctl_read(filename, &value) < 0)
|
||||
goto nomatch;
|
||||
|
||||
len = strlen(value);
|
||||
while (len > 0 && isspace(value[--len]))
|
||||
value[len] = '\0';
|
||||
if (match_key(rules, cur, value) != 0)
|
||||
goto nomatch;
|
||||
break;
|
||||
}
|
||||
case TK_M_KERNELS:
|
||||
case TK_M_SUBSYSTEMS:
|
||||
case TK_M_DRIVERS:
|
||||
@ -2522,6 +2564,21 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TK_A_SYSCTL: {
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
char value[UTIL_NAME_SIZE];
|
||||
int r;
|
||||
|
||||
udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename));
|
||||
sysctl_normalize(filename);
|
||||
udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value));
|
||||
log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value,
|
||||
rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
|
||||
r = sysctl_write(filename, value);
|
||||
if (r < 0)
|
||||
log_error("error writing SYSCTL{%s}='%s': %s", filename, value, strerror(-r));
|
||||
break;
|
||||
}
|
||||
case TK_A_RUN_BUILTIN:
|
||||
case TK_A_RUN_PROGRAM: {
|
||||
struct udev_list_entry *entry;
|
||||
|
Loading…
Reference in New Issue
Block a user