X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=src%2Fudev%2Fudev-rules.c;h=f6f640a21614384abdb8da095d6f21086aff3562;hb=49c603bd5ef9c36052623d820ab361a6d99173de;hp=ad4b32abea063540885211b28cbaa12b10334dd5;hpb=e67813dde00663e99b438fb702e58029971e0645;p=thirdparty%2Fsystemd.git diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index ad4b32abea0..f6f640a2161 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -15,7 +15,6 @@ #include "alloc-util.h" #include "conf-files.h" -#include "def.h" #include "device-private.h" #include "device-util.h" #include "dirent-util.h" @@ -24,7 +23,9 @@ #include "fileio.h" #include "fs-util.h" #include "glob-util.h" -#include "libudev-private.h" +#include "libudev-util.h" +#include "mkdir.h" +#include "parse-util.h" #include "path-util.h" #include "proc-cmdline.h" #include "stat-util.h" @@ -32,6 +33,7 @@ #include "strbuf.h" #include "string-util.h" #include "strv.h" +#include "strxcpyx.h" #include "sysctl-util.h" #include "udev-builtin.h" #include "udev.h" @@ -57,7 +59,7 @@ static const char* const rules_dirs[] = { struct udev_rules { usec_t dirs_ts_usec; - int resolve_names; + ResolveNameTiming resolve_name_timing; /* every key in the rules file becomes a token */ struct token *tokens; @@ -201,7 +203,7 @@ struct token { union { unsigned attr_off; unsigned rule_goto; - mode_t mode; + mode_t mode; uid_t uid; gid_t gid; int devlink_prio; @@ -220,7 +222,7 @@ struct rule_tmp { unsigned token_cur; }; -#ifdef DEBUG +#if ENABLE_DEBUG_UDEV static const char *operation_str(enum operation_type type) { static const char *operation_strs[] = { [OP_UNSET] = "UNSET", @@ -232,7 +234,7 @@ static const char *operation_str(enum operation_type type) { [OP_REMOVE] = "remove", [OP_ASSIGN] = "assign", [OP_ASSIGN_FINAL] = "assign-final", -} ; + }; return operation_strs[type]; } @@ -422,7 +424,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) { case TK_M_PARENTS_MAX: case TK_M_MAX: case TK_UNSET: - log_debug("unknown type %u", type); + log_debug("Unknown token type %u", type); break; } } @@ -430,7 +432,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) { static void dump_rules(struct udev_rules *rules) { unsigned i; - log_debug("dumping %u (%zu bytes) tokens, %zu (%zu bytes) strings", + log_debug("Dumping %u (%zu bytes) tokens, %zu (%zu bytes) strings", rules->token_cur, rules->token_cur * sizeof(struct token), rules->strbuf->nodes_count, @@ -441,7 +443,7 @@ static void dump_rules(struct udev_rules *rules) { #else static inline void dump_token(struct udev_rules *rules, struct token *token) {} static inline void dump_rules(struct udev_rules *rules) {} -#endif /* DEBUG */ +#endif /* ENABLE_DEBUG_UDEV */ static int add_token(struct udev_rules *rules, struct token *token) { /* grow buffer if needed */ @@ -455,7 +457,7 @@ static int add_token(struct udev_rules *rules, struct token *token) { add = 8; tokens = reallocarray(rules->tokens, rules->token_max + add, sizeof(struct token)); - if (tokens == NULL) + if (!tokens) return -1; rules->tokens = tokens; rules->token_max += add; @@ -465,11 +467,11 @@ static int add_token(struct udev_rules *rules, struct token *token) { return 0; } -static void log_unknown_owner(int error, const char *entity, const char *owner) { +static void log_unknown_owner(sd_device *dev, int error, const char *entity, const char *owner) { if (IN_SET(abs(error), ENOENT, ESRCH)) - log_error("Specified %s '%s' unknown", entity, owner); + log_device_error(dev, "Specified %s '%s' unknown", entity, owner); else - log_error_errno(error, "Error resolving %s '%s': %m", entity, owner); + log_device_error_errno(dev, error, "Failed to resolve %s '%s': %m", entity, owner); } static uid_t add_uid(struct udev_rules *rules, const char *owner) { @@ -488,7 +490,7 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) { } r = get_user_creds(&owner, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING); if (r < 0) - log_unknown_owner(r, "user", owner); + log_unknown_owner(NULL, r, "user", owner); /* grow buffer if needed */ if (rules->uids_cur+1 >= rules->uids_max) { @@ -501,7 +503,7 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) { add = 8; uids = reallocarray(rules->uids, rules->uids_max + add, sizeof(struct uid_gid)); - if (uids == NULL) + if (!uids) return uid; rules->uids = uids; rules->uids_max += add; @@ -531,7 +533,7 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) { } r = get_group_creds(&group, &gid, USER_CREDS_ALLOW_MISSING); if (r < 0) - log_unknown_owner(r, "group", group); + log_unknown_owner(NULL, r, "group", group); /* grow buffer if needed */ if (rules->gids_cur+1 >= rules->gids_max) { @@ -544,7 +546,7 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) { add = 8; gids = reallocarray(rules->gids, rules->gids_max + add, sizeof(struct uid_gid)); - if (gids == NULL) + if (!gids) return gid; rules->gids = gids; rules->gids_max += add; @@ -604,10 +606,10 @@ static int import_property_from_string(sd_device *dev, char *line) { /* unquote */ if (IN_SET(val[0], '"', '\'')) { - if (len == 1 || val[len-1] != val[0]) { - log_debug("inconsistent quoting: '%s', skip", line); - return -EINVAL; - } + if (len == 1 || val[len-1] != val[0]) + return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), + "Inconsistent quoting: '%s', skip", + line); val[len-1] = '\0'; val++; } @@ -640,22 +642,21 @@ static int import_file_into_properties(sd_device *dev, const char *filename) { static int import_program_into_properties(struct udev_event *event, usec_t timeout_usec, - usec_t timeout_warn_usec, const char *program) { char result[UTIL_LINE_SIZE]; char *line; int err; - err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, result, sizeof(result)); + err = udev_event_spawn(event, timeout_usec, true, program, result, sizeof(result)); if (err < 0) return err; line = result; - while (line != NULL) { + while (line) { char *pos; pos = strchr(line, '\n'); - if (pos != NULL) { + if (pos) { pos[0] = '\0'; pos = &pos[1]; } @@ -695,7 +696,7 @@ static void attr_subst_subdir(char *attr, size_t len) { tail = pos + 2; path = strndupa(attr, pos - attr + 1); /* include slash at end */ dir = opendir(path); - if (dir == NULL) + if (!dir) return; FOREACH_DIRENT_ALL(dent, dir, break) @@ -716,7 +717,7 @@ static int get_key(char **line, char **key, enum operation_type *op, char **valu unsigned i, j; linepos = *line; - if (linepos == NULL || linepos[0] == '\0') + if (!linepos || linepos[0] == '\0') return -1; /* skip whitespace */ @@ -817,10 +818,10 @@ static const char *get_key_attribute(char *str) { char *attr; attr = strchr(str, '{'); - if (attr != NULL) { + if (attr) { attr++; pos = strchr(attr, '}'); - if (pos == NULL) { + if (!pos) { log_error("Missing closing brace for format"); return NULL; } @@ -888,7 +889,7 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, break; case TK_M_TEST: token->key.value_off = rules_add_string(rule_tmp->rules, value); - if (data != NULL) + if (data) token->key.mode = *(mode_t *)data; break; case TK_A_STRING_ESCAPE_NONE: @@ -922,44 +923,43 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, assert_not_reached("wrong type"); } - if (value != NULL && type < TK_M_MAX) { + if (value && type < TK_M_MAX) { /* check if we need to split or call fnmatch() while matching rules */ enum string_glob_type glob; - int has_split; - int has_glob; + bool has_split, has_glob; - has_split = (strchr(value, '|') != NULL); + has_split = strchr(value, '|'); has_glob = string_is_glob(value); - if (has_split && has_glob) { + if (has_split && has_glob) glob = GL_SPLIT_GLOB; - } else if (has_split) { + else if (has_split) glob = GL_SPLIT; - } else if (has_glob) { + else if (has_glob) { if (streq(value, "?*")) glob = GL_SOMETHING; else glob = GL_GLOB; - } else { + } else glob = GL_PLAIN; - } + token->key.glob = glob; } - if (value != NULL && type > TK_M_MAX) { + if (value && type > TK_M_MAX) { /* check if assigned value has substitution chars */ if (value[0] == '[') token->key.subst = SB_SUBSYS; - else if (strchr(value, '%') != NULL || strchr(value, '$') != NULL) + else if (strchr(value, '%') || strchr(value, '$')) token->key.subst = SB_FORMAT; else token->key.subst = SB_NONE; } - if (attr != NULL) { + if (attr) { /* check if property/attribute name has substitution chars */ if (attr[0] == '[') token->key.attrsubst = SB_SUBSYS; - else if (strchr(attr, '%') != NULL || strchr(attr, '$') != NULL) + else if (strchr(attr, '%') || strchr(attr, '$')) token->key.attrsubst = SB_FORMAT; else token->key.attrsubst = SB_NONE; @@ -1004,9 +1004,10 @@ static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) { return 0; } -#define LOG_RULE_ERROR(fmt, ...) log_error("Invalid rule %s:%u: " fmt, filename, lineno, ##__VA_ARGS__) -#define LOG_RULE_WARNING(fmt, ...) log_warning("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__) -#define LOG_RULE_DEBUG(fmt, ...) log_debug("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__) +#define LOG_RULE_FULL(level, fmt, ...) log_full(level, "%s:%u: " fmt, filename, lineno, ##__VA_ARGS__) +#define LOG_RULE_ERROR(fmt, ...) LOG_RULE_FULL(LOG_ERR, fmt, ##__VA_ARGS__) +#define LOG_RULE_WARNING(fmt, ...) LOG_RULE_FULL(LOG_WARNING, fmt, ##__VA_ARGS__) +#define LOG_RULE_DEBUG(fmt, ...) LOG_RULE_FULL(LOG_DEBUG, fmt, ##__VA_ARGS__) #define LOG_AND_RETURN(fmt, ...) { LOG_RULE_ERROR(fmt, __VA_ARGS__); return; } static void add_rule(struct udev_rules *rules, char *line, @@ -1043,38 +1044,37 @@ static void add_rule(struct udev_rules *rules, char *line, _cleanup_free_ char *tmp; tmp = cescape(buf); - log_error("invalid key/value pair in file %s on line %u, starting at character %tu ('%s')", - filename, lineno, linepos - line + 1, tmp); + LOG_RULE_ERROR("Invalid key/value pair, starting at character %tu ('%s')", linepos - line + 1, tmp); if (*linepos == '#') - log_error("hint: comments can only start at beginning of line"); + LOG_RULE_ERROR("Hint: comments can only start at beginning of line"); } break; } if (rule_tmp.token_cur >= ELEMENTSOF(rule_tmp.token)) - LOG_AND_RETURN("temporary rule array too small, aborting event processing with %u items", rule_tmp.token_cur); + LOG_AND_RETURN("Temporary rule array too small, aborting event processing with %u items", rule_tmp.token_cur); if (streq(key, "ACTION")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL); } else if (streq(key, "DEVPATH")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL); } else if (streq(key, "KERNEL")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL); } else if (streq(key, "SUBSYSTEM")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); /* bus, class, subsystem events should all be the same */ if (STR_IN_SET(value, "subsystem", "bus", "class")) { @@ -1087,17 +1087,17 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (streq(key, "DRIVER")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL); } else if (startswith(key, "ATTR{")) { attr = get_key_attribute(key + STRLEN("ATTR")); - if (attr == NULL) - LOG_AND_RETURN("error parsing %s attribute", "ATTR"); + if (!attr) + LOG_AND_RETURN("Failed to parse %s attribute", "ATTR"); if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "ATTR"); + LOG_AND_RETURN("Invalid %s operation", "ATTR"); if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr); @@ -1106,11 +1106,11 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (startswith(key, "SYSCTL{")) { attr = get_key_attribute(key + STRLEN("SYSCTL")); - if (attr == NULL) - LOG_AND_RETURN("error parsing %s attribute", "ATTR"); + if (!attr) + LOG_AND_RETURN("Failed to parse %s attribute", "ATTR"); if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "ATTR"); + LOG_AND_RETURN("Invalid %s operation", "ATTR"); if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_SYSCTL, op, value, attr); @@ -1119,59 +1119,59 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (startswith(key, "SECLABEL{")) { attr = get_key_attribute(key + STRLEN("SECLABEL")); - if (attr == NULL) - LOG_AND_RETURN("error parsing %s attribute", "SECLABEL"); + if (!attr) + LOG_AND_RETURN("Failed to parse %s attribute", "SECLABEL"); if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "SECLABEL"); + LOG_AND_RETURN("Invalid %s operation", "SECLABEL"); rule_add_key(&rule_tmp, TK_A_SECLABEL, op, value, attr); } else if (streq(key, "KERNELS")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL); } else if (streq(key, "SUBSYSTEMS")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL); } else if (streq(key, "DRIVERS")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL); } else if (startswith(key, "ATTRS{")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", "ATTRS"); + LOG_AND_RETURN("Invalid %s operation", "ATTRS"); attr = get_key_attribute(key + STRLEN("ATTRS")); - if (attr == NULL) - LOG_AND_RETURN("error parsing %s attribute", "ATTRS"); + if (!attr) + LOG_AND_RETURN("Failed to parse %s attribute", "ATTRS"); if (startswith(attr, "device/")) LOG_RULE_WARNING("'device' link may not be available in future kernels; please fix"); - if (strstr(attr, "../") != NULL) - LOG_RULE_WARNING("direct reference to parent sysfs directory, may break in future kernels; please fix"); + if (strstr(attr, "../")) + LOG_RULE_WARNING("Direct reference to parent sysfs directory, may break in future kernels; please fix"); rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr); } else if (streq(key, "TAGS")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL); } else if (startswith(key, "ENV{")) { attr = get_key_attribute(key + STRLEN("ENV")); - if (attr == NULL) - LOG_AND_RETURN("error parsing %s attribute", "ENV"); + if (!attr) + LOG_AND_RETURN("Failed to parse %s attribute", "ENV"); if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "ENV"); + LOG_AND_RETURN("Invalid %s operation", "ENV"); if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr); @@ -1188,7 +1188,7 @@ static void add_rule(struct udev_rules *rules, char *line, "DEVLINKS", "DEVPATH", "TAGS")) - LOG_AND_RETURN("invalid ENV attribute, '%s' cannot be set", attr); + LOG_AND_RETURN("Invalid ENV attribute, '%s' cannot be set", attr); rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr); } @@ -1201,24 +1201,24 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (streq(key, "PROGRAM")) { if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL); } else if (streq(key, "RESULT")) { if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL); } else if (startswith(key, "IMPORT")) { attr = get_key_attribute(key + STRLEN("IMPORT")); - if (attr == NULL) { - LOG_RULE_WARNING("ignoring IMPORT{} with missing type"); + if (!attr) { + LOG_RULE_WARNING("Ignoring IMPORT{} with missing type"); continue; } if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "IMPORT"); + LOG_AND_RETURN("Invalid %s operation", "IMPORT"); if (streq(attr, "program")) { /* find known built-in command */ @@ -1248,16 +1248,16 @@ static void add_rule(struct udev_rules *rules, char *line, else if (streq(attr, "parent")) rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL); else - LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "IMPORT", attr); + LOG_RULE_ERROR("Ignoring unknown %s{} type '%s'", "IMPORT", attr); } else if (startswith(key, "TEST")) { mode_t mode = 0; if (op > OP_MATCH_MAX) - LOG_AND_RETURN("invalid %s operation", "TEST"); + LOG_AND_RETURN("Invalid %s operation", "TEST"); attr = get_key_attribute(key + STRLEN("TEST")); - if (attr != NULL) { + if (attr) { mode = strtol(attr, NULL, 8); rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode); } else @@ -1265,10 +1265,10 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (startswith(key, "RUN")) { attr = get_key_attribute(key + STRLEN("RUN")); - if (attr == NULL) + if (!attr) attr = "program"; if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", "RUN"); + LOG_AND_RETURN("Invalid %s operation", "RUN"); if (streq(attr, "builtin")) { const enum udev_builtin_cmd cmd = udev_builtin_lookup(value); @@ -1282,23 +1282,23 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); } else - LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr); + LOG_RULE_ERROR("Ignoring unknown %s{} type '%s'", "RUN", attr); } else if (streq(key, "LABEL")) { if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_tmp.rule.rule.label_off = rules_add_string(rules, value); } else if (streq(key, "GOTO")) { if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL); } else if (startswith(key, "NAME")) { if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL); @@ -1317,7 +1317,7 @@ static void add_rule(struct udev_rules *rules, char *line, } else if (streq(key, "SYMLINK")) { if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL); @@ -1330,15 +1330,15 @@ static void add_rule(struct udev_rules *rules, char *line, char *endptr; if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); uid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - else if (rules->resolve_names > 0 && strchr("$%", value[0]) == NULL) { + else if (rules->resolve_name_timing == RESOLVE_NAME_EARLY && !strchr("$%", value[0])) { uid = add_uid(rules, value); rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid); - } else if (rules->resolve_names >= 0) + } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER) rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL); rule_tmp.rule.rule.can_set_name = true; @@ -1348,15 +1348,15 @@ static void add_rule(struct udev_rules *rules, char *line, char *endptr; if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); gid = strtoul(value, &endptr, 10); if (endptr[0] == '\0') rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) { + else if ((rules->resolve_name_timing == RESOLVE_NAME_EARLY) && !strchr("$%", value[0])) { gid = add_gid(rules, value); rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid); - } else if (rules->resolve_names >= 0) + } else if (rules->resolve_name_timing != RESOLVE_NAME_NEVER) rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL); rule_tmp.rule.rule.can_set_name = true; @@ -1366,7 +1366,7 @@ static void add_rule(struct udev_rules *rules, char *line, char *endptr; if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); mode = strtol(value, &endptr, 8); if (endptr[0] == '\0') @@ -1379,17 +1379,17 @@ static void add_rule(struct udev_rules *rules, char *line, const char *pos; if (op == OP_REMOVE) - LOG_AND_RETURN("invalid %s operation", key); + LOG_AND_RETURN("Invalid %s operation", key); pos = strstr(value, "link_priority="); - if (pos != NULL) { + if (pos) { int prio = atoi(pos + STRLEN("link_priority=")); rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio); } pos = strstr(value, "string_escape="); - if (pos != NULL) { + if (pos) { pos += STRLEN("string_escape="); if (startswith(pos, "none")) rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL); @@ -1398,7 +1398,7 @@ static void add_rule(struct udev_rules *rules, char *line, } pos = strstr(value, "db_persist"); - if (pos != NULL) + if (pos) rule_add_key(&rule_tmp, TK_A_DB_PERSIST, op, NULL, NULL); pos = strstr(value, "nowatch"); @@ -1413,20 +1413,20 @@ static void add_rule(struct udev_rules *rules, char *line, } pos = strstr(value, "static_node="); - if (pos != NULL) { + if (pos) { pos += STRLEN("static_node="); rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, pos, NULL); rule_tmp.rule.rule.has_static_node = true; } } else - LOG_AND_RETURN("unknown key '%s'", key); + LOG_AND_RETURN("Unknown key '%s'", key); } /* add rule token and sort tokens */ rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur; if (add_token(rules, &rule_tmp.rule) != 0 || sort_token(rules, &rule_tmp) != 0) - LOG_RULE_ERROR("failed to add rule token"); + LOG_RULE_ERROR("Failed to add rule token"); } static int parse_file(struct udev_rules *rules, const char *filename) { @@ -1454,7 +1454,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) { first_token = rules->token_cur; filename_off = rules_add_string(rules, filename); - while (fgets(line, sizeof(line), f) != NULL) { + while (fgets(line, sizeof(line), f)) { char *key; size_t len; @@ -1474,7 +1474,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) { /* continue reading if backslash+newline is found */ while (line[len-2] == '\\') { - if (fgets(&line[len-2], (sizeof(line)-len)+2, f) == NULL) + if (!fgets(&line[len-2], (sizeof(line)-len)+2, f)) break; if (strlen(&line[len-2]) < 2) break; @@ -1483,7 +1483,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) { } if (len+1 >= sizeof(line)) { - log_error("line too long '%s':%u, ignored", filename, line_nr); + log_error("Line too long '%s':%u, ignored", filename, line_nr); continue; } add_rule(rules, key, filename, filename_off, line_nr); @@ -1512,36 +1512,38 @@ static int parse_file(struct udev_rules *rules, const char *filename) { return 0; } -struct udev_rules *udev_rules_new(int resolve_names) { +struct udev_rules *udev_rules_new(ResolveNameTiming resolve_name_timing) { struct udev_rules *rules; struct token end_token; char **files, **f; int r; + assert(resolve_name_timing >= 0 && resolve_name_timing < _RESOLVE_NAME_TIMING_MAX); + rules = new(struct udev_rules, 1); if (!rules) return NULL; *rules = (struct udev_rules) { - .resolve_names = resolve_names, + .resolve_name_timing = resolve_name_timing, }; /* init token array and string buffer */ rules->tokens = malloc_multiply(PREALLOC_TOKEN, sizeof(struct token)); - if (rules->tokens == NULL) - return udev_rules_unref(rules); + if (!rules->tokens) + return udev_rules_free(rules); rules->token_max = PREALLOC_TOKEN; rules->strbuf = strbuf_new(); if (!rules->strbuf) - return udev_rules_unref(rules); + return udev_rules_free(rules); udev_rules_check_timestamp(rules); r = conf_files_list_strv(&files, ".rules", NULL, 0, rules_dirs); if (r < 0) { - log_error_errno(r, "failed to enumerate rules files: %m"); - return udev_rules_unref(rules); + log_error_errno(r, "Failed to enumerate rules files: %m"); + return udev_rules_free(rules); } /* @@ -1559,7 +1561,7 @@ struct udev_rules *udev_rules_new(int resolve_names) { memzero(&end_token, sizeof(struct token)); end_token.type = TK_END; add_token(rules, &end_token); - log_debug("rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings", + log_debug("Rules contain %zu bytes tokens (%u * %zu bytes), %zu bytes strings", rules->token_max * sizeof(struct token), rules->token_max, sizeof(struct token), rules->strbuf->len); /* cleanup temporary strbuf data */ @@ -1580,8 +1582,8 @@ struct udev_rules *udev_rules_new(int resolve_names) { return rules; } -struct udev_rules *udev_rules_unref(struct udev_rules *rules) { - if (rules == NULL) +struct udev_rules *udev_rules_free(struct udev_rules *rules) { + if (!rules) return NULL; free(rules->tokens); strbuf_cleanup(rules->strbuf); @@ -1602,7 +1604,7 @@ static int match_key(struct udev_rules *rules, struct token *token, const char * char *pos; bool match = false; - if (val == NULL) + if (!val) val = ""; switch (token->key.glob) { @@ -1623,7 +1625,7 @@ static int match_key(struct udev_rules *rules, struct token *token, const char * const char *next; next = strchr(s, '|'); - if (next != NULL) { + if (next) { size_t matchlen = (size_t)(next - s); match = (matchlen == len && strneq(s, val, matchlen)); @@ -1643,9 +1645,9 @@ static int match_key(struct udev_rules *rules, struct token *token, const char * strscpy(value, sizeof(value), rules_str(rules, token->key.value_off)); key_value = value; - while (key_value != NULL) { + while (key_value) { pos = strchr(key_value, '|'); - if (pos != NULL) { + if (pos) { pos[0] = '\0'; pos = &pos[1]; } @@ -1686,7 +1688,7 @@ static int match_attr(struct udev_rules *rules, sd_device *dev, struct udev_even return -1; break; case SB_SUBSYS: - if (util_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), 1) != 0) + if (util_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), true) != 0) return -1; value = vbuf; break; @@ -1725,7 +1727,6 @@ int udev_rules_apply_to_event( struct udev_rules *rules, struct udev_event *event, usec_t timeout_usec, - usec_t timeout_warn_usec, Hashmap *properties_list) { sd_device *dev = event->dev; enum escape_type esc = ESCAPE_UNSET; @@ -1930,7 +1931,7 @@ int udev_rules_apply_to_event( int match; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false); - if (util_resolve_subsys_kernel(filename, filename, sizeof(filename), 0) != 0) { + if (util_resolve_subsys_kernel(filename, filename, sizeof(filename), false) != 0) { if (filename[0] != '/') { char tmp[UTIL_PATH_SIZE]; @@ -1957,12 +1958,12 @@ int udev_rules_apply_to_event( event->program_result = mfree(event->program_result); udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program), false); - log_debug("PROGRAM '%s' %s:%u", - program, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "PROGRAM '%s' %s:%u", + program, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); - if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, result, sizeof(result)) < 0) { + if (udev_event_spawn(event, timeout_usec, true, program, result, sizeof(result)) < 0) { if (cur->key.op != OP_NOMATCH) goto nomatch; } else { @@ -1972,7 +1973,7 @@ int udev_rules_apply_to_event( if (IN_SET(esc, ESCAPE_UNSET, ESCAPE_REPLACE)) { count = util_replace_chars(result, UDEV_ALLOWED_CHARS_INPUT); if (count > 0) - log_debug("%i character(s) replaced" , count); + log_device_debug(dev, "Replaced %i character(s) from result of '%s'" , count, program); } event->program_result = strdup(result); if (cur->key.op == OP_NOMATCH) @@ -1993,12 +1994,12 @@ int udev_rules_apply_to_event( char import[UTIL_PATH_SIZE]; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), import, sizeof(import), false); - log_debug("IMPORT '%s' %s:%u", - import, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "IMPORT '%s' %s:%u", + import, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); - if (import_program_into_properties(event, timeout_usec, timeout_warn_usec, import) != 0) + if (import_program_into_properties(event, timeout_usec, import) != 0) if (cur->key.op != OP_NOMATCH) goto nomatch; break; @@ -2009,10 +2010,10 @@ int udev_rules_apply_to_event( if (udev_builtin_run_once(cur->key.builtin_cmd)) { /* check if we ran already */ if (event->builtin_run & (1 << cur->key.builtin_cmd)) { - log_debug("IMPORT builtin skip '%s' %s:%u", - udev_builtin_name(cur->key.builtin_cmd), - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "IMPORT builtin skip '%s' %s:%u", + udev_builtin_name(cur->key.builtin_cmd), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); /* return the result from earlier run */ if (event->builtin_ret & (1 << cur->key.builtin_cmd)) if (cur->key.op != OP_NOMATCH) @@ -2024,16 +2025,16 @@ int udev_rules_apply_to_event( } udev_event_apply_format(event, rules_str(rules, cur->key.value_off), command, sizeof(command), false); - log_debug("IMPORT builtin '%s' %s:%u", - udev_builtin_name(cur->key.builtin_cmd), - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "IMPORT builtin '%s' %s:%u", + udev_builtin_name(cur->key.builtin_cmd), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); r = udev_builtin_run(dev, cur->key.builtin_cmd, command, false); if (r < 0) { /* remember failure */ - log_debug_errno(r, "IMPORT builtin '%s' fails: %m", - udev_builtin_name(cur->key.builtin_cmd)); + log_device_debug_errno(dev, r, "IMPORT builtin '%s' fails: %m", + udev_builtin_name(cur->key.builtin_cmd)); event->builtin_ret |= (1 << cur->key.builtin_cmd); if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -2044,7 +2045,8 @@ int udev_rules_apply_to_event( const char *key; key = rules_str(rules, cur->key.value_off); - if (sd_device_get_property_value(event->dev_db_clone, key, &val) >= 0) + if (event->dev_db_clone && + sd_device_get_property_value(event->dev_db_clone, key, &val) >= 0) device_add_property(dev, key, val); else if (cur->key.op != OP_NOMATCH) goto nomatch; @@ -2058,7 +2060,7 @@ int udev_rules_apply_to_event( key = rules_str(rules, cur->key.value_off); r = proc_cmdline_get_key(key, PROC_CMDLINE_VALUE_OPTIONAL, &value); if (r < 0) - log_debug_errno(r, "Failed to read %s from /proc/cmdline, ignoring: %m", key); + log_device_debug_errno(dev, r, "Failed to read %s from /proc/cmdline, ignoring: %m", key); else if (r > 0) { imported = true; @@ -2117,13 +2119,13 @@ int udev_rules_apply_to_event( event->owner_set = true; r = get_user_creds(&ow, &event->uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING); if (r < 0) { - log_unknown_owner(r, "user", owner); + log_unknown_owner(dev, r, "user", owner); event->uid = 0; } - log_debug("OWNER %u %s:%u", - event->uid, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "OWNER %u %s:%u", + event->uid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_GROUP: { @@ -2138,35 +2140,35 @@ int udev_rules_apply_to_event( event->group_set = true; r = get_group_creds(&gr, &event->gid, USER_CREDS_ALLOW_MISSING); if (r < 0) { - log_unknown_owner(r, "group", group); + log_unknown_owner(dev, r, "group", group); event->gid = 0; } - log_debug("GROUP %u %s:%u", - event->gid, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "GROUP %u %s:%u", + event->gid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_MODE: { - char mode_str[UTIL_NAME_SIZE], *endptr; + char mode_str[UTIL_NAME_SIZE]; mode_t mode; if (event->mode_final) break; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), mode_str, sizeof(mode_str), false); - mode = strtol(mode_str, &endptr, 8); - if (endptr[0] != '\0') { - log_error("ignoring invalid mode '%s'", mode_str); + r = parse_mode(mode_str, &mode); + if (r < 0) { + log_device_error_errno(dev, r, "Failed to parse mode '%s': %m", mode_str); break; } if (cur->key.op == OP_ASSIGN_FINAL) event->mode_final = true; event->mode_set = true; event->mode = mode; - log_debug("MODE %#o %s:%u", - event->mode, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "MODE %#o %s:%u", + event->mode, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_OWNER_ID: @@ -2176,10 +2178,10 @@ int udev_rules_apply_to_event( event->owner_final = true; event->owner_set = true; event->uid = cur->key.uid; - log_debug("OWNER %u %s:%u", - event->uid, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "OWNER %u %s:%u", + event->uid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; case TK_A_GROUP_ID: if (event->group_final) @@ -2188,10 +2190,10 @@ int udev_rules_apply_to_event( event->group_final = true; event->group_set = true; event->gid = cur->key.gid; - log_debug("GROUP %u %s:%u", - event->gid, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "GROUP %u %s:%u", + event->gid, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; case TK_A_MODE_ID: if (event->mode_final) @@ -2200,10 +2202,10 @@ int udev_rules_apply_to_event( event->mode_final = true; event->mode_set = true; event->mode = cur->key.mode; - log_debug("MODE %#o %s:%u", - event->mode, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "MODE %#o %s:%u", + event->mode, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; case TK_A_SECLABEL: { _cleanup_free_ char *name = NULL, *label = NULL; @@ -2234,10 +2236,10 @@ int udev_rules_apply_to_event( name = label = NULL; - log_debug("SECLABEL{%s}='%s' %s:%u", - name, label, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "SECLABEL{%s}='%s' %s:%u", + name, label, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_ENV: { @@ -2279,7 +2281,7 @@ int udev_rules_apply_to_event( (*p >= '0' && *p <= '9') || IN_SET(*p, '-', '_')) continue; - log_error("ignoring invalid tag name '%s'", tag); + log_device_error(dev, "Ignoring invalid tag name '%s'", tag); break; } if (cur->key.op == OP_REMOVE) @@ -2302,24 +2304,24 @@ int udev_rules_apply_to_event( if (IN_SET(esc, ESCAPE_UNSET, ESCAPE_REPLACE)) { count = util_replace_chars(name_str, "/"); if (count > 0) - log_debug("%i character(s) replaced", count); + log_device_debug(dev, "Replaced %i character(s) from result of NAME=\"%s\"", count, name); } if (sd_device_get_devnum(dev, NULL) >= 0 && (sd_device_get_devname(dev, &val) < 0 || !streq(name_str, val + STRLEN("/dev/")))) { - log_error("NAME=\"%s\" ignored, kernel device nodes cannot be renamed; please fix it in %s:%u\n", - name, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_error(dev, "Kernel device nodes cannot be renamed, ignoring NAME=\"%s\"; please fix it in %s:%u\n", + name, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } if (free_and_strdup(&event->name, name_str) < 0) return log_oom(); - log_debug("NAME '%s' %s:%u", - event->name, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "NAME '%s' %s:%u", + event->name, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_DEVLINK: { @@ -2342,15 +2344,15 @@ int udev_rules_apply_to_event( else if (esc == ESCAPE_REPLACE) count = util_replace_chars(temp, "/"); if (count > 0) - log_debug("%i character(s) replaced" , count); + log_device_debug(dev, "Replaced %i character(s) from result of LINK" , count); pos = temp; while (isspace(pos[0])) pos++; next = strchr(pos, ' '); while (next) { next[0] = '\0'; - log_debug("LINK '%s' %s:%u", pos, - rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + log_device_debug(dev, "LINK '%s' %s:%u", pos, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); device_add_devlink(dev, filename); while (isspace(next[1])) @@ -2359,8 +2361,8 @@ int udev_rules_apply_to_event( next = strchr(pos, ' '); } if (pos[0] != '\0') { - log_debug("LINK '%s' %s:%u", pos, - rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + log_device_debug(dev, "LINK '%s' %s:%u", pos, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); strscpyl(filename, sizeof(filename), "/dev/", pos, NULL); device_add_devlink(dev, filename); } @@ -2372,20 +2374,20 @@ int udev_rules_apply_to_event( const char *key_name; key_name = rules_str(rules, cur->key.attr_off); - if (util_resolve_subsys_kernel(key_name, attr, sizeof(attr), 0) != 0 && + if (util_resolve_subsys_kernel(key_name, attr, sizeof(attr), false) != 0 && sd_device_get_syspath(dev, &val) >= 0) strscpyl(attr, sizeof(attr), val, "/", key_name, NULL); attr_subst_subdir(attr, sizeof(attr)); udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); - log_debug("ATTR '%s' writing '%s' %s:%u", attr, value, - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "ATTR '%s' writing '%s' %s:%u", attr, value, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); f = fopen(attr, "we"); - if (f == NULL) - log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr); + if (!f) + log_device_error_errno(dev, errno, "Failed to open ATTR{%s} for writing: %m", attr); else if (fprintf(f, "%s", value) <= 0) - log_error_errno(errno, "error writing ATTR{%s}: %m", attr); + log_device_error_errno(dev, errno, "Failed to write ATTR{%s}: %m", attr); break; } case TK_A_SYSCTL: { @@ -2394,11 +2396,11 @@ int udev_rules_apply_to_event( udev_event_apply_format(event, rules_str(rules, cur->key.attr_off), filename, sizeof(filename), false); sysctl_normalize(filename); udev_event_apply_format(event, rules_str(rules, cur->key.value_off), value, sizeof(value), false); - log_debug("SYSCTL '%s' writing '%s' %s:%u", filename, value, - rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); + log_device_debug(dev, "SYSCTL '%s' writing '%s' %s:%u", filename, value, + rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); r = sysctl_write(filename, value); if (r < 0) - log_error_errno(r, "error writing SYSCTL{%s}='%s': %m", filename, value); + log_device_error_errno(dev, r, "Failed to write SYSCTL{%s}='%s': %m", filename, value); break; } case TK_A_RUN_BUILTIN: @@ -2426,10 +2428,10 @@ int udev_rules_apply_to_event( cmd = NULL; - log_debug("RUN '%s' %s:%u", - rules_str(rules, cur->key.value_off), - rules_str(rules, rule->rule.filename_off), - rule->rule.filename_line); + log_device_debug(dev, "RUN '%s' %s:%u", + rules_str(rules, cur->key.value_off), + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); break; } case TK_A_GOTO: @@ -2444,7 +2446,7 @@ int udev_rules_apply_to_event( case TK_M_PARENTS_MAX: case TK_M_MAX: case TK_UNSET: - log_error("wrong type %u", cur->type); + log_device_error(dev, "Wrong type %u", cur->type); goto nomatch; } @@ -2470,7 +2472,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) { _cleanup_free_ char *path = NULL; int r; - if (rules->tokens == NULL) + if (!rules->tokens) return 0; cur = &rules->tokens[0]; @@ -2513,7 +2515,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) { /* we assure, that the permissions tokens are sorted before the static token */ - if (mode == 0 && uid == 0 && gid == 0 && tags == NULL) + if (mode == 0 && uid == 0 && gid == 0 && !tags) goto next; strscpyl(device_node, sizeof(device_node), "/dev/", rules_str(rules, cur->key.value_off), NULL); @@ -2530,14 +2532,14 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) { strscpyl(tags_dir, sizeof(tags_dir), "/run/udev/static_node-tags/", *t, "/", NULL); r = mkdir_p(tags_dir, 0755); if (r < 0) - return log_error_errno(r, "failed to create %s: %m", tags_dir); + return log_error_errno(r, "Failed to create %s: %m", tags_dir); unescaped_filename = xescape(rules_str(rules, cur->key.value_off), "/."); strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL); r = symlink(device_node, tag_symlink); if (r < 0 && errno != EEXIST) - return log_error_errno(errno, "failed to create symlink %s -> %s: %m", + return log_error_errno(errno, "Failed to create symlink %s -> %s: %m", tag_symlink, device_node); } }