shill: Implement Modem1::GetLinkName()
Iterate over the links in /sys/class/net and find the one that
corresponds to the sysfs device path in our provided modem properties.
BUG=chromium-os:28498
TEST=Use a modem with an interface name other than usb0 (E362, or use
nameif to mangle usb0 into something else.
Change-Id: I16424c1d52f7fbac81c427750596e1f72be2a823
Reviewed-on: https://gerrit.chromium.org/gerrit/20102
Commit-Ready: Nathan J. Williams <njw@chromium.org>
Reviewed-by: Nathan J. Williams <njw@chromium.org>
Tested-by: Nathan J. Williams <njw@chromium.org>
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
diff --git a/modem_1.cc b/modem_1.cc
index 2d8ccd4..e8fc65f 100644
--- a/modem_1.cc
+++ b/modem_1.cc
@@ -4,6 +4,7 @@
#include "shill/modem.h"
+#include <base/file_util.h>
#include <mm/ModemManager-enums.h>
#include <mm/ModemManager-names.h>
@@ -47,12 +48,43 @@
}
}
-bool Modem1::GetLinkName(const DBusPropertiesMap & /* modem_props */,
+bool Modem1::GetLinkName(const DBusPropertiesMap &modem_props,
string *name) const {
- // TODO(rochberg): use the device path to find the link name in
- // sysfs. crosbug.com/28498
- *name = "usb0";
- return true;
+ string device_prop;
+ if (!DBusProperties::GetString(modem_props,
+ Modem::kPropertyLinkName,
+ &device_prop)) {
+ return false;
+ }
+
+ // |device_prop| will be a sysfs path such as:
+ // /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-2
+ FilePath device_path(device_prop);
+
+ // Each entry in /sys/class/net has the name of a network interface
+ // and is a symlink into the actual device structure:
+ // eth0 -> ../../devices/pci0000:00/0000:00:1c.5/0000:01:00.0/net/eth0
+ // Iterate over all of these and see if any of them point into
+ // subdirectories of the sysfs path from the Device property.
+ FilePath netfiles_path("/sys/class/net");
+
+ // FileEnumerator warns that it is a blocking interface; that
+ // shouldn't be a problem here.
+ file_util::FileEnumerator netfiles(netfiles_path,
+ false, // don't recurse
+ file_util::FileEnumerator::DIRECTORIES);
+ for (FilePath link = netfiles.Next(); !link.empty(); link = netfiles.Next()) {
+ FilePath target;
+ if (!file_util::ReadSymbolicLink(link, &target))
+ continue;
+ if (!target.IsAbsolute())
+ target = netfiles_path.Append(target);
+ if (file_util::ContainsPath(device_path, target)) {
+ *name = link.BaseName().value();
+ return true;
+ }
+ }
+ return false;
}
void Modem1::CreateDeviceMM1(const DBusInterfaceToProperties &i_to_p) {