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 */
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 */
[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",
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;
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);
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");
}
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);
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 (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)
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);