summaryrefslogtreecommitdiff
path: root/udev/udev-rules.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2009-09-09 18:18:17 +0200
committerKay Sievers <kay.sievers@vrfy.org>2009-09-09 18:49:07 +0200
commit6c29f2b942358d4dd9d3e7c65c13c3612dded3cc (patch)
tree2604ad41d6cd00785e13caa5515996acc3e942ee /udev/udev-rules.c
parent7f06ec2e19387424de34bae35320c2fe192cb69d (diff)
simplify "symlink name stack"
With well defined and kernel-supplied node names, we no longer need to support a possible stack of conflicting symlinks and node names. Only symlinks with identical names can be claimed by multiple devices. This shrinks the former /dev/.udev/names/ significantly. Also the /dev/{block,char}/MAJ:MIN" links are excluded from the name stack - they are unique and can not conflict.
Diffstat (limited to 'udev/udev-rules.c')
-rw-r--r--udev/udev-rules.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/udev/udev-rules.c b/udev/udev-rules.c
index a85800adf2..904ddac72c 100644
--- a/udev/udev-rules.c
+++ b/udev/udev-rules.c
@@ -190,7 +190,8 @@ struct token {
unsigned int value_off;
union {
unsigned int attr_off;
- int ignore_error;
+ int devlink_unique;
+ int fail_on_error;
unsigned int rule_goto;
mode_t mode;
uid_t uid;
@@ -1011,7 +1012,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_A_GROUP:
case TK_A_MODE:
case TK_A_NAME:
- case TK_A_DEVLINK:
case TK_A_GOTO:
token->key.value_off = add_string(rule_tmp->rules, value);
break;
@@ -1024,6 +1024,10 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
token->key.value_off = add_string(rule_tmp->rules, value);
token->key.attr_off = add_string(rule_tmp->rules, attr);
break;
+ case TK_A_DEVLINK:
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ token->key.devlink_unique = *(int *)data;
+ break;
case TK_M_TEST:
token->key.value_off = add_string(rule_tmp->rules, value);
if (data != NULL)
@@ -1037,7 +1041,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
break;
case TK_A_RUN:
token->key.value_off = add_string(rule_tmp->rules, value);
- token->key.ignore_error = *(int *)data;
+ token->key.fail_on_error = *(int *)data;
break;
case TK_A_INOTIFY_WATCH:
case TK_A_NUM_FAKE_PART:
@@ -1432,10 +1436,16 @@ static int add_rule(struct udev_rules *rules, char *line,
}
if (strcmp(key, "SYMLINK") == 0) {
- if (op < OP_MATCH_MAX)
+ if (op < OP_MATCH_MAX) {
rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
- else
- rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
+ } else {
+ int flag = 0;
+
+ attr = get_key_attribute(rules->udev, key + sizeof("SYMLINK")-1);
+ if (attr != NULL && strstr(attr, "unique") != NULL)
+ flag = 1;
+ rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, &flag);
+ }
rule_tmp.rule.rule.flags = 1;
continue;
}
@@ -2445,26 +2455,22 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
while (isspace(pos[0]))
pos++;
next = strchr(pos, ' ');
- while (next) {
+ while (next != NULL) {
next[0] = '\0';
- info(event->udev, "LINK '%s' %s:%u\n",
- pos,
- &rules->buf[rule->rule.filename_off],
- rule->rule.filename_line);
+ info(event->udev, "LINK '%s' %s:%u\n", pos,
+ &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
- udev_device_add_devlink(event->dev, filename);
+ udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
while (isspace(next[1]))
next++;
pos = &next[1];
next = strchr(pos, ' ');
}
if (pos[0] != '\0') {
- info(event->udev, "LINK '%s' %s:%u\n",
- pos,
- &rules->buf[rule->rule.filename_off],
- rule->rule.filename_line);
+ info(event->udev, "LINK '%s' %s:%u\n", pos,
+ &rules->buf[rule->rule.filename_off], rule->rule.filename_line);
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(event->udev), "/", pos, NULL);
- udev_device_add_devlink(event->dev, filename);
+ udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique);
}
}
break;
@@ -2511,7 +2517,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
rule->rule.filename_line);
list_entry = udev_list_entry_add(event->udev, &event->run_list,
&rules->buf[cur->key.value_off], NULL, 1, 0);
- if (cur->key.ignore_error)
+ if (cur->key.fail_on_error)
udev_list_entry_set_flag(list_entry, 1);
break;
}