X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fudev%2Fudev-rules.c;h=a800ccdc9f3ab1527a45740a8e2380ce5de150f5;hb=33502ffe2eb7b56cdd018a4fb6830d7828519fad;hp=73e17c65c0f12b00af114eb810b6016046b545d2;hpb=83cd6b754b270091840456a2c8a66dae19f5a7dc;p=elogind.git diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 73e17c65c..a800ccdc9 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -36,6 +36,13 @@ #define PREALLOC_STRBUF 32 * 1024 #define PREALLOC_TRIE 256 +/* configuration directories with last modification timestamp */ +static const char *rules_dirs[] = { + TEST_PREFIX UDEVLIBEXECDIR "/rules.d", + TEST_PREFIX "/run/udev/rules.d", + TEST_PREFIX SYSCONFDIR "/udev/rules.d", +}; + struct uid_gid { unsigned int name_off; union { @@ -58,6 +65,7 @@ struct trie_node { struct udev_rules { struct udev *udev; + unsigned long long dirs_ts_usec[ELEMENTSOF(rules_dirs)]; int resolve_names; /* every key in the rules file becomes a token */ @@ -589,7 +597,7 @@ static uid_t add_uid(struct udev_rules *rules, const char *owner) /* lookup, if we know it already */ for (i = 0; i < rules->uids_cur; i++) { off = rules->uids[i].name_off; - if (strcmp(&rules->buf[off], owner) == 0) { + if (streq(&rules->buf[off], owner)) { uid = rules->uids[i].uid; return uid; } @@ -630,7 +638,7 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) /* lookup, if we know it already */ for (i = 0; i < rules->gids_cur; i++) { off = rules->gids[i].name_off; - if (strcmp(&rules->buf[off], group) == 0) { + if (streq(&rules->buf[off], group)) { gid = rules->gids[i].gid; return gid; } @@ -664,7 +672,6 @@ static gid_t add_gid(struct udev_rules *rules, const char *group) static int import_property_from_string(struct udev_device *dev, char *line) { - struct udev *udev = udev_device_get_udev(dev); char *key; char *val; size_t len; @@ -719,12 +726,12 @@ static int import_property_from_string(struct udev_device *dev, char *line) } /* handle device, renamed by external tool, returning new path */ - if (strcmp(key, "DEVPATH") == 0) { + if (streq(key, "DEVPATH")) { char syspath[UTIL_PATH_SIZE]; log_debug("updating devpath from '%s' to '%s'\n", udev_device_get_devpath(dev), val); - util_strscpyl(syspath, sizeof(syspath), udev_get_sys_path(udev), val, NULL); + util_strscpyl(syspath, sizeof(syspath), "/sys", val, NULL); udev_device_set_syspath(dev, syspath); } else { struct udev_list_entry *entry; @@ -781,7 +788,6 @@ static int import_program_into_properties(struct udev_event *event, const char * static int import_parent_into_properties(struct udev_device *dev, const char *filter) { - struct udev *udev = udev_device_get_udev(dev); struct udev_device *dev_parent; struct udev_list_entry *list_entry; @@ -808,7 +814,6 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi #define WAIT_LOOP_PER_SECOND 50 static int wait_for_file(struct udev_device *dev, const char *file, int timeout) { - struct udev *udev = udev_device_get_udev(dev); char filepath[UTIL_PATH_SIZE]; char devicepath[UTIL_PATH_SIZE]; struct stat stats; @@ -817,8 +822,7 @@ static int wait_for_file(struct udev_device *dev, const char *file, int timeout) /* a relative path is a device attribute */ devicepath[0] = '\0'; if (file[0] != '/') { - util_strscpyl(devicepath, sizeof(devicepath), - udev_get_sys_path(udev), udev_device_get_devpath(dev), NULL); + util_strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL); util_strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL); file = filepath; } @@ -969,7 +973,7 @@ static int get_key(struct udev *udev, char **line, char **key, enum operation_ty } /* extract possible KEY{attr} */ -static char *get_key_attribute(struct udev *udev, char *str) +static const char *get_key_attribute(struct udev *udev, char *str) { char *pos; char *attr; @@ -1053,8 +1057,8 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, case TK_A_DB_PERSIST: break; case TK_A_RUN_BUILTIN: - token->key.builtin_cmd = *(enum udev_builtin_cmd *)data; case TK_A_RUN_PROGRAM: + token->key.builtin_cmd = *(enum udev_builtin_cmd *)data; token->key.value_off = add_string(rule_tmp->rules, value); break; case TK_A_INOTIFY_WATCH: @@ -1099,7 +1103,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, } else if (has_split) { glob = GL_SPLIT; } else if (has_glob) { - if (strcmp(value, "?*") == 0) + if (streq(value, "?*")) glob = GL_SOMETHING; else glob = GL_GLOB; @@ -1132,7 +1136,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, token->key.type = type; token->key.op = op; rule_tmp->token_cur++; - if (rule_tmp->token_cur >= ARRAY_SIZE(rule_tmp->token)) { + if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) { log_error("temporary rule array too small\n"); return -1; } @@ -1178,7 +1182,7 @@ static int add_rule(struct udev_rules *rules, char *line, const char *filename, unsigned int filename_off, unsigned int lineno) { char *linepos; - char *attr; + const char *attr; struct rule_tmp rule_tmp; memset(&rule_tmp, 0x00, sizeof(struct rule_tmp)); @@ -1196,7 +1200,7 @@ static int add_rule(struct udev_rules *rules, char *line, if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) break; - if (strcmp(key, "ACTION") == 0) { + if (streq(key, "ACTION")) { if (op > OP_MATCH_MAX) { log_error("invalid ACTION operation\n"); goto invalid; @@ -1205,7 +1209,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "DEVPATH") == 0) { + if (streq(key, "DEVPATH")) { if (op > OP_MATCH_MAX) { log_error("invalid DEVPATH operation\n"); goto invalid; @@ -1214,7 +1218,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "KERNEL") == 0) { + if (streq(key, "KERNEL")) { if (op > OP_MATCH_MAX) { log_error("invalid KERNEL operation\n"); goto invalid; @@ -1223,16 +1227,16 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "SUBSYSTEM") == 0) { + if (streq(key, "SUBSYSTEM")) { if (op > OP_MATCH_MAX) { log_error("invalid SUBSYSTEM operation\n"); goto invalid; } /* bus, class, subsystem events should all be the same */ - if (strcmp(value, "subsystem") == 0 || - strcmp(value, "bus") == 0 || - strcmp(value, "class") == 0) { - if (strcmp(value, "bus") == 0 || strcmp(value, "class") == 0) + if (streq(value, "subsystem") || + streq(value, "bus") || + streq(value, "class")) { + if (streq(value, "bus") || streq(value, "class")) log_error("'%s' must be specified as 'subsystem' \n" "please fix it in %s:%u", value, filename, lineno); rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL); @@ -1241,7 +1245,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "DRIVER") == 0) { + if (streq(key, "DRIVER")) { if (op > OP_MATCH_MAX) { log_error("invalid DRIVER operation\n"); goto invalid; @@ -1250,7 +1254,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "ATTR{", sizeof("ATTR{")-1) == 0) { + if (startswith(key, "ATTR{")) { attr = get_key_attribute(rules->udev, key + sizeof("ATTR")-1); if (attr == NULL) { log_error("error parsing ATTR attribute\n"); @@ -1264,7 +1268,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "KERNELS") == 0) { + if (streq(key, "KERNELS")) { if (op > OP_MATCH_MAX) { log_error("invalid KERNELS operation\n"); goto invalid; @@ -1273,7 +1277,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "SUBSYSTEMS") == 0) { + if (streq(key, "SUBSYSTEMS")) { if (op > OP_MATCH_MAX) { log_error("invalid SUBSYSTEMS operation\n"); goto invalid; @@ -1282,7 +1286,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "DRIVERS") == 0) { + if (streq(key, "DRIVERS")) { if (op > OP_MATCH_MAX) { log_error("invalid DRIVERS operation\n"); goto invalid; @@ -1291,7 +1295,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "ATTRS{", sizeof("ATTRS{")-1) == 0) { + if (startswith(key, "ATTRS{")) { if (op > OP_MATCH_MAX) { log_error("invalid ATTRS operation\n"); goto invalid; @@ -1301,7 +1305,7 @@ static int add_rule(struct udev_rules *rules, char *line, log_error("error parsing ATTRS attribute\n"); goto invalid; } - if (strncmp(attr, "device/", 7) == 0) + if (startswith(attr, "device/")) log_error("the 'device' link may not be available in a future kernel, " "please fix it in %s:%u", filename, lineno); else if (strstr(attr, "../") != NULL) @@ -1311,7 +1315,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "TAGS") == 0) { + if (streq(key, "TAGS")) { if (op > OP_MATCH_MAX) { log_error("invalid TAGS operation\n"); goto invalid; @@ -1320,7 +1324,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "ENV{", sizeof("ENV{")-1) == 0) { + if (startswith(key, "ENV{")) { attr = get_key_attribute(rules->udev, key + sizeof("ENV")-1); if (attr == NULL) { log_error("error parsing ENV attribute\n"); @@ -1345,8 +1349,8 @@ static int add_rule(struct udev_rules *rules, char *line, }; unsigned int i; - for (i = 0; i < ARRAY_SIZE(blacklist); i++) - if (strcmp(attr, blacklist[i]) == 0) { + for (i = 0; i < ELEMENTSOF(blacklist); i++) + if (streq(attr, blacklist[i])) { log_error("invalid ENV attribute, '%s' can not be set %s:%u\n", attr, filename, lineno); continue; } @@ -1356,7 +1360,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "TAG") == 0) { + if (streq(key, "TAG")) { if (op < OP_MATCH_MAX) rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL); else @@ -1364,12 +1368,12 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "PROGRAM") == 0) { + if (streq(key, "PROGRAM")) { rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL); continue; } - if (strcmp(key, "RESULT") == 0) { + if (streq(key, "RESULT")) { if (op > OP_MATCH_MAX) { log_error("invalid RESULT operation\n"); goto invalid; @@ -1378,13 +1382,13 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) { + if (startswith(key, "IMPORT")) { attr = get_key_attribute(rules->udev, key + sizeof("IMPORT")-1); if (attr == NULL) { log_error("IMPORT{} type missing, ignoring IMPORT %s:%u\n", filename, lineno); continue; } - if (strcmp(attr, "program") == 0) { + if (streq(attr, "program")) { /* find known built-in command */ if (value[0] != '/') { enum udev_builtin_cmd cmd; @@ -1398,27 +1402,27 @@ static int add_rule(struct udev_rules *rules, char *line, } } rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL); - } else if (strcmp(attr, "builtin") == 0) { + } else if (streq(attr, "builtin")) { enum udev_builtin_cmd cmd = udev_builtin_lookup(value); if (cmd < UDEV_BUILTIN_MAX) rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd); else log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); - } else if (strcmp(attr, "file") == 0) { + } else if (streq(attr, "file")) { rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL); - } else if (strcmp(attr, "db") == 0) { + } else if (streq(attr, "db")) { rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL); - } else if (strcmp(attr, "cmdline") == 0) { + } else if (streq(attr, "cmdline")) { rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL); - } else if (strcmp(attr, "parent") == 0) { + } else if (streq(attr, "parent")) { rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL); } else log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u\n", filename, lineno); continue; } - if (strncmp(key, "TEST", sizeof("TEST")-1) == 0) { + if (startswith(key, "TEST")) { mode_t mode = 0; if (op > OP_MATCH_MAX) { @@ -1435,24 +1439,21 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "RUN", sizeof("RUN")-1) == 0) { + if (startswith(key, "RUN")) { attr = get_key_attribute(rules->udev, key + sizeof("RUN")-1); if (attr == NULL) attr = "program"; - if (strcmp(attr, "builtin") == 0) { + if (streq(attr, "builtin")) { enum udev_builtin_cmd cmd = udev_builtin_lookup(value); if (cmd < UDEV_BUILTIN_MAX) rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd); else log_error("IMPORT{builtin}: '%s' unknown %s:%u\n", value, filename, lineno); - } else if (strcmp(attr, "program") == 0) { + } else if (streq(attr, "program")) { enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX; - if (strncmp(value, "socket:", 7) == 0) - log_error("RUN+=\"socket:...\" support will be removed from a future udev release. " - "Please remove it from: %s:%u and use libudev to subscribe to events.\n", filename, lineno); rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd); } else { log_error("RUN{} unknown type, ignoring RUN %s:%u\n", filename, lineno); @@ -1461,26 +1462,26 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "WAIT_FOR") == 0 || strcmp(key, "WAIT_FOR_SYSFS") == 0) { + if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) { rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL); continue; } - if (strcmp(key, "LABEL") == 0) { + if (streq(key, "LABEL")) { rule_tmp.rule.rule.label_off = add_string(rules, value); continue; } - if (strcmp(key, "GOTO") == 0) { + if (streq(key, "GOTO")) { rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL); continue; } - if (strncmp(key, "NAME", sizeof("NAME")-1) == 0) { + if (startswith(key, "NAME")) { if (op < OP_MATCH_MAX) { rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL); } else { - if (strcmp(value, "%k") == 0) { + if (streq(value, "%k")) { log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, " "please remove it from %s:%u\n", filename, lineno); continue; @@ -1496,7 +1497,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strncmp(key, "SYMLINK", sizeof("SYMLINK")-1) == 0) { + if (startswith(key, "SYMLINK")) { if (op < OP_MATCH_MAX) { rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL); } else { @@ -1511,7 +1512,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "OWNER") == 0) { + if (streq(key, "OWNER")) { uid_t uid; char *endptr; @@ -1528,7 +1529,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "GROUP") == 0) { + if (streq(key, "GROUP")) { gid_t gid; char *endptr; @@ -1545,7 +1546,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "MODE") == 0) { + if (streq(key, "MODE")) { mode_t mode; char *endptr; @@ -1558,7 +1559,7 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (strcmp(key, "OPTIONS") == 0) { + if (streq(key, "OPTIONS")) { const char *pos; pos = strstr(value, "link_priority="); @@ -1578,9 +1579,9 @@ static int add_rule(struct udev_rules *rules, char *line, pos = strstr(value, "string_escape="); if (pos != NULL) { pos = &pos[strlen("string_escape=")]; - if (strncmp(pos, "none", strlen("none")) == 0) + if (startswith(pos, "none")) rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL); - else if (strncmp(pos, "replace", strlen("replace")) == 0) + else if (startswith(pos, "replace")) rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_REPLACE, op, NULL, NULL); } @@ -1693,7 +1694,7 @@ static int parse_file(struct udev_rules *rules, const char *filename, unsigned s continue; if (rules->tokens[j].rule.label_off == 0) continue; - if (strcmp(label, &rules->buf[rules->tokens[j].rule.label_off]) != 0) + if (!streq(label, &rules->buf[rules->tokens[j].rule.label_off])) continue; rules->tokens[i].key.rule_goto = j; break; @@ -1728,7 +1729,7 @@ static int add_matching_files(struct udev *udev, struct udev_list *file_list, co ext = strrchr(dent->d_name, '.'); if (ext == NULL) continue; - if (strcmp(ext, suffix) != 0) + if (!streq(ext, suffix)) continue; } util_strscpyl(filename, sizeof(filename), dirname, "/", dent->d_name, NULL); @@ -1750,7 +1751,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) struct udev_list file_list; struct udev_list_entry *file_loop; struct token end_token; - char **s; + unsigned int i; rules = calloc(1, sizeof(struct udev_rules)); if (rules == NULL) @@ -1790,8 +1791,8 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) memset(rules->trie_nodes, 0x00, sizeof(struct trie_node)); rules->trie_nodes_cur = 1; - for (udev_get_rules_path(udev, &s, NULL); *s != NULL; s++) - add_matching_files(udev, &file_list, *s, ".rules"); + for (i = 0; i < ELEMENTSOF(rules_dirs); i++) + add_matching_files(udev, &file_list, rules_dirs[i], ".rules"); /* add all filenames to the string buffer */ udev_list_entry_foreach(file_loop, udev_list_get_entry(&file_list)) { @@ -1888,6 +1889,33 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules) return NULL; } +bool udev_rules_check_timestamp(struct udev_rules *rules) +{ + unsigned int i; + bool changed = false; + + for (i = 0; i < ELEMENTSOF(rules_dirs); i++) { + struct stat stats; + + if (stat(rules_dirs[i], &stats) < 0) + continue; + + if (rules->dirs_ts_usec[i] == ts_usec(&stats.st_mtim)) + continue; + + /* first check */ + if (rules->dirs_ts_usec[i] != 0) { + log_debug("reload - timestamp of '%s' changed\n", rules_dirs[i]); + changed = true; + } + + /* update timestamp */ + rules->dirs_ts_usec[i] = ts_usec(&stats.st_mtim); + } + + return changed; +} + static int match_key(struct udev_rules *rules, struct token *token, const char *val) { char *key_value = &rules->buf[token->key.value_off]; @@ -1899,33 +1927,33 @@ static int match_key(struct udev_rules *rules, struct token *token, const char * switch (token->key.glob) { case GL_PLAIN: - match = (strcmp(key_value, val) == 0); + match = (streq(key_value, val)); break; case GL_GLOB: match = (fnmatch(key_value, val, 0) == 0); break; case GL_SPLIT: { - const char *split; + const char *s; size_t len; - split = &rules->buf[token->key.value_off]; + s = &rules->buf[token->key.value_off]; len = strlen(val); for (;;) { const char *next; - next = strchr(split, '|'); + next = strchr(s, '|'); if (next != NULL) { - size_t matchlen = (size_t)(next - split); + size_t matchlen = (size_t)(next - s); - match = (matchlen == len && strncmp(split, val, matchlen) == 0); + match = (matchlen == len && strncmp(s, val, matchlen) == 0); if (match) break; } else { - match = (strcmp(split, val) == 0); + match = (streq(s, val)); break; } - split = &next[1]; + s = &next[1]; } break; } @@ -2027,7 +2055,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (rules->tokens == NULL) return -1; - can_set_name = ((strcmp(udev_device_get_action(event->dev), "remove") != 0) && + can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) && (major(udev_device_get_devnum(event->dev)) > 0 || udev_device_get_ifindex(event->dev) > 0)); @@ -2058,14 +2086,13 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event goto nomatch; break; case TK_M_DEVLINK: { - size_t devlen = strlen(udev_get_dev_path(event->udev))+1; struct udev_list_entry *list_entry; bool match = false; udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(event->dev)) { const char *devlink; - devlink = &udev_list_entry_get_name(list_entry)[devlen]; + devlink = udev_list_entry_get_name(list_entry) + strlen(TEST_PREFIX "/dev/"); if (match_key(rules, cur, devlink) == 0) { match = true; break; @@ -2095,7 +2122,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event bool match = false; udev_list_entry_foreach(list_entry, udev_device_get_tags_list_entry(event->dev)) { - if (strcmp(&rules->buf[cur->key.value_off], udev_list_entry_get_name(list_entry)) == 0) { + if (streq(&rules->buf[cur->key.value_off], udev_list_entry_get_name(list_entry))) { match = true; break; } @@ -2538,15 +2565,12 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (count > 0) log_debug("%i character(s) replaced\n", count); } - if (major(udev_device_get_devnum(event->dev))) { - size_t devlen = strlen(udev_get_dev_path(event->udev))+1; - - if (strcmp(name_str, &udev_device_get_devnode(event->dev)[devlen]) != 0) { - log_error("NAME=\"%s\" ignored, kernel device nodes " - "can not be renamed; please fix it in %s:%u\n", name, - &rules->buf[rule->rule.filename_off], rule->rule.filename_line); - break; - } + if (major(udev_device_get_devnum(event->dev)) && + (!streq(name_str, udev_device_get_devnode(event->dev) + strlen(TEST_PREFIX "/dev/")))) { + log_error("NAME=\"%s\" ignored, kernel device nodes " + "can not be renamed; please fix it in %s:%u\n", name, + &rules->buf[rule->rule.filename_off], rule->rule.filename_line); + break; } free(event->name); event->name = strdup(name_str); @@ -2587,7 +2611,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event next[0] = '\0'; log_debug("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); + util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", pos, NULL); udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique); while (isspace(next[1])) next++; @@ -2597,7 +2621,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event if (pos[0] != '\0') { log_debug("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); + util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", pos, NULL); udev_device_add_devlink(event->dev, filename, cur->key.devlink_unique); } break; @@ -2707,7 +2731,7 @@ void 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) goto next; - util_strscpyl(filename, sizeof(filename), udev_get_dev_path(rules->udev), "/", + util_strscpyl(filename, sizeof(filename), TEST_PREFIX "/dev/", &rules->buf[cur->key.value_off], NULL); if (stat(filename, &stats) != 0) goto next;