From a580407e11f89447bc40e505e305b6fcb6ab5e3f Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Mon, 1 Apr 2019 13:50:42 +0200 Subject: [PATCH] WIP: deetect net iface rename --- plugins/udevng.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/plugins/udevng.c b/plugins/udevng.c index 1a5bcb2b..5f85eb33 100644 --- a/plugins/udevng.c +++ b/plugins/udevng.c @@ -56,6 +56,7 @@ struct modem_info { }; struct ofono_modem *modem; const char *sysattr; + gboolean needs_update; }; struct device_info { @@ -1635,6 +1636,7 @@ static void add_device(const char *syspath, const char *devname, modem->devices = g_slist_insert_sorted(modem->devices, info, compare_device); + modem->needs_update = TRUE; } static struct { @@ -1827,6 +1829,8 @@ static gboolean create_modem(gpointer key, gpointer value, gpointer user_data) const char *syspath = key; unsigned int i; + modem->needs_update = FALSE; + if (modem->modem != NULL) return FALSE; @@ -1914,6 +1918,81 @@ static gboolean check_modem_list(gpointer user_data) return FALSE; } +static void drop_old_device(gpointer key, gpointer value, gpointer user_data) +{ + const char *syspath = key; + struct modem_info *modem = value; + struct udev_device *device = user_data; + const char *devpath_old; + GSList *list; + + devpath_old = udev_device_get_property_value(device, "DEVPATH_OLD"); + if (!devpath_old) + return; + + for (list = modem->devices; list; list = list->next) { + struct device_info *info = list->data; + struct udev_device *dev; + + if (g_strcmp0(info->subsystem, "net") != 0) + continue; + + if (g_strcmp0(info->devpath, devpath_old) != 0) + continue; + + /* Drop no longer existing net iface device */ + DBG("Dropping lost device %s", info->devpath); + modem->devices = g_slist_remove_link(modem->devices, list); + g_slist_free_1 (list); + device_info_free(info); + udev_device_unref(dev); + modem->needs_update = TRUE; + } +} + + +static void update_modem(gpointer key, gpointer value, gpointer user_data) +{ + const char *syspath = key; + struct modem_info *modem = value; + unsigned int i; + + if (!modem->needs_update) + return; + + DBG("Updating modem %s", syspath); + + for (i = 0; driver_list[i].name; i++) { + if (g_str_equal(driver_list[i].name, modem->driver) == FALSE) + continue; + if (driver_list[i].setup(modem) == FALSE) + continue; + } +} +static void update_device(struct udev_device *device) +{ + const char *syspath; + + syspath = udev_device_get_syspath(device); + if (syspath == NULL) + return; + + DBG("%s", syspath); + + /* We only care about net iface renames for now */ + if (g_strcmp0(udev_device_get_subsystem(device), "net") != 0) + return; + + /* Drop old device from modem */ + g_hash_table_foreach(modem_list, drop_old_device, device); + + /* Add new device to modem */ + check_device(device); + + /* Update modified modems */ + g_hash_table_foreach(modem_list, update_modem, NULL); +} + static gboolean udev_event(GIOChannel *channel, GIOCondition cond, gpointer user_data) { @@ -1941,8 +2020,11 @@ static gboolean udev_event(GIOChannel *channel, GIOCondition cond, check_device(device); udev_delay = g_timeout_add_seconds(1, check_modem_list, NULL); - } else if (g_str_equal(action, "remove") == TRUE) + } else if (g_str_equal(action, "remove") == TRUE) { remove_device(device); + } else if (g_str_equal(action, "move") == TRUE) { + update_device(device); + } udev_device_unref(device);