1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-23 17:34:00 +03:00

add "[$SUBSYSTEM/$KERNEL]<attribute>" lookup

This commit is contained in:
Kay Sievers 2007-06-03 12:29:46 +02:00
parent 953249a3a0
commit 4ad47b2de6
2 changed files with 81 additions and 5 deletions

View File

@ -1559,6 +1559,15 @@ EOF
# 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
KERNEL="sda1", NAME=="no"
KERNEL=="sda1", NAME="yes"
EOF
},
{
desc => "magic subsys/kernel lookup",
subsys => "block",
devpath => "/block/sda",
exp_name => "00:e0:00:fb:04:e1",
rules => <<EOF
KERNEL=="sda", NAME="\$attr{[net/eth0]address}"
EOF
},
);

View File

@ -267,10 +267,48 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout)
info("wait for '%s' for %i mseconds", filepath, 1000 / WAIT_LOOP_PER_SECOND);
usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND);
}
err("waiting for '%s' failed", filepath);
info("waiting for '%s' failed", filepath);
return -1;
}
/* handle "[$SUBSYSTEM/$KERNEL]<attribute>" lookup */
static int attr_get_by_subsys_id(const char *attrstr, char *devpath, size_t len, char **attr)
{
char subsys[NAME_SIZE];
char *attrib;
char *id;
int found = 0;
if (attrstr[0] != '[')
goto out;
strlcpy(subsys, &attrstr[1], sizeof(subsys));
attrib = strchr(subsys, ']');
if (attrib == NULL)
goto out;
attrib[0] = '\0';
attrib = &attrib[1];
id = strchr(subsys, '/');
if (id == NULL)
goto out;
id[0] = '\0';
id = &id[1];
if (sysfs_lookup_devpath_by_subsys_id(devpath, len, subsys, id)) {
if (attr != NULL) {
if (attrib[0] != '\0')
*attr = attrib;
else
*attr = NULL;
}
found = 1;
}
out:
return found;
}
void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize)
{
char temp[PATH_SIZE];
@ -443,11 +481,20 @@ found:
if (attr == NULL)
err("missing file parameter for attr");
else {
char devpath[PATH_SIZE];
char *attrib;
const char *value = NULL;
size_t size;
/* first try the current device, other matches may have selected */
if (udev->dev_parent != NULL && udev->dev_parent != udev->dev)
if (attr_get_by_subsys_id(attr, devpath, sizeof(devpath), &attrib)) {
if (attrib != NULL)
value = sysfs_attr_get_value(devpath, attrib);
else
break;
}
/* try the current device, other matches may have selected */
if (value == NULL && udev->dev_parent != NULL && udev->dev_parent != udev->dev)
value = sysfs_attr_get_value(udev->dev_parent->devpath, attr);
/* look at all devices along the chain of parents */
@ -643,12 +690,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
if (rule->test.operation != KEY_OP_UNSET) {
char filename[PATH_SIZE];
char devpath[PATH_SIZE];
char *attr;
struct stat statbuf;
int match;
strlcpy(filename, key_val(rule, &rule->test), sizeof(filename));
udev_rules_apply_format(udev, filename, sizeof(filename));
if (attr_get_by_subsys_id(filename, devpath, sizeof(devpath), &attr)) {
strlcpy(filename, sysfs_path, sizeof(filename));
strlcat(filename, devpath, sizeof(filename));
if (attr != NULL) {
strlcat(filename, "/", sizeof(filename));
strlcat(filename, attr, sizeof(filename));
}
}
match = (stat(filename, &statbuf) == 0);
info("'%s' %s", filename, match ? "exists" : "does not exist");
if (match && rule->test_mode_mask > 0) {
@ -680,11 +738,20 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule)
pair->key.operation == KEY_OP_NOMATCH) {
const char *key_name = key_pair_name(rule, pair);
const char *key_value = key_val(rule, &pair->key);
const char *value;
char devpath[PATH_SIZE];
char *attrib;
const char *value = NULL;
char val[VALUE_SIZE];
size_t len;
value = sysfs_attr_get_value(udev->dev->devpath, key_name);
if (attr_get_by_subsys_id(key_name, devpath, sizeof(devpath), &attrib)) {
if (attrib != NULL)
value = sysfs_attr_get_value(devpath, attrib);
else
goto nomatch;
}
if (value == NULL)
value = sysfs_attr_get_value(udev->dev->devpath, key_name);
if (value == NULL)
goto nomatch;
strlcpy(val, value, sizeof(val));