core: work around udev parallel startup race
Ignore devices that aren't completely configured by udev yet. If ModemManager is started in parallel with udev, explicitly requesting devices may return devices for which not all udev rules have yet been applied (a bug in udev/gudev). Since we often need those rules to match the device to a specific ModemManager driver, we need to ensure that all rules have been processed before handling a device. Do this by adding an item to the environment of each device that MM might possibly be interested in, and ignoring devices that don't have that. When the device is fully processed by udev, MM will get an 'add' event and the device will have all rules applied.
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
# do not edit this file, it will be overwritten on update
|
||||
|
||||
# Tag any devices that MM might be interested in; if ModemManager is started
|
||||
# up right after udev, when MM explicitly requests devices on startup it may
|
||||
# get devices that haven't had all rules run yet. Thus, we tag devices we're
|
||||
# interested in and when handling devices during MM startup we ignore any
|
||||
# that don't have this tag. MM will still get the udev 'add' event for the
|
||||
# device a short while later and then process it as normal.
|
||||
|
||||
ACTION!="add|change", GOTO="mm_candidate_end"
|
||||
|
||||
SUBSYSTEM=="tty", ENV{ID_MM_CANDIDATE}="1"
|
||||
SUBSYSTEM=="net", ENV{ID_MM_CANDIDATE}="1"
|
||||
|
||||
LABEL="mm_candidate_end"
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@ udevrulesdir = $(UDEV_BASE_DIR)/rules.d
|
||||
udevrules_DATA = \
|
||||
77-mm-usb-device-blacklist.rules \
|
||||
77-mm-pcmcia-device-blacklist.rules \
|
||||
77-mm-platform-serial-whitelist.rules
|
||||
77-mm-platform-serial-whitelist.rules \
|
||||
80-mm-candidate.rules
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(udevrules_DATA)
|
||||
|
||||
+12
-1
@@ -733,7 +733,7 @@ device_added (MMManager *manager, GUdevDevice *device)
|
||||
const char *subsys, *name, *physdev_path, *physdev_subsys;
|
||||
SupportsInfo *info;
|
||||
char *key;
|
||||
gboolean found;
|
||||
gboolean found, is_candidate;
|
||||
GUdevDevice *physdev = NULL;
|
||||
MMPlugin *plugin;
|
||||
MMModem *existing;
|
||||
@@ -750,6 +750,17 @@ device_added (MMManager *manager, GUdevDevice *device)
|
||||
if (strncmp (name, "tty", 3) == 0 && isdigit (name[3]))
|
||||
return;
|
||||
|
||||
/* Ignore devices that aren't completely configured by udev yet. If
|
||||
* ModemManager is started in parallel with udev, explicitly requesting
|
||||
* devices may return devices for which not all udev rules have yet been
|
||||
* applied (a bug in udev/gudev). Since we often need those rules to match
|
||||
* the device to a specific ModemManager driver, we need to ensure that all
|
||||
* rules have been processed before handling a device.
|
||||
*/
|
||||
is_candidate = g_udev_device_get_property_as_boolean (device, "ID_MM_CANDIDATE");
|
||||
if (!is_candidate)
|
||||
return;
|
||||
|
||||
if (find_modem_for_port (manager, subsys, name))
|
||||
return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user