Merge pull request #10429 from yuwata/drop-udev-list
udev: replace udev_list by Hashmap
This commit is contained in:
commit
17fd78cb86
|
@ -44,18 +44,19 @@ struct udev_event *udev_event_new(struct udev_device *dev) {
|
|||
if (event == NULL)
|
||||
return NULL;
|
||||
event->dev = dev;
|
||||
udev_list_init(NULL, &event->run_list, false);
|
||||
udev_list_init(NULL, &event->seclabel_list, false);
|
||||
event->birth_usec = now(CLOCK_MONOTONIC);
|
||||
return event;
|
||||
}
|
||||
|
||||
void udev_event_unref(struct udev_event *event) {
|
||||
void *p;
|
||||
|
||||
if (event == NULL)
|
||||
return;
|
||||
sd_netlink_unref(event->rtnl);
|
||||
udev_list_cleanup(&event->run_list);
|
||||
udev_list_cleanup(&event->seclabel_list);
|
||||
while ((p = hashmap_steal_first_key(event->run_list)))
|
||||
free(p);
|
||||
hashmap_free_free_free(event->seclabel_list);
|
||||
free(event->program_result);
|
||||
free(event->name);
|
||||
free(event);
|
||||
|
@ -790,7 +791,7 @@ static int rename_netif(struct udev_event *event) {
|
|||
|
||||
void udev_event_execute_rules(struct udev_event *event,
|
||||
usec_t timeout_usec, usec_t timeout_warn_usec,
|
||||
struct udev_list *properties_list,
|
||||
Hashmap *properties_list,
|
||||
struct udev_rules *rules) {
|
||||
struct udev_device *dev = event->dev;
|
||||
|
||||
|
@ -873,7 +874,7 @@ void udev_event_execute_rules(struct udev_event *event,
|
|||
}
|
||||
|
||||
apply = streq(udev_device_get_action(dev), "add") || event->owner_set || event->group_set || event->mode_set;
|
||||
udev_node_add(dev->device, apply, event->mode, event->uid, event->gid, &event->seclabel_list);
|
||||
udev_node_add(dev->device, apply, event->mode, event->uid, event->gid, event->seclabel_list);
|
||||
}
|
||||
|
||||
/* preserve old, or get new initialization timestamp */
|
||||
|
@ -889,12 +890,13 @@ void udev_event_execute_rules(struct udev_event *event,
|
|||
}
|
||||
|
||||
void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec) {
|
||||
struct udev_list_entry *list_entry;
|
||||
const char *cmd;
|
||||
void *val;
|
||||
Iterator i;
|
||||
|
||||
udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) {
|
||||
HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
|
||||
enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val);
|
||||
char command[UTIL_PATH_SIZE];
|
||||
const char *cmd = udev_list_entry_get_name(list_entry);
|
||||
enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry);
|
||||
|
||||
udev_event_apply_format(event, cmd, command, sizeof(command), false);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "libudev-private.h"
|
||||
#include "path-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "smack-util.h"
|
||||
|
@ -271,9 +272,8 @@ int udev_node_update_old_links(sd_device *dev, sd_device *dev_old) {
|
|||
|
||||
static int node_permissions_apply(sd_device *dev, bool apply,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
struct udev_list *seclabel_list) {
|
||||
Hashmap *seclabel_list) {
|
||||
const char *devnode, *subsystem, *id_filename = NULL;
|
||||
struct udev_list_entry *entry;
|
||||
struct stat stats;
|
||||
dev_t devnum;
|
||||
int r = 0;
|
||||
|
@ -305,6 +305,8 @@ static int node_permissions_apply(sd_device *dev, bool apply,
|
|||
|
||||
if (apply) {
|
||||
bool selinux = false, smack = false;
|
||||
const char *name, *label;
|
||||
Iterator i;
|
||||
|
||||
if ((stats.st_mode & 0777) != (mode & 0777) || stats.st_uid != uid || stats.st_gid != gid) {
|
||||
log_debug("Setting permissions %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
|
||||
|
@ -316,13 +318,9 @@ static int node_permissions_apply(sd_device *dev, bool apply,
|
|||
log_debug("Preserve permissions of %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
|
||||
|
||||
/* apply SECLABEL{$module}=$label */
|
||||
udev_list_entry_foreach(entry, udev_list_get_entry(seclabel_list)) {
|
||||
const char *name, *label;
|
||||
HASHMAP_FOREACH_KEY(label, name, seclabel_list, i) {
|
||||
int q;
|
||||
|
||||
name = udev_list_entry_get_name(entry);
|
||||
label = udev_list_entry_get_value(entry);
|
||||
|
||||
if (streq(name, "selinux")) {
|
||||
selinux = true;
|
||||
|
||||
|
@ -388,7 +386,7 @@ static int xsprintf_dev_num_path_from_sd_device(sd_device *dev, char **ret) {
|
|||
|
||||
int udev_node_add(sd_device *dev, bool apply,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
struct udev_list *seclabel_list) {
|
||||
Hashmap *seclabel_list) {
|
||||
const char *devnode, *devlink;
|
||||
_cleanup_free_ char *filename = NULL;
|
||||
int r;
|
||||
|
|
|
@ -4,13 +4,12 @@
|
|||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "libudev.h"
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "libudev-private.h"
|
||||
#include "hashmap.h"
|
||||
|
||||
int udev_node_add(sd_device *dev, bool apply,
|
||||
mode_t mode, uid_t uid, gid_t gid,
|
||||
struct udev_list *seclabel_list);
|
||||
Hashmap *seclabel_list);
|
||||
int udev_node_remove(sd_device *dev);
|
||||
int udev_node_update_old_links(sd_device *dev, sd_device *dev_old);
|
||||
|
|
|
@ -1711,19 +1711,20 @@ enum escape_type {
|
|||
ESCAPE_REPLACE,
|
||||
};
|
||||
|
||||
void udev_rules_apply_to_event(struct udev_rules *rules,
|
||||
struct udev_event *event,
|
||||
usec_t timeout_usec,
|
||||
usec_t timeout_warn_usec,
|
||||
struct udev_list *properties_list) {
|
||||
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) {
|
||||
struct token *cur;
|
||||
struct token *rule;
|
||||
enum escape_type esc = ESCAPE_UNSET;
|
||||
bool can_set_name;
|
||||
int r;
|
||||
|
||||
if (rules->tokens == NULL)
|
||||
return;
|
||||
if (!rules->tokens)
|
||||
return 0;
|
||||
|
||||
can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
|
||||
(major(udev_device_get_devnum(event->dev)) > 0 ||
|
||||
|
@ -1783,18 +1784,10 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
value = udev_device_get_property_value(event->dev, key_name);
|
||||
|
||||
/* check global properties */
|
||||
if (!value && properties_list) {
|
||||
struct udev_list_entry *list_entry;
|
||||
if (!value && properties_list)
|
||||
value = hashmap_get(properties_list, key_name);
|
||||
|
||||
list_entry = udev_list_get_entry(properties_list);
|
||||
list_entry = udev_list_entry_get_by_name(list_entry, key_name);
|
||||
if (list_entry != NULL)
|
||||
value = udev_list_entry_get_value(list_entry);
|
||||
}
|
||||
|
||||
if (!value)
|
||||
value = "";
|
||||
if (match_key(rules, cur, value))
|
||||
if (match_key(rules, cur, strempty(value)))
|
||||
goto nomatch;
|
||||
break;
|
||||
}
|
||||
|
@ -2188,19 +2181,34 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
rule->rule.filename_line);
|
||||
break;
|
||||
case TK_A_SECLABEL: {
|
||||
_cleanup_free_ char *name = NULL, *label = NULL;
|
||||
char label_str[UTIL_LINE_SIZE] = {};
|
||||
const char *name, *label;
|
||||
|
||||
name = rules_str(rules, cur->key.attr_off);
|
||||
name = strdup(rules_str(rules, cur->key.attr_off));
|
||||
if (!name)
|
||||
return log_oom();
|
||||
|
||||
udev_event_apply_format(event, rules_str(rules, cur->key.value_off), label_str, sizeof(label_str), false);
|
||||
if (label_str[0] != '\0')
|
||||
label = label_str;
|
||||
if (!isempty(label_str))
|
||||
label = strdup(label_str);
|
||||
else
|
||||
label = rules_str(rules, cur->key.value_off);
|
||||
label = strdup(rules_str(rules, cur->key.value_off));
|
||||
if (!label)
|
||||
return log_oom();
|
||||
|
||||
if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
|
||||
udev_list_cleanup(&event->seclabel_list);
|
||||
udev_list_entry_add(&event->seclabel_list, name, label);
|
||||
hashmap_clear_free_free(event->seclabel_list);
|
||||
|
||||
r = hashmap_ensure_allocated(&event->seclabel_list, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(event->seclabel_list, name, label);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
name = label = NULL;
|
||||
|
||||
log_debug("SECLABEL{%s}='%s' %s:%u",
|
||||
name, label,
|
||||
rules_str(rules, rule->rule.filename_off),
|
||||
|
@ -2280,10 +2288,9 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
rule->rule.filename_line);
|
||||
break;
|
||||
}
|
||||
if (free_and_strdup(&event->name, name_str) < 0) {
|
||||
log_oom();
|
||||
return;
|
||||
}
|
||||
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),
|
||||
|
@ -2373,16 +2380,33 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
}
|
||||
case TK_A_RUN_BUILTIN:
|
||||
case TK_A_RUN_PROGRAM: {
|
||||
struct udev_list_entry *entry;
|
||||
_cleanup_free_ char *cmd = NULL;
|
||||
|
||||
if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL)) {
|
||||
void *p;
|
||||
|
||||
while ((p = hashmap_steal_first_key(event->run_list)))
|
||||
free(p);
|
||||
}
|
||||
|
||||
r = hashmap_ensure_allocated(&event->run_list, NULL);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
cmd = strdup(rules_str(rules, cur->key.value_off));
|
||||
if (!cmd)
|
||||
return log_oom();
|
||||
|
||||
r = hashmap_put(event->run_list, cmd, INT_TO_PTR(cur->key.builtin_cmd));
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
cmd = NULL;
|
||||
|
||||
if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
|
||||
udev_list_cleanup(&event->run_list);
|
||||
log_debug("RUN '%s' %s:%u",
|
||||
rules_str(rules, cur->key.value_off),
|
||||
rules_str(rules, rule->rule.filename_off),
|
||||
rule->rule.filename_line);
|
||||
entry = udev_list_entry_add(&event->run_list, rules_str(rules, cur->key.value_off), NULL);
|
||||
udev_list_entry_set_num(entry, cur->key.builtin_cmd);
|
||||
break;
|
||||
}
|
||||
case TK_A_GOTO:
|
||||
|
@ -2391,7 +2415,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
cur = &rules->tokens[cur->key.rule_goto];
|
||||
continue;
|
||||
case TK_END:
|
||||
return;
|
||||
return 0;
|
||||
|
||||
case TK_M_PARENTS_MIN:
|
||||
case TK_M_PARENTS_MAX:
|
||||
|
@ -2407,6 +2431,8 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
|||
/* fast-forward to next rule */
|
||||
cur = rule + rule->rule.token_count;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "sd-device.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "hashmap.h"
|
||||
#include "label.h"
|
||||
#include "libudev-private.h"
|
||||
#include "macro.h"
|
||||
|
@ -28,8 +29,8 @@ struct udev_event {
|
|||
mode_t mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
struct udev_list seclabel_list;
|
||||
struct udev_list run_list;
|
||||
Hashmap *seclabel_list;
|
||||
Hashmap *run_list;
|
||||
int exec_delay;
|
||||
usec_t birth_usec;
|
||||
sd_netlink *rtnl;
|
||||
|
@ -53,9 +54,9 @@ struct udev_rules;
|
|||
struct udev_rules *udev_rules_new(int resolve_names);
|
||||
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
|
||||
bool udev_rules_check_timestamp(struct udev_rules *rules);
|
||||
void udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
|
||||
usec_t timeout_usec, usec_t timeout_warn_usec,
|
||||
struct udev_list *properties_list);
|
||||
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);
|
||||
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
|
||||
|
||||
/* udev-event.c */
|
||||
|
@ -73,7 +74,7 @@ int udev_event_spawn(struct udev_event *event,
|
|||
const char *cmd, char *result, size_t ressize);
|
||||
void udev_event_execute_rules(struct udev_event *event,
|
||||
usec_t timeout_usec, usec_t timeout_warn_usec,
|
||||
struct udev_list *properties_list,
|
||||
Hashmap *properties_list,
|
||||
struct udev_rules *rules);
|
||||
void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec);
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ int test_main(int argc, char *argv[], void *userdata) {
|
|||
_cleanup_(udev_event_unrefp) struct udev_event *event = NULL;
|
||||
struct udev_list_entry *entry;
|
||||
sigset_t mask, sigmask_orig;
|
||||
const char *cmd;
|
||||
Iterator i;
|
||||
void *val;
|
||||
int r;
|
||||
|
||||
log_set_max_level(LOG_DEBUG);
|
||||
|
@ -138,10 +141,10 @@ int test_main(int argc, char *argv[], void *userdata) {
|
|||
udev_list_entry_foreach(entry, udev_device_get_properties_list_entry(dev))
|
||||
printf("%s=%s\n", udev_list_entry_get_name(entry), udev_list_entry_get_value(entry));
|
||||
|
||||
udev_list_entry_foreach(entry, udev_list_get_entry(&event->run_list)) {
|
||||
HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
|
||||
char program[UTIL_PATH_SIZE];
|
||||
|
||||
udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false);
|
||||
udev_event_apply_format(event, cmd, program, sizeof(program), false);
|
||||
printf("run: '%s'\n", program);
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ typedef struct Manager {
|
|||
pid_t pid; /* the process that originally allocated the manager object */
|
||||
|
||||
struct udev_rules *rules;
|
||||
struct udev_list properties;
|
||||
Hashmap *properties;
|
||||
|
||||
struct udev_monitor *monitor;
|
||||
struct udev_ctrl *ctrl;
|
||||
|
@ -293,7 +293,7 @@ static void manager_free(Manager *manager) {
|
|||
udev_ctrl_unref(manager->ctrl);
|
||||
udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
|
||||
|
||||
udev_list_cleanup(&manager->properties);
|
||||
hashmap_free_free_free(manager->properties);
|
||||
udev_rules_unref(manager->rules);
|
||||
|
||||
safe_close(manager->fd_inotify);
|
||||
|
@ -444,7 +444,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
|
|||
/* apply rules, create node, symlinks */
|
||||
udev_event_execute_rules(udev_event,
|
||||
arg_event_timeout_usec, arg_event_timeout_warn_usec,
|
||||
&manager->properties,
|
||||
manager->properties,
|
||||
manager->rules);
|
||||
|
||||
udev_event_execute_run(udev_event,
|
||||
|
@ -918,7 +918,7 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
|
|||
_cleanup_(udev_ctrl_connection_unrefp) struct udev_ctrl_connection *ctrl_conn = NULL;
|
||||
_cleanup_(udev_ctrl_msg_unrefp) struct udev_ctrl_msg *ctrl_msg = NULL;
|
||||
const char *str;
|
||||
int i;
|
||||
int i, r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
|
@ -954,27 +954,56 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
|
|||
}
|
||||
|
||||
str = udev_ctrl_get_set_env(ctrl_msg);
|
||||
if (str != NULL) {
|
||||
_cleanup_free_ char *key = NULL;
|
||||
if (str) {
|
||||
_cleanup_free_ char *key = NULL, *val = NULL, *old_key = NULL, *old_val = NULL;
|
||||
char *eq;
|
||||
|
||||
key = strdup(str);
|
||||
if (key) {
|
||||
char *val;
|
||||
|
||||
val = strchr(key, '=');
|
||||
if (val != NULL) {
|
||||
val[0] = '\0';
|
||||
val = &val[1];
|
||||
if (val[0] == '\0') {
|
||||
log_debug("udevd message (ENV) received, unset '%s'", key);
|
||||
udev_list_entry_add(&manager->properties, key, NULL);
|
||||
} else {
|
||||
log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
|
||||
udev_list_entry_add(&manager->properties, key, val);
|
||||
}
|
||||
} else
|
||||
log_error("wrong key format '%s'", key);
|
||||
eq = strchr(str, '=');
|
||||
if (!eq) {
|
||||
log_error("Invalid key format '%s'", str);
|
||||
return 1;
|
||||
}
|
||||
|
||||
key = strndup(str, eq - str);
|
||||
if (!key) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
old_val = hashmap_remove2(manager->properties, key, (void **) &old_key);
|
||||
|
||||
r = hashmap_ensure_allocated(&manager->properties, &string_hash_ops);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
eq++;
|
||||
if (!isempty(eq)) {
|
||||
log_debug("udevd message (ENV) received, unset '%s'", key);
|
||||
|
||||
r = hashmap_put(manager->properties, key, NULL);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
val = strdup(eq);
|
||||
if (!val) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_debug("udevd message (ENV) received, set '%s=%s'", key, val);
|
||||
|
||||
r = hashmap_put(manager->properties, key, val);
|
||||
if (r < 0) {
|
||||
log_oom();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
key = val = NULL;
|
||||
manager_kill_workers(manager);
|
||||
}
|
||||
|
||||
|
@ -1529,7 +1558,6 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
|
|||
return log_error_errno(ENOMEM, "error reading rules");
|
||||
|
||||
LIST_HEAD_INIT(manager->events);
|
||||
udev_list_init(NULL, &manager->properties, true);
|
||||
|
||||
manager->cgroup = cgroup;
|
||||
|
||||
|
|
Loading…
Reference in a new issue