diff options
author | Ian Stakenvicius <axs@gentoo.org> | 2013-07-11 14:04:02 -0400 |
---|---|---|
committer | Ian Stakenvicius <axs@gentoo.org> | 2013-08-02 12:03:36 -0400 |
commit | d9488d78ebc2dde8ac4065381780e4d974056e92 (patch) | |
tree | 18fadf819a86da759cc9ad49807802dfa20d530a /src/udev/udev-rules.c | |
parent | e2f82dc60f6fc7988c258ebb0aa27e112ad3ce04 (diff) |
rule-generator: proactively rename ifaces to avoid conflicts
When a new network iface device is added, scan through the list of rules to see if its
kernel-assigned name is used as a target for another device. If so, and said target device
is not this device, rename it to a temporary interface name. Then rename the device in
accordance with any rename rules that may apply to this device, if applicable.
The temporary name assigned is the basename of the interface with a numeric compoment which is
close to the inverse of the numeric id (127 - id#). This should provide a more user-friendly
output than the old 'rename#' behaviour, when there is no final target name for the iface.
This proactive temporary rename will prevent cases where old-style rule-generator rules are used
and a target NAME= is set for one iface, assigning it to the iface name used by a second iface,
and that second iface has no rename rule to apply. The original rename code would be blocked
due to the conflict and time out when attempting to rename, leaving the interface assigned to the
temporary 'rename[id#]' name and/or failing to rename other ifaces in accordance with the existing
rules. This is a corner case that only occurrs when 75-persistent-net-generator.rules or the
write_net_rules script it 'IMPORTS' fails to generate a new rule and rename the interface and
there is no other interface-renaming rules that apply.
There may also be performance benefits to renaming ifaces early, but no benchmarks have been
run to confirm this.
Signed-off-by: Ian Stakenvicius <axs@gentoo.org>
Diffstat (limited to 'src/udev/udev-rules.c')
-rw-r--r-- | src/udev/udev-rules.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index f6c2b7943c..2c28ef7e20 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1849,6 +1849,71 @@ enum escape_type { ESCAPE_REPLACE, }; +#ifdef ENABLE_RULE_GENERATOR +/* function to return the count of rules that assign NAME= to a value matching arg#2 - returns 0,1 */ +int udev_rules_assigning_name_to(struct udev_rules *rules, const char *match_name) +{ + struct token *cur; + struct token *rule; + enum escape_type esc = ESCAPE_UNSET; + bool name_final = false; + + if (rules->tokens == NULL) + return 0; + + /* loop through token list, match, run actions or forward to next rule */ + cur = &rules->tokens[0]; + rule = cur; + for (;;) { + dump_token(rules, cur); + switch (cur->type) { + case TK_RULE: + /* current rule */ + rule = cur; + if (!rule->rule.can_set_name) + goto nomatch; + break; + case TK_M_SUBSYSTEM: + if (match_key(rules, cur, "net") != 0) + goto nomatch; + break; + case TK_M_ACTION: + if (match_key(rules, cur, "add") != 0) + goto nomatch; + break; + case TK_A_NAME: { + const char *name = rules_str(rules, cur->key.value_off); + char name_str[UTIL_PATH_SIZE]; + int count; + + strscpy(name_str,UTIL_PATH_SIZE,name); + count = util_replace_chars(name_str, "/"); + if (count > 0) + log_debug("%i character(s) replaced\n", count); + if (streq(name_str,match_name)) { + log_debug("found a match! NAME assigns %s in: %s:%u\n", + name, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + return 1; /* no need to find more than one */ + } + + /* skip to next rule */ + goto nomatch; + } + case TK_END: + return 0; + } + + cur++; + continue; + nomatch: + /* fast-forward to next rule */ + cur = rule + rule->rule.token_count; + } +} +#endif + int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, const sigset_t *sigmask) { struct token *cur; |