diff options
Diffstat (limited to 'src/udev/udev-rules.c')
-rw-r--r-- | src/udev/udev-rules.c | 121 |
1 files changed, 56 insertions, 65 deletions
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 5f12002..581bbaf 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -691,9 +691,7 @@ static int parse_token(UdevRuleLine *rule_line, const char *key, char *attr, Ude } if (!is_match) { - if (STR_IN_SET(attr, - "ACTION", "DEVLINKS", "DEVNAME", "DEVPATH", "DEVTYPE", "DRIVER", - "IFINDEX", "MAJOR", "MINOR", "SEQNUM", "SUBSYSTEM", "TAGS")) + if (!device_property_can_set(attr)) return log_line_error_errno(rule_line, SYNTHETIC_ERRNO(EINVAL), "Invalid ENV attribute. '%s' cannot be set.", attr); @@ -1538,7 +1536,7 @@ int udev_rules_parse_file(UdevRules *rules, const char *filename, bool extra_che r = hashmap_put_stats_by_path(&rules->stats_by_path, filename, &st); if (r < 0) - return log_warning_errno(errno, "Failed to save stat for %s, ignoring: %m", filename); + return log_warning_errno(r, "Failed to save stat for %s, ignoring: %m", filename); (void) fd_warn_permissions(filename, fileno(f)); @@ -1761,7 +1759,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev switch (token->attr_subst_type) { case SUBST_TYPE_FORMAT: - (void) udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false, NULL, &truncated); + (void) udev_event_apply_format(event, name, nbuf, sizeof(nbuf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "sysfs attribute name", name, token->type == TK_M_ATTR ? "ATTR" : "ATTRS", /* is_match = */ true); @@ -1928,10 +1926,7 @@ static size_t udev_replace_ifname(char *str) { static int udev_rule_apply_token_to_event( UdevRuleToken *token, sd_device *dev, - UdevEvent *event, - usec_t timeout_usec, - int timeout_signal, - Hashmap *properties_list) { + UdevEvent *event) { int r; @@ -1983,7 +1978,7 @@ static int udev_rule_apply_token_to_event( case TK_M_ENV: { const char *val = NULL; - (void) device_get_property_value_with_fallback(dev, token->data, properties_list, &val); + (void) device_get_property_value_with_fallback(dev, token->data, event->worker ? event->worker->properties : NULL, &val); return token_match_string(token, val); } @@ -2038,7 +2033,7 @@ static int udev_rule_apply_token_to_event( char buf[UDEV_PATH_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "sysctl entry name", token->data, "SYSCTL", /* is_match = */ true); return false; @@ -2056,7 +2051,7 @@ static int udev_rule_apply_token_to_event( struct stat statbuf; bool match, truncated; - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "file name", token->value, "TEST", /* is_match = */ true); return false; @@ -2099,15 +2094,15 @@ static int udev_rule_apply_token_to_event( size_t count; event->program_result = mfree(event->program_result); - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "command", token->value, "PROGRAM", /* is_match = */ true); return false; } - log_event_debug(dev, token, "Running PROGRAM '%s'", buf); + log_event_debug(dev, token, "Running PROGRAM=\"%s\"", buf); - r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof(result), NULL); + r = udev_event_spawn(event, /* accept_failure = */ true, buf, result, sizeof(result), NULL); if (r != 0) { if (r < 0) log_event_warning_errno(dev, token, r, "Failed to execute \"%s\": %m", buf); @@ -2131,7 +2126,7 @@ static int udev_rule_apply_token_to_event( char buf[UDEV_PATH_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "file name to be imported", token->value, "IMPORT", /* is_match = */ true); return false; @@ -2182,7 +2177,7 @@ static int udev_rule_apply_token_to_event( char buf[UDEV_LINE_SIZE], result[UDEV_LINE_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "command", token->value, "IMPORT", /* is_match = */ true); return false; @@ -2190,7 +2185,7 @@ static int udev_rule_apply_token_to_event( log_event_debug(dev, token, "Importing properties from results of '%s'", buf); - r = udev_event_spawn(event, timeout_usec, timeout_signal, true, buf, result, sizeof result, &truncated); + r = udev_event_spawn(event, /* accept_failure = */ true, buf, result, sizeof result, &truncated); if (r != 0) { if (r < 0) log_event_warning_errno(dev, token, r, "Failed to execute '%s', ignoring: %m", buf); @@ -2261,7 +2256,7 @@ static int udev_rule_apply_token_to_event( event->builtin_run |= mask; } - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "builtin command", token->value, "IMPORT", /* is_match = */ true); return false; @@ -2269,7 +2264,7 @@ static int udev_rule_apply_token_to_event( log_event_debug(dev, token, "Importing properties from results of builtin command '%s'", buf); - r = udev_builtin_run(event, cmd, buf, false); + r = udev_builtin_run(event, cmd, buf); if (r < 0) { /* remember failure */ log_event_debug_errno(dev, token, r, "Failed to run builtin '%s': %m", buf); @@ -2317,7 +2312,7 @@ static int udev_rule_apply_token_to_event( char buf[UDEV_PATH_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "property name", token->value, "IMPORT", /* is_match = */ true); return false; @@ -2378,7 +2373,7 @@ static int udev_rule_apply_token_to_event( if (token->op == OP_ASSIGN_FINAL) event->owner_final = true; - (void) udev_event_apply_format(event, token->value, owner, sizeof(owner), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, owner, sizeof(owner), false, &truncated); if (truncated) { log_event_truncated(dev, token, "user name", token->value, "OWNER", /* is_match = */ false); break; @@ -2401,7 +2396,7 @@ static int udev_rule_apply_token_to_event( if (token->op == OP_ASSIGN_FINAL) event->group_final = true; - (void) udev_event_apply_format(event, token->value, group, sizeof(group), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, group, sizeof(group), false, &truncated); if (truncated) { log_event_truncated(dev, token, "group name", token->value, "GROUP", /* is_match = */ false); break; @@ -2423,7 +2418,7 @@ static int udev_rule_apply_token_to_event( if (token->op == OP_ASSIGN_FINAL) event->mode_final = true; - (void) udev_event_apply_format(event, token->value, mode_str, sizeof(mode_str), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, mode_str, sizeof(mode_str), false, &truncated); if (truncated) { log_event_truncated(dev, token, "mode", token->value, "MODE", /* is_match = */ false); break; @@ -2475,7 +2470,7 @@ static int udev_rule_apply_token_to_event( if (!name) return log_oom(); - (void) udev_event_apply_format(event, token->value, label_str, sizeof(label_str), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, label_str, sizeof(label_str), false, &truncated); if (truncated) { log_event_truncated(dev, token, "security label", token->value, "SECLABEL", /* is_match = */ false); break; @@ -2519,7 +2514,7 @@ static int udev_rule_apply_token_to_event( } if (token->op == OP_ADD && - device_get_property_value_with_fallback(dev, name, properties_list, &val) >= 0) { + device_get_property_value_with_fallback(dev, name, event->worker ? event->worker->properties : NULL, &val) >= 0) { l = strpcpyl_full(&p, l, &truncated, val, " ", NULL); if (truncated) { log_event_warning(dev, token, @@ -2529,7 +2524,7 @@ static int udev_rule_apply_token_to_event( } } - (void) udev_event_apply_format(event, token->value, p, l, false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, p, l, false, &truncated); if (truncated) { _cleanup_free_ char *key_with_name = strjoin("ENV{", name, "}"); log_event_truncated(dev, token, "property value", token->value, @@ -2554,7 +2549,7 @@ static int udev_rule_apply_token_to_event( char buf[UDEV_PATH_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "tag name", token->value, "TAG", /* is_match = */ false); break; @@ -2591,7 +2586,7 @@ static int udev_rule_apply_token_to_event( break; } - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "network interface name", token->value, "NAME", /* is_match = */ false); break; @@ -2629,7 +2624,7 @@ static int udev_rule_apply_token_to_event( device_cleanup_devlinks(dev); (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), - /* replace_whitespace = */ event->esc != ESCAPE_NONE, properties_list, &truncated); + /* replace_whitespace = */ event->esc != ESCAPE_NONE, &truncated); if (truncated) { log_event_truncated(dev, token, "symbolic link path", token->value, "SYMLINK", /* is_match = */ false); break; @@ -2701,33 +2696,37 @@ static int udev_rule_apply_token_to_event( log_event_error_errno(dev, token, r, "Could not find file matches '%s', ignoring: %m", buf); break; } - (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, &truncated); if (truncated) { log_event_truncated(dev, token, "attribute value", token->value, "ATTR", /* is_match = */ false); break; } - log_event_debug(dev, token, "ATTR '%s' writing '%s'", buf, value); - r = write_string_file(buf, value, - WRITE_STRING_FILE_VERIFY_ON_FAILURE | - WRITE_STRING_FILE_DISABLE_BUFFER | - WRITE_STRING_FILE_AVOID_NEWLINE | - WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE); - if (r < 0) - log_event_error_errno(dev, token, r, "Failed to write ATTR{%s}, ignoring: %m", buf); + if (EVENT_MODE_DESTRUCTIVE(event)) { + log_event_debug(dev, token, "Writing ATTR{'%s'}=\"%s\".", buf, value); + r = write_string_file(buf, value, + WRITE_STRING_FILE_VERIFY_ON_FAILURE | + WRITE_STRING_FILE_DISABLE_BUFFER | + WRITE_STRING_FILE_AVOID_NEWLINE | + WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE); + if (r < 0) + log_event_error_errno(dev, token, r, "Failed to write ATTR{%s}=\"%s\", ignoring: %m", buf, value); + } else + log_event_debug(dev, token, "Running in test mode, skipping writing ATTR{%s}=\"%s\".", buf, value); + break; } case TK_A_SYSCTL: { char buf[UDEV_PATH_SIZE], value[UDEV_NAME_SIZE]; bool truncated; - (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->data, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "sysctl entry name", token->data, "SYSCTL", /* is_match = */ false); break; } - (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, value, sizeof(value), false, &truncated); if (truncated) { _cleanup_free_ char *key_with_name = strjoin("SYSCTL{", buf, "}"); log_event_truncated(dev, token, "sysctl value", token->value, @@ -2736,10 +2735,15 @@ static int udev_rule_apply_token_to_event( } sysctl_normalize(buf); - log_event_debug(dev, token, "SYSCTL '%s' writing '%s'", buf, value); - r = sysctl_write(buf, value); - if (r < 0) - log_event_error_errno(dev, token, r, "Failed to write SYSCTL{%s}='%s', ignoring: %m", buf, value); + + if (EVENT_MODE_DESTRUCTIVE(event)) { + log_event_debug(dev, token, "Writing SYSCTL{%s}=\"%s\".", buf, value); + r = sysctl_write(buf, value); + if (r < 0) + log_event_error_errno(dev, token, r, "Failed to write SYSCTL{%s}=\"%s\", ignoring: %m", buf, value); + } else + log_event_debug(dev, token, "Running in test mode, skipping writing SYSCTL{%s}=\"%s\".", buf, value); + break; } case TK_A_RUN_BUILTIN: @@ -2756,7 +2760,7 @@ static int udev_rule_apply_token_to_event( if (IN_SET(token->op, OP_ASSIGN, OP_ASSIGN_FINAL)) ordered_hashmap_clear_free_key(event->run_list); - (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, properties_list, &truncated); + (void) udev_event_apply_format(event, token->value, buf, sizeof(buf), false, &truncated); if (truncated) { log_event_truncated(dev, token, "command", token->value, token->type == TK_A_RUN_BUILTIN ? "RUN{builtin}" : "RUN{program}", @@ -2793,11 +2797,7 @@ static bool token_is_for_parents(UdevRuleToken *token) { return token->type >= TK_M_PARENTS_KERNEL && token->type <= TK_M_PARENTS_TAG; } -static int udev_rule_apply_parent_token_to_event( - UdevRuleToken *head_token, - UdevEvent *event, - int timeout_signal) { - +static int udev_rule_apply_parent_token_to_event(UdevRuleToken *head_token, UdevEvent *event) { int r; assert(head_token); @@ -2810,7 +2810,7 @@ static int udev_rule_apply_parent_token_to_event( if (!token_is_for_parents(token)) return true; /* All parent tokens match. */ - r = udev_rule_apply_token_to_event(token, event->dev_parent, event, 0, timeout_signal, NULL); + r = udev_rule_apply_token_to_event(token, event->dev_parent, event); if (r < 0) return r; if (r == 0) @@ -2830,9 +2830,6 @@ static int udev_rule_apply_parent_token_to_event( static int udev_rule_apply_line_to_event( UdevRuleLine *line, UdevEvent *event, - usec_t timeout_usec, - int timeout_signal, - Hashmap *properties_list, UdevRuleLine **next_line) { UdevRuleLineType mask = LINE_HAS_GOTO | LINE_UPDATE_SOMETHING; @@ -2868,7 +2865,7 @@ static int udev_rule_apply_line_to_event( if (parents_done) continue; - r = udev_rule_apply_parent_token_to_event(token, event, timeout_signal); + r = udev_rule_apply_parent_token_to_event(token, event); if (r <= 0) return r; @@ -2876,7 +2873,7 @@ static int udev_rule_apply_line_to_event( continue; } - r = udev_rule_apply_token_to_event(token, event->dev, event, timeout_usec, timeout_signal, properties_list); + r = udev_rule_apply_token_to_event(token, event->dev, event); if (r <= 0) return r; } @@ -2887,13 +2884,7 @@ static int udev_rule_apply_line_to_event( return 0; } -int udev_rules_apply_to_event( - UdevRules *rules, - UdevEvent *event, - usec_t timeout_usec, - int timeout_signal, - Hashmap *properties_list) { - +int udev_rules_apply_to_event(UdevRules *rules, UdevEvent *event) { int r; assert(rules); @@ -2901,7 +2892,7 @@ int udev_rules_apply_to_event( LIST_FOREACH(rule_files, file, rules->rule_files) LIST_FOREACH_WITH_NEXT(rule_lines, line, next_line, file->rule_lines) { - r = udev_rule_apply_line_to_event(line, event, timeout_usec, timeout_signal, properties_list, &next_line); + r = udev_rule_apply_line_to_event(line, event, &next_line); if (r < 0) return r; } |