summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-10-09 00:16:50 +0200
committerKay Sievers <kay@vrfy.org>2012-10-09 00:16:50 +0200
commit07845c142b41083bc759a18e601123aa5f6864f1 (patch)
tree190d67aa648caa60263a865d78b627bf4e6feb80
parentcc30f5f388a96ab261e73fabf968b2ec3a8fd63b (diff)
udev: support multiple entries for ENV{SYSTEMD_ALIAS} and ENV{SYSTEM_WANTS}
-rw-r--r--rules/99-systemd.rules.in20
-rw-r--r--src/core/device.c35
-rw-r--r--src/udev/udev-rules.c33
3 files changed, 60 insertions, 28 deletions
diff --git a/rules/99-systemd.rules.in b/rules/99-systemd.rules.in
index a5e43cd1ac..d17bdd9a0a 100644
--- a/rules/99-systemd.rules.in
+++ b/rules/99-systemd.rules.in
@@ -36,16 +36,16 @@ ACTION=="add", SUBSYSTEM=="block", KERNEL=="nbd*", ENV{SYSTEMD_READY}="0"
#
# http://cgit.freedesktop.org/systemd/systemd/tree/src/libudev/libudev-enumerate.c#n922
-SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/sys/subsystem/net/devices/$name"
-SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}="/sys/subsystem/bluetooth/devices/%k"
+SUBSYSTEM=="net", KERNEL!="lo", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/net/devices/$name"
+SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_ALIAS}+="/sys/subsystem/bluetooth/devices/%k"
-SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}="bluetooth.target"
-ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}="smartcard.target"
-SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}="sound.target"
+SUBSYSTEM=="bluetooth", TAG+="systemd", ENV{SYSTEMD_WANTS}+="bluetooth.target"
+ENV{ID_SMARTCARD_READER}=="*?", TAG+="systemd", ENV{SYSTEMD_WANTS}+="smartcard.target"
+SUBSYSTEM=="sound", KERNEL=="card*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sound.target"
-SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target"
-SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target"
-SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}="printer.target"
+SUBSYSTEM=="printer", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
+SUBSYSTEM=="usb", KERNEL=="lp*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
+SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:*", TAG+="systemd", ENV{SYSTEMD_WANTS}+="printer.target"
# Apply sysctl variables to network devices (and only to those) as they appear.
@@ -54,7 +54,7 @@ SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/
# Asynchronously mount file systems implemented by these modules as
# soon as they are loaded.
-SUBSYSTEM=="module", KERNEL=="fuse", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}="sys-fs-fuse-connections.mount"
-SUBSYSTEM=="module", KERNEL=="configfs", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}="sys-kernel-config.mount"
+SUBSYSTEM=="module", KERNEL=="fuse", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-fs-fuse-connections.mount"
+SUBSYSTEM=="module", KERNEL=="configfs", ACTION=="add", TAG+="systemd", ENV{SYSTEMD_WANTS}+="sys-kernel-config.mount"
LABEL="systemd_end"
diff --git a/src/core/device.c b/src/core/device.c
index 5307341d70..8121dc95d1 100644
--- a/src/core/device.c
+++ b/src/core/device.c
@@ -251,30 +251,49 @@ static int device_update_unit(Manager *m, struct udev_device *dev, const char *p
* interpret for the main object */
const char *wants, *alias;
- if ((alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS"))) {
- if (!is_path(alias))
- log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, alias);
- else {
- if ((r = device_add_escaped_name(u, alias)) < 0)
+ alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
+ if (alias) {
+ char *state, *w;
+ size_t l;
+
+ FOREACH_WORD_QUOTED(w, l, alias, state) {
+ char *e;
+
+ e = strndup(w, l);
+ if (!e) {
+ r = -ENOMEM;
goto fail;
+ }
+
+ if (!is_path(e)) {
+ log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, e);
+ free(e);
+ } else {
+
+ r = device_add_escaped_name(u, e);
+ free(e);
+ if (r < 0)
+ goto fail;
+ }
}
}
- if ((wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS"))) {
+ wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS");
+ if (wants) {
char *state, *w;
size_t l;
FOREACH_WORD_QUOTED(w, l, wants, state) {
char *e;
- if (!(e = strndup(w, l))) {
+ e = strndup(w, l);
+ if (!e) {
r = -ENOMEM;
goto fail;
}
r = unit_add_dependency_by_name(u, UNIT_WANTS, e, NULL, true);
free(e);
-
if (r < 0)
goto fail;
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index b3b42fe989..ee35f464e8 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -2471,19 +2471,32 @@ int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event
case TK_A_ENV: {
const char *name = &rules->buf[cur->key.attr_off];
char *value = &rules->buf[cur->key.value_off];
+ char value_new[UTIL_NAME_SIZE];
+ const char *value_old = NULL;
+ struct udev_list_entry *entry;
- if (value[0] != '\0') {
- char temp_value[UTIL_NAME_SIZE];
- struct udev_list_entry *entry;
-
- udev_event_apply_format(event, value, temp_value, sizeof(temp_value));
- entry = udev_device_add_property(event->dev, name, temp_value);
- /* store in db, skip private keys */
- if (name[0] != '.')
- udev_list_entry_set_num(entry, true);
- } else {
+ if (value[0] == '\0') {
+ if (cur->key.op == OP_ADD)
+ break;
udev_device_add_property(event->dev, name, NULL);
+ break;
}
+
+ if (cur->key.op == OP_ADD)
+ value_old = udev_device_get_property_value(event->dev, name);
+ if (value_old) {
+ char temp[UTIL_NAME_SIZE];
+
+ /* append value separated by space */
+ udev_event_apply_format(event, value, temp, sizeof(temp));
+ util_strscpyl(value_new, sizeof(value_new), value_old, " ", temp, NULL);
+ } else
+ udev_event_apply_format(event, value, value_new, sizeof(value_new));
+
+ entry = udev_device_add_property(event->dev, name, value_new);
+ /* store in db, skip private keys */
+ if (name[0] != '.')
+ udev_list_entry_set_num(entry, true);
break;
}
case TK_A_TAG: {