summaryrefslogtreecommitdiff
path: root/src/udev/udev-rules.c
diff options
context:
space:
mode:
authorIan Stakenvicius <axs@gentoo.org>2013-07-11 14:04:02 -0400
committerIan Stakenvicius <axs@gentoo.org>2013-08-02 12:03:36 -0400
commitd9488d78ebc2dde8ac4065381780e4d974056e92 (patch)
tree18fadf819a86da759cc9ad49807802dfa20d530a /src/udev/udev-rules.c
parente2f82dc60f6fc7988c258ebb0aa27e112ad3ce04 (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.c65
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;