mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
add WAIT_FOR_SYSFS key to loop until a file in sysfs arrives
Signed-off-by: Kay Sievers <kay.sievers@suse.de>
This commit is contained in:
parent
5f79d72c43
commit
b2fe4b9ac9
44
udev_rules.c
44
udev_rules.c
@ -335,6 +335,28 @@ attr_found:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define WAIT_LOOP_PER_SECOND 20
|
||||
static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
|
||||
{
|
||||
char filename[PATH_SIZE];
|
||||
struct stat stats;
|
||||
int loop = timeout * WAIT_LOOP_PER_SECOND;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->devpath, file);
|
||||
filename[sizeof(filename)-1] = '\0';
|
||||
dbg("wait %i sec for '%s'", timeout, filename);
|
||||
|
||||
while (--loop) {
|
||||
if (stat(filename, &stats) == 0) {
|
||||
dbg("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1);
|
||||
return 0;
|
||||
}
|
||||
usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
|
||||
}
|
||||
dbg("waiting for '%s' failed", filename);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void apply_format(struct udevice *udev, char *string, size_t maxsize,
|
||||
struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device)
|
||||
{
|
||||
@ -622,15 +644,15 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k
|
||||
dbg("check for %s '%s' <-> '%s'", key_name, key_value, val);
|
||||
match = (strcmp_pattern(key_value, val) == 0);
|
||||
if (match && (key->operation != KEY_OP_NOMATCH)) {
|
||||
dbg("%s key is matching (matching value)", key_name);
|
||||
dbg("%s is matching (matching value)", key_name);
|
||||
return 0;
|
||||
}
|
||||
if (!match && (key->operation == KEY_OP_NOMATCH)) {
|
||||
dbg("%s key is matching, (non matching value)", key_name);
|
||||
dbg("%s is matching, (non matching value)", key_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dbg("%s key is not matching", key_name);
|
||||
dbg("%s is not matching", key_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -681,6 +703,22 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule,
|
||||
dbg("all %i ENV keys matched", rule->env.count);
|
||||
}
|
||||
|
||||
if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) {
|
||||
int match;
|
||||
|
||||
match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0);
|
||||
if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) {
|
||||
dbg("WAIT_FOR_SYSFS is matching (matching value)");
|
||||
return 0;
|
||||
}
|
||||
if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) {
|
||||
dbg("WAIT_FOR_SYSFS is matching, (non matching value)");
|
||||
return 0;
|
||||
}
|
||||
dbg("WAIT_FOR_SYSFS is not matching");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* walk up the chain of physical devices and find a match */
|
||||
while (1) {
|
||||
/* check for matching driver */
|
||||
|
@ -66,6 +66,7 @@ struct udev_rule {
|
||||
struct key result;
|
||||
struct key modalias;
|
||||
struct key import;
|
||||
struct key wait_for_sysfs;
|
||||
struct key_pairs sysfs;
|
||||
struct key_pairs env;
|
||||
|
||||
|
@ -284,6 +284,12 @@ static int add_to_rules(struct udev_rules *rules, char *line)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) {
|
||||
add_rule_key(rule, &rule->wait_for_sysfs, operation, value);
|
||||
valid = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) {
|
||||
attr = get_key_attribute(key + sizeof("ENV")-1);
|
||||
if (attr == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user