diff options
-rw-r--r-- | udev.h | 6 | ||||
-rw-r--r-- | udev_rules.c | 21 | ||||
-rw-r--r-- | udev_rules.h | 1 | ||||
-rw-r--r-- | udev_rules_parse.c | 5 | ||||
-rw-r--r-- | udev_utils.c | 12 | ||||
-rw-r--r-- | udevd.c | 7 |
6 files changed, 34 insertions, 18 deletions
@@ -138,10 +138,12 @@ extern int udev_db_get_all_entries(struct list_head *name_list); struct name_entry { struct list_head node; char name[PATH_SIZE]; + unsigned int ignore_error:1; }; + extern int log_priority(const char *priority); -extern char *name_list_add(struct list_head *name_list, const char *name, int sort); -extern char *name_list_key_add(struct list_head *name_list, const char *key, const char *value); +extern struct name_entry *name_list_add(struct list_head *name_list, const char *name, int sort); +extern struct name_entry *name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern int name_list_key_remove(struct list_head *name_list, const char *key); extern void name_list_cleanup(struct list_head *name_list); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); diff --git a/udev_rules.c b/udev_rules.c index cb74da56e3..b2b4809d79 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -911,12 +911,13 @@ try_parent: unsetenv(key_name); info("unset ENV '%s'", key_name); } else { - char *key_value = name_list_key_add(&udev->env_list, key_name, temp_value); + struct name_entry *entry; - if (key_value == NULL) + entry = name_list_key_add(&udev->env_list, key_name, temp_value); + if (entry == NULL) break; - putenv(key_value); - info("set ENV '%s'", key_value); + putenv(entry->name); + info("set ENV '%s'", entry->name); } } } @@ -1100,6 +1101,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) } if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { + struct name_entry *entry; + if (rule->run.operation == KEY_OP_ASSIGN_FINAL) udev->run_final = 1; if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { @@ -1107,7 +1110,9 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) name_list_cleanup(&udev->run_list); } dbg("add run '%s'", key_val(rule, &rule->run)); - name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + entry = name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + if (rule->run_ignore_error) + entry->ignore_error = 1; } if (rule->last_rule) { @@ -1165,13 +1170,17 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev) } if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { + struct name_entry *entry; + if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { info("reset run list"); name_list_cleanup(&udev->run_list); } dbg("add run '%s'", key_val(rule, &rule->run)); - name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + entry = name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); + if (rule->run_ignore_error) + entry->ignore_error = 1; if (rule->run.operation == KEY_OP_ASSIGN_FINAL) break; } diff --git a/udev_rules.h b/udev_rules.h index 682bedac01..038f6da84d 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -99,6 +99,7 @@ struct udev_rule { unsigned int link_priority; unsigned int partitions; unsigned int last_rule:1, + run_ignore_error:1, ignore_device:1, ignore_remove:1; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 9a12d53816..c4fa142b04 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -477,7 +477,10 @@ static int add_to_rules(struct udev_rules *rules, char *line, const char *filena continue; } - if (strcasecmp(key, "RUN") == 0) { + if (strncasecmp(key, "RUN", sizeof("RUN")-1) == 0) { + attr = get_key_attribute(key + sizeof("RUN")-1); + if (attr && strstr(attr, "ignore_error")) + rule->run_ignore_error = 1; add_rule_key(rule, &rule->run, operation, value); valid = 1; continue; diff --git a/udev_utils.c b/udev_utils.c index 6d646b0ee6..e2f84cf24a 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -54,7 +54,7 @@ int log_priority(const char *priority) return 0; } -char *name_list_add(struct list_head *name_list, const char *name, int sort) +struct name_entry *name_list_add(struct list_head *name_list, const char *name, int sort) { struct name_entry *loop_name; struct name_entry *new_name; @@ -63,7 +63,7 @@ char *name_list_add(struct list_head *name_list, const char *name, int sort) /* avoid doubles */ if (strcmp(loop_name->name, name) == 0) { dbg("'%s' is already in the list", name); - return loop_name->name; + return loop_name; } } @@ -81,10 +81,10 @@ char *name_list_add(struct list_head *name_list, const char *name, int sort) dbg("adding '%s'", new_name->name); list_add_tail(&new_name->node, &loop_name->node); - return new_name->name; + return new_name; } -char *name_list_key_add(struct list_head *name_list, const char *key, const char *value) +struct name_entry *name_list_key_add(struct list_head *name_list, const char *key, const char *value) { struct name_entry *loop_name; struct name_entry *new_name; @@ -94,7 +94,7 @@ char *name_list_key_add(struct list_head *name_list, const char *key, const char dbg("key already present '%s', replace it", loop_name->name); snprintf(loop_name->name, sizeof(loop_name->name), "%s=%s", key, value); loop_name->name[sizeof(loop_name->name)-1] = '\0'; - return loop_name->name; + return loop_name; } } @@ -107,7 +107,7 @@ char *name_list_key_add(struct list_head *name_list, const char *key, const char dbg("adding '%s'", new_name->name); list_add_tail(&new_name->node, &loop_name->node); - return new_name->name; + return new_name; } int name_list_key_remove(struct list_head *name_list, const char *key) @@ -148,8 +148,9 @@ static int udev_event_process(struct udevd_uevent_msg *msg) strlcpy(program, name_loop->name, sizeof(program)); udev_rules_apply_format(udev, program, sizeof(program)); if (run_program(program, udev->dev->subsystem, NULL, 0, NULL, - (udev_log_priority >= LOG_INFO))) - retval = -1; + (udev_log_priority >= LOG_INFO)) != 0) + if (!name_loop->ignore_error) + retval = -1; } } } @@ -258,7 +259,7 @@ static void udev_event_run(struct udevd_uevent_msg *msg) setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); retval = udev_event_process(msg); - info("seq %llu finished", msg->seqnum); + info("seq %llu finished with %i", msg->seqnum, retval); logging_close(); if (retval) |