diff options
author | Dan Williams <dcbw@redhat.com> | 2010-12-08 17:04:59 -0600 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-12-08 17:04:59 -0600 |
commit | 592d71ff76318b6389f6866d5394a844c7e35513 (patch) | |
tree | b9aae94f790482b74736ddb580205e8cadf075ad | |
parent | 067490960a65781029e5c931a28d1f7497cc9b1e (diff) |
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.
-rw-r--r-- | src/80-mm-candidate.rules | 16 | ||||
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/mm-manager.c | 13 |
3 files changed, 30 insertions, 2 deletions
diff --git a/src/80-mm-candidate.rules b/src/80-mm-candidate.rules new file mode 100644 index 00000000..f396cfcf --- /dev/null +++ b/src/80-mm-candidate.rules @@ -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" + diff --git a/src/Makefile.am b/src/Makefile.am index cadc98ac..de15beea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) diff --git a/src/mm-manager.c b/src/mm-manager.c index 0aaac9cf..605ec5a1 100644 --- a/src/mm-manager.c +++ b/src/mm-manager.c @@ -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; |