summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--udev.c12
-rw-r--r--udev_rules.c22
-rw-r--r--udev_rules.h6
-rw-r--r--udevd.c1
4 files changed, 31 insertions, 10 deletions
diff --git a/udev.c b/udev.c
index d44f73081d..6e0f7f1d0c 100644
--- a/udev.c
+++ b/udev.c
@@ -147,27 +147,29 @@ int main(int argc, char *argv[], char *envp[])
udev_rules_get_name(&rules, &udev, class_dev);
if (udev.ignore_device) {
info("device event will be ignored");
+ sysfs_close_class_device(class_dev);
goto cleanup;
}
if (udev.name[0] == '\0') {
info("device node creation supressed");
+ sysfs_close_class_device(class_dev);
goto cleanup;
}
-
/* create node, store in db */
retval = udev_add_device(&udev, class_dev);
} else {
dbg("no dev-file found");
- udev_rules_get_run(&rules, &udev, NULL);
+ udev_rules_get_run(&rules, &udev, class_dev, NULL);
if (udev.ignore_device) {
info("device event will be ignored");
+ sysfs_close_class_device(class_dev);
goto cleanup;
}
}
sysfs_close_class_device(class_dev);
} else if (strcmp(action, "remove") == 0) {
dbg("node remove");
- udev_rules_get_run(&rules, &udev, NULL);
+ udev_rules_get_run(&rules, &udev, NULL, NULL);
if (udev.ignore_device) {
dbg("device event will be ignored");
goto cleanup;
@@ -194,7 +196,7 @@ int main(int argc, char *argv[], char *envp[])
}
dbg("devices device opened '%s'", path);
wait_for_devices_device(devices_dev, &error);
- udev_rules_get_run(&rules, &udev, devices_dev);
+ udev_rules_get_run(&rules, &udev, NULL, devices_dev);
sysfs_close_device(devices_dev);
if (udev.ignore_device) {
info("device event will be ignored");
@@ -202,7 +204,7 @@ int main(int argc, char *argv[], char *envp[])
}
} else {
dbg("default handling");
- udev_rules_get_run(&rules, &udev, NULL);
+ udev_rules_get_run(&rules, &udev, NULL, NULL);
if (udev.ignore_device) {
info("device event will be ignored");
goto cleanup;
diff --git a/udev_rules.c b/udev_rules.c
index 939febe8f6..6cbaa781f6 100644
--- a/udev_rules.c
+++ b/udev_rules.c
@@ -1091,10 +1091,21 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s
return 0;
}
-int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device)
+int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
+ struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev)
{
struct udev_rule *rule;
+ if (class_dev && !sysfs_dev)
+ sysfs_dev = sysfs_get_classdev_device(class_dev);
+ if (sysfs_dev) {
+ dbg("found devices device: path='%s', bus_id='%s', bus='%s'",
+ sysfs_dev->path, sysfs_dev->bus_id, sysfs_dev->bus);
+ strlcpy(udev->bus_id, sysfs_dev->bus_id, sizeof(udev->bus_id));
+ }
+
+ dbg("udev->kernel_name='%s'", udev->kernel_name);
+
/* look for a matching rule to apply */
udev_rules_iter_init(rules);
while (1) {
@@ -1109,7 +1120,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy
continue;
}
- if (match_rule(udev, rule, NULL, sysfs_device) == 0) {
+ if (match_rule(udev, rule, class_dev, sysfs_dev) == 0) {
if (rule->ignore_device) {
info("rule applied, '%s' is ignored", udev->kernel_name);
udev->ignore_device = 1;
@@ -1130,7 +1141,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy
}
}
strlcpy(program, key_val(rule, &rule->run), sizeof(program));
- apply_format(udev, program, sizeof(program), NULL, sysfs_device);
+ apply_format(udev, program, sizeof(program), class_dev, sysfs_dev);
dbg("add run '%s'", program);
name_list_add(&udev->run_list, program, 0);
if (rule->run.operation == KEY_OP_ASSIGN_FINAL)
@@ -1141,6 +1152,11 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy
dbg("last rule to be applied");
break;
}
+
+ if (rule->goto_label.operation != KEY_OP_UNSET) {
+ dbg("moving forward to label '%s'", key_val(rule, &rule->goto_label));
+ udev_rules_iter_label(rules, key_val(rule, &rule->goto_label));
+ }
}
}
diff --git a/udev_rules.h b/udev_rules.h
index d22d31f7e1..bfcb3f23d5 100644
--- a/udev_rules.h
+++ b/udev_rules.h
@@ -112,7 +112,9 @@ extern void udev_rules_iter_init(struct udev_rules *rules);
extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules);
extern struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const char *label);
-extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev);
-extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device);
+extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev,
+ struct sysfs_class_device *class_dev);
+extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev,
+ struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev);
#endif
diff --git a/udevd.c b/udevd.c
index 110d8e7c4d..be401bec30 100644
--- a/udevd.c
+++ b/udevd.c
@@ -38,6 +38,7 @@
#include <sys/un.h>
#include <sys/sysinfo.h>
#include <sys/stat.h>
+#include <linux/types.h>
#include <linux/netlink.h>
#include "list.h"