From 35e0f989b7cc82bbd0c3a95647f4140eb745f9a1 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 13 Jan 2025 04:03:11 +0900 Subject: [PATCH] udev-rules: add more trace logs for string match (cherry picked from commit 0febeccfdc4839ace732280f06005e81f5cadff7) Resolves: RHEL-75774 --- src/udev/udev-rules.c | 81 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 3a61403338..35a3a9cc69 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -1821,10 +1821,11 @@ static bool apply_format_attr( return apply_format_full(event, token, token->data, result, result_size, /* replace_whitespace = */ false, what); } -static bool token_match_string(UdevRuleToken *token, const char *str) { +static bool token_match_string(UdevEvent *event, UdevRuleToken *token, const char *str, bool log_result) { const char *value; bool match = false, case_insensitive; + assert(event); assert(token); assert(token->value); assert(token->type < _TK_M_MAX); @@ -1873,7 +1874,51 @@ static bool token_match_string(UdevRuleToken *token, const char *str) { assert_not_reached(); } - return token->op == (match ? OP_MATCH : OP_NOMATCH); + bool result = token->op == (match ? OP_MATCH : OP_NOMATCH); + + if (event->trace) + switch (token->match_type & _MATCH_TYPE_MASK) { + case MATCH_TYPE_EMPTY: + log_event_trace(event, token, "String \"%s\" is%s empty%s", + strempty(str), match ? "" : " not", + log_result ? result ? ": PASS" : ": FAIL" : "."); + break; + case MATCH_TYPE_SUBSYSTEM: + log_event_trace(event, token, + "String \"%s\" matches %s of \"subsystem\", \"class\", or \"bus\"%s", + strempty(str), match ? "one" : "neither", + log_result ? result ? ": PASS" : ": FAIL" : "."); + break; + case MATCH_TYPE_PLAIN_WITH_EMPTY: + case MATCH_TYPE_PLAIN: + case MATCH_TYPE_GLOB_WITH_EMPTY: + case MATCH_TYPE_GLOB: { + _cleanup_free_ char *joined = NULL; + unsigned c = 0; + + if (IN_SET(token->match_type & _MATCH_TYPE_MASK, MATCH_TYPE_PLAIN_WITH_EMPTY, MATCH_TYPE_GLOB_WITH_EMPTY)) { + (void) strextend_with_separator(&joined, ", ", "\"\""); + c++; + } + + NULSTR_FOREACH(i, value) { + (void) strextendf_with_separator(&joined, ", ", "\"%s\"", i); + c++; + } + + assert(c > 0); + log_event_trace(event, token, "String \"%s\" %s %s%s", + strempty(str), + match ? (c > 1 ? "matches one of" : "matches") : (c > 1 ? "matches neither of" : "does not match"), + strempty(joined), + log_result ? result ? ": PASS" : ": FAIL" : "."); + break; + } + default: + assert_not_reached(); + } + + return result; } static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *event) { @@ -1904,7 +1949,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev value = delete_trailing_chars(vbuf, NULL); } - return token_match_string(token, value); + return token_match_string(event, token, value, /* log_result = */ true); case SUBST_TYPE_SUBSYS: if (udev_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) < 0) @@ -1914,7 +1959,7 @@ static bool token_match_attr(UdevRuleToken *token, sd_device *dev, UdevEvent *ev if (FLAGS_SET(token->match_type, MATCH_REMOVE_TRAILING_WHITESPACE)) delete_trailing_chars(vbuf, NULL); - return token_match_string(token, vbuf); + return token_match_string(event, token, vbuf, /* log_result = */ true); default: assert_not_reached(); @@ -2074,7 +2119,7 @@ static int udev_rule_apply_token_to_event( if (r < 0) return log_event_error_errno(event, token, r, "Failed to get uevent action type: %m"); - return token_match_string(token, device_action_to_string(a)); + return token_match_string(event, token, device_action_to_string(a), /* log_result = */ true); } case TK_M_DEVPATH: { const char *val; @@ -2083,7 +2128,7 @@ static int udev_rule_apply_token_to_event( if (r < 0) return log_event_error_errno(event, token, r, "Failed to get devpath: %m"); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_KERNEL: case TK_M_PARENTS_KERNEL: { @@ -2093,21 +2138,23 @@ static int udev_rule_apply_token_to_event( if (r < 0) return log_event_error_errno(event, token, r, "Failed to get sysname: %m"); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_DEVLINK: FOREACH_DEVICE_DEVLINK(dev, val) - if (token_match_string(token, strempty(startswith(val, "/dev/"))) == (token->op == OP_MATCH)) + if (token_match_string(event, token, strempty(startswith(val, "/dev/")), /* log_result = */ false) == (token->op == OP_MATCH)) return token->op == OP_MATCH; return token->op == OP_NOMATCH; + case TK_M_NAME: - return token_match_string(token, event->name); + return token_match_string(event, token, event->name, /* log_result = */ true); + case TK_M_ENV: { const char *val = NULL; (void) device_get_property_value_with_fallback(dev, token->data, event->worker ? event->worker->properties : NULL, &val); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_CONST: { const char *val, *k = token->data; @@ -2120,14 +2167,15 @@ static int udev_rule_apply_token_to_event( val = confidential_virtualization_to_string(detect_confidential_virtualization()); else assert_not_reached(); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_TAG: case TK_M_PARENTS_TAG: FOREACH_DEVICE_CURRENT_TAG(dev, val) - if (token_match_string(token, val) == (token->op == OP_MATCH)) + if (token_match_string(event, token, val, /* log_result = */ false) == (token->op == OP_MATCH)) return token->op == OP_MATCH; return token->op == OP_NOMATCH; + case TK_M_SUBSYSTEM: case TK_M_PARENTS_SUBSYSTEM: { const char *val; @@ -2138,7 +2186,7 @@ static int udev_rule_apply_token_to_event( else if (r < 0) return log_event_error_errno(event, token, r, "Failed to get subsystem: %m"); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_DRIVER: case TK_M_PARENTS_DRIVER: { @@ -2150,11 +2198,12 @@ static int udev_rule_apply_token_to_event( else if (r < 0) return log_event_error_errno(event, token, r, "Failed to get driver: %m"); - return token_match_string(token, val); + return token_match_string(event, token, val, /* log_result = */ true); } case TK_M_ATTR: case TK_M_PARENTS_ATTR: return token_match_attr(token, dev, event); + case TK_M_SYSCTL: { _cleanup_free_ char *value = NULL; char buf[UDEV_PATH_SIZE]; @@ -2166,7 +2215,7 @@ static int udev_rule_apply_token_to_event( if (r < 0 && r != -ENOENT) return log_event_error_errno(event, token, r, "Failed to read sysctl '%s': %m", buf); - return token_match_string(token, strstrip(value)); + return token_match_string(event, token, strstrip(value), /* log_result = */ true); } case TK_M_TEST: { mode_t mode = PTR_TO_MODE(token->data); @@ -2429,7 +2478,7 @@ static int udev_rule_apply_token_to_event( return token->op == (r > 0 ? OP_MATCH : OP_NOMATCH); } case TK_M_RESULT: - return token_match_string(token, event->program_result); + return token_match_string(event, token, event->program_result, /* log_result = */ true); case TK_A_OPTIONS_STRING_ESCAPE_NONE: event->esc = ESCAPE_NONE; break;