udev: run programs in the specified order

This fixes bugs introduced by 29448498c7
and d838e14515.

Previously, RUN and SECLABEL keys are stored in udev_list with its unique
flag is false. If the flag is false, then udev_list is just a linked
list and new entries are always added in the last.
So, we should use OrderedHashmap instead of Hashmap.

Fixes #11368.
This commit is contained in:
Yu Watanabe
2019-03-05 04:01:34 +09:00
committed by Lennart Poettering
parent 0dcb426328
commit 39a15c8a8d
6 changed files with 16 additions and 16 deletions

View File

@@ -71,8 +71,8 @@ UdevEvent *udev_event_free(UdevEvent *event) {
sd_device_unref(event->dev);
sd_device_unref(event->dev_db_clone);
sd_netlink_unref(event->rtnl);
hashmap_free_free_key(event->run_list);
hashmap_free_free_free(event->seclabel_list);
ordered_hashmap_free_free_key(event->run_list);
ordered_hashmap_free_free_free(event->seclabel_list);
free(event->program_result);
free(event->name);
@@ -891,7 +891,7 @@ void udev_event_execute_run(UdevEvent *event, usec_t timeout_usec) {
void *val;
Iterator i;
HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
enum udev_builtin_cmd builtin_cmd = PTR_TO_INT(val);
char command[UTIL_PATH_SIZE];

View File

@@ -272,7 +272,7 @@ 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,
Hashmap *seclabel_list) {
OrderedHashmap *seclabel_list) {
const char *devnode, *subsystem, *id_filename = NULL;
struct stat stats;
dev_t devnum;
@@ -318,7 +318,7 @@ static int node_permissions_apply(sd_device *dev, bool apply,
log_device_debug(dev, "Preserve permissions of %s, %#o, uid=%u, gid=%u", devnode, mode, uid, gid);
/* apply SECLABEL{$module}=$label */
HASHMAP_FOREACH_KEY(label, name, seclabel_list, i) {
ORDERED_HASHMAP_FOREACH_KEY(label, name, seclabel_list, i) {
int q;
if (streq(name, "selinux")) {
@@ -386,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,
Hashmap *seclabel_list) {
OrderedHashmap *seclabel_list) {
const char *devnode, *devlink;
_cleanup_free_ char *filename = NULL;
int r;

View File

@@ -10,6 +10,6 @@
int udev_node_add(sd_device *dev, bool apply,
mode_t mode, uid_t uid, gid_t gid,
Hashmap *seclabel_list);
OrderedHashmap *seclabel_list);
int udev_node_remove(sd_device *dev);
int udev_node_update_old_links(sd_device *dev, sd_device *dev_old);

View File

@@ -2260,13 +2260,13 @@ int udev_rules_apply_to_event(
return log_oom();
if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
hashmap_clear_free_free(event->seclabel_list);
ordered_hashmap_clear_free_free(event->seclabel_list);
r = hashmap_ensure_allocated(&event->seclabel_list, NULL);
r = ordered_hashmap_ensure_allocated(&event->seclabel_list, NULL);
if (r < 0)
return log_oom();
r = hashmap_put(event->seclabel_list, name, label);
r = ordered_hashmap_put(event->seclabel_list, name, label);
if (r < 0)
return log_oom();
log_device_debug(dev, "SECLABEL{%s}='%s' %s:%u",
@@ -2443,9 +2443,9 @@ int udev_rules_apply_to_event(
_cleanup_free_ char *cmd = NULL;
if (IN_SET(cur->key.op, OP_ASSIGN, OP_ASSIGN_FINAL))
hashmap_clear_free_key(event->run_list);
ordered_hashmap_clear_free_key(event->run_list);
r = hashmap_ensure_allocated(&event->run_list, NULL);
r = ordered_hashmap_ensure_allocated(&event->run_list, NULL);
if (r < 0)
return log_oom();
@@ -2453,7 +2453,7 @@ int udev_rules_apply_to_event(
if (!cmd)
return log_oom();
r = hashmap_put(event->run_list, cmd, INT_TO_PTR(cur->key.builtin_cmd));
r = ordered_hashmap_put(event->run_list, cmd, INT_TO_PTR(cur->key.builtin_cmd));
if (r < 0)
return log_oom();

View File

@@ -25,8 +25,8 @@ typedef struct UdevEvent {
mode_t mode;
uid_t uid;
gid_t gid;
Hashmap *seclabel_list;
Hashmap *run_list;
OrderedHashmap *seclabel_list;
OrderedHashmap *run_list;
usec_t exec_delay_usec;
usec_t birth_usec;
sd_netlink *rtnl;

View File

@@ -135,7 +135,7 @@ int test_main(int argc, char *argv[], void *userdata) {
FOREACH_DEVICE_PROPERTY(dev, key, value)
printf("%s=%s\n", key, value);
HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
ORDERED_HASHMAP_FOREACH_KEY(val, cmd, event->run_list, i) {
char program[UTIL_PATH_SIZE];
udev_event_apply_format(event, cmd, program, sizeof(program), false);