X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fudev%2Fudev-rules.c;h=f793e57712266429f3c1e7903c11d964daca34f0;hp=6f8b1278723afd30335ad6422a9aa65a357a9e32;hb=53461b74df0576ec091275d1a5dbee00611df1ee;hpb=3cf0f8f7e0b950b5f6d678f3e8b7f0fc0f52d4bf diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 6f8b12787..f793e5771 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -49,7 +49,7 @@ struct uid_gid { struct udev_rules { struct udev *udev; char **dirs; - usec_t *dirs_ts_usec; + usec_t dirs_ts_usec; int resolve_names; /* every key in the rules file becomes a token */ @@ -156,6 +156,7 @@ enum token_type { TK_A_MODE_ID, /* mode_t */ TK_A_TAG, /* val */ TK_A_STATIC_NODE, /* val */ + TK_A_SECLABEL, /* val, attr */ TK_A_ENV, /* val, attr */ TK_A_NAME, /* val */ TK_A_DEVLINK, /* val */ @@ -291,6 +292,7 @@ static const char *token_str(enum token_type type) [TK_A_OWNER_ID] = "A OWNER_ID", [TK_A_GROUP_ID] = "A GROUP_ID", [TK_A_STATIC_NODE] = "A STATIC_NODE", + [TK_A_SECLABEL] = "A SECLABEL", [TK_A_MODE_ID] = "A MODE_ID", [TK_A_ENV] = "A ENV", [TK_A_TAG] = "A ENV", @@ -399,6 +401,9 @@ static void dump_token(struct udev_rules *rules, struct token *token) case TK_A_STATIC_NODE: log_debug("%s '%s'\n", token_str(type), value); break; + case TK_A_SECLABEL: + log_debug("%s %s '%s' '%s'\n", token_str(type), operation_str(op), attr, value); + break; case TK_M_EVENT_TIMEOUT: log_debug("%s %u\n", token_str(type), token->key.event_timeout); break; @@ -426,7 +431,7 @@ static void dump_rules(struct udev_rules *rules) rules->token_cur * sizeof(struct token), rules->buf_count, rules->buf_cur); - for(i = 0; i < rules->token_cur; i++) + for (i = 0; i < rules->token_cur; i++) dump_token(rules, &rules->tokens[i]); } #else @@ -546,6 +551,7 @@ static int import_property_from_string(struct udev_device *dev, char *line) char *key; char *val; size_t len; + struct udev_list_entry *entry; /* find key */ key = line; @@ -596,22 +602,11 @@ static int import_property_from_string(struct udev_device *dev, char *line) val++; } - /* handle device, renamed by external tool, returning new path */ - if (streq(key, "DEVPATH")) { - char syspath[UTIL_PATH_SIZE]; - - log_debug("updating devpath from '%s' to '%s'\n", - udev_device_get_devpath(dev), val); - strscpyl(syspath, sizeof(syspath), "/sys", val, NULL); - udev_device_set_syspath(dev, syspath); - } else { - struct udev_list_entry *entry; - - entry = udev_device_add_property(dev, key, val); - /* store in db, skip private keys */ - if (key[0] != '.') - udev_list_entry_set_num(entry, true); - } + entry = udev_device_add_property(dev, key, val); + /* store in db, skip private keys */ + if (key[0] != '.') + udev_list_entry_set_num(entry, true); + return 0; } @@ -911,6 +906,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type, case TK_M_ATTRS: case TK_A_ATTR: case TK_A_ENV: + case TK_A_SECLABEL: attr = data; token->key.value_off = rules_add_string(rule_tmp->rules, value); token->key.attr_off = rules_add_string(rule_tmp->rules, attr); @@ -1085,7 +1081,7 @@ static int add_rule(struct udev_rules *rules, char *line, "starting at character %tu ('%s')\n", filename, lineno, linepos - line + 1, tmp); if (linepos[1] == '#') - log_info("hint: comments can only start at beginning of line"); + log_error("hint: comments can only start at beginning of line"); } break; } @@ -1158,6 +1154,17 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } + if (startswith(key, "SECLABEL{")) { + attr = get_key_attribute(rules->udev, key + sizeof("SECLABEL")-1); + if (!attr) { + log_error("error parsing SECLABEL attribute\n"); + goto invalid; + } + + rule_add_key(&rule_tmp, TK_A_SECLABEL, op, value, attr); + continue; + } + if (streq(key, "KERNELS")) { if (op > OP_MATCH_MAX) { log_error("invalid KERNELS operation\n"); @@ -1636,9 +1643,6 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) } strv_uniq(rules->dirs); - rules->dirs_ts_usec = calloc(strv_length(rules->dirs), sizeof(usec_t)); - if(!rules->dirs_ts_usec) - return udev_rules_unref(rules); udev_rules_check_timestamp(rules); r = conf_files_list_strv(&files, ".rules", NULL, (const char **)rules->dirs); @@ -1694,39 +1698,16 @@ struct udev_rules *udev_rules_unref(struct udev_rules *rules) free(rules->uids); free(rules->gids); strv_free(rules->dirs); - free(rules->dirs_ts_usec); free(rules); return NULL; } bool udev_rules_check_timestamp(struct udev_rules *rules) { - unsigned int i; - bool changed = false; - - if (rules == NULL) - goto out; - - for (i = 0; rules->dirs[i]; i++) { - struct stat stats; + if (!rules) + return false; - if (stat(rules->dirs[i], &stats) < 0) - continue; - - if (rules->dirs_ts_usec[i] == timespec_load(&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] = timespec_load(&stats.st_mtim); - } -out: - return changed; + return paths_check_timestamp(rules->dirs, &rules->dirs_ts_usec, true); } static int match_key(struct udev_rules *rules, struct token *token, const char *val) @@ -2329,6 +2310,20 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); break; + case TK_A_SECLABEL: { + const char *name, *label; + + name = rules_str(rules, cur->key.attr_off); + label = rules_str(rules, cur->key.value_off); + if (cur->key.op == OP_ASSIGN || cur->key.op == OP_ASSIGN_FINAL) + udev_list_cleanup(&event->seclabel_list); + udev_list_entry_add(&event->seclabel_list, name, label); + log_debug("SECLABEL{%s}='%s' %s:%u\n", + name, label, + rules_str(rules, rule->rule.filename_off), + rule->rule.filename_line); + break; + } case TK_A_ENV: { const char *name = rules_str(rules, cur->key.attr_off); char *value = rules_str(rules, cur->key.value_off); @@ -2600,7 +2595,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) strscpyl(tag_symlink, sizeof(tag_symlink), tags_dir, unescaped_filename, NULL); r = symlink(device_node, tag_symlink); if (r < 0 && errno != EEXIST) { - log_error("failed to create symlink %s -> %s: %s\n", tag_symlink, device_node, strerror(errno)); + log_error("failed to create symlink %s -> %s: %m\n", tag_symlink, device_node); return -errno; } else r = 0;