summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2010-05-10 04:08:53 +0200
committerLennart Poettering <lennart@poettering.net>2010-05-10 04:08:53 +0200
commitafb757b1a8a416b3c692728330a266b3915eef41 (patch)
tree66c82e19ec7c8f3f92e9fe833c2a86b4efc79545
parentbab45044482dc012331c768c08d78a2d006485ad (diff)
device: allow easy identification of network interfaces without their full sysfs device path
-rw-r--r--99-systemd.rules15
-rw-r--r--device.c21
2 files changed, 33 insertions, 3 deletions
diff --git a/99-systemd.rules b/99-systemd.rules
index 9a9b27a022..c5c330f936 100644
--- a/99-systemd.rules
+++ b/99-systemd.rules
@@ -19,7 +19,20 @@ ACTION!="add|change", GOTO="systemd_end"
KERNEL=="tty[0-9]|tty1[0-2]", ENV{SYSTEMD_EXPOSE}="1"
KERNEL=="ttyS*", ENV{SYSTEMD_EXPOSE}="1"
+
SUBSYSTEM=="block", ENV{SYSTEMD_EXPOSE}="1"
-SUBSYSTEM=="net", ENV{SYSTEMD_EXPOSE}="1"
+
+# We need a hardware independant way to identify network devices. We
+# use the /sys/subsystem path for this. Current vanilla kernels don't
+# actually support that hierarchy right now, however upcoming kernels
+# will. HAL and udev internally support /sys/subsystem already, hence
+# it should be safe to use this here, too. This is mostly just an
+# identification string for systemd, so whether the path actually is
+# accessible or not does not matter as long as it is unique and in the
+# filesystem namespace.
+#
+# http://git.kernel.org/?p=linux/hotplug/udev.git;a=blob;f=libudev/libudev-enumerate.c;h=da831449dcaf5e936a14409e8e68ab12d30a98e2;hb=HEAD#l742
+
+SUBSYSTEM=="net", KERNEL!="lo", ENV{SYSTEMD_EXPOSE}="1", ENV{SYSTEMD_ALIAS}="/sys/subsystem/net/devices/%k"
LABEL="systemd_end"
diff --git a/device.c b/device.c
index 95c458f3d7..70936808be 100644
--- a/device.c
+++ b/device.c
@@ -144,7 +144,7 @@ static int device_find_escape_name(Manager *m, const char *dn, Unit **_u) {
}
static int device_process_new_device(Manager *m, struct udev_device *dev, bool update_state) {
- const char *dn, *wants, *sysfs, *expose, *model;
+ const char *dn, *wants, *sysfs, *expose, *model, *alias;
Unit *u = NULL;
int r;
char *w, *state;
@@ -172,6 +172,15 @@ static int device_process_new_device(Manager *m, struct udev_device *dev, bool u
/* Check whether this entry is even relevant for us. */
dn = udev_device_get_devnode(dev);
wants = udev_device_get_property_value(dev, "SYSTEMD_WANTS");
+ alias = udev_device_get_property_value(dev, "SYSTEMD_ALIAS");
+
+ /* We allow exactly one alias to be configured a this time and
+ * it must be a path */
+
+ if (alias && !is_path(alias)) {
+ log_warning("SYSTEMD_ALIAS for %s is not a path, ignoring: %s", sysfs, alias);
+ alias = NULL;
+ }
if ((r = device_find_escape_name(m, sysfs, &u)) < 0)
return r;
@@ -191,12 +200,16 @@ static int device_process_new_device(Manager *m, struct udev_device *dev, bool u
}
}
+ if (r == 0 && alias)
+ if ((r = device_find_escape_name(m, alias, &u)) < 0)
+ return r;
+
/* FIXME: this needs proper merging */
assert((r > 0) == !!u);
/* If this is a different unit, then let's not merge things */
- if (u && DEVICE(u)->sysfs && !streq(DEVICE(u)->sysfs, sysfs))
+ if (u && DEVICE(u)->sysfs && !path_equal(DEVICE(u)->sysfs, sysfs))
u = NULL;
if (!u) {
@@ -218,6 +231,10 @@ static int device_process_new_device(Manager *m, struct udev_device *dev, bool u
goto fail;
}
+ if (alias)
+ if ((r = device_add_escaped_name(u, alias, true)) < 0)
+ goto fail;
+
if (dn)
if ((r = device_add_escaped_name(u, dn, true)) < 0)
goto fail;