![]() |
[solved] udev rule not starting gpsd during boot
I'm trying to configure gpsd 2.96 to start automatically from udev rule on a Slack 13.37 box.
1. I've compiled and installed gpsd from sources and made sure it starts manually. 2. I've copied the /lib/udev/gpsd.hotplug and /lib/udev/gpsd.hotplug.wrapper scripts in their places from the source tree and made them executable. 3. I've copied the gpsd.rules file from sources into /etc/udev/rules.d 4. I renamed it 99-persistent-gpsd.rules to run late in the bootup process. 5. I've copied the /etc/default/gpsd file from sources and made sure it has the right settings inside. Now, for the results. If I plug the gps usb dongle in while the system runs, it starts gpsd if it is not started, and it connects to it just as it should. But if I start the system with the dongle in, gpsd doesn't get started during boot. I can't find any relevant message in /var/log/syslog or /var/log/messages for boot time. There is stuff there from when I plug the dongle in while the system is running though. It's like udev ignores the rules for it at boot time. Is there something in the Slackware boot scripts that would prevent running those scripts (/lib/udev/gpsd.hotplug.wrapper which in turn runs /lib/udev/gpsd.hotplug which is a Python script)? Here is the contents of 99-persistent-gpsd.rules (ignore the comments referring to Debian, it was meant for a Debian box). My usb gps adapter is the first one - the Prolific chipset one: Code:
# udev rules for gpsdThank you |
There is a slackbuild available for gpsd on slackbuilds.org, see http://slackbuilds.org/repository/13.37/system/gpsd/
Not sure it will answer you question -- but at least it can help you keep your system clean ;) |
Thanks for the reply. I've actually used the slackBuilds script - just modified it to use version 2.96 instead of 2.95. The slackBuilds script does not install or configure any of the udev rules. I had to copy them manually from the source code. If I manage to get it going, I would like to go back to slackBuilds and suggest they modify their script to automatically configure the udev stuff.
As a follow-up to my post above - I know that the rule gets triggered during boot - because gps0 shows up in /dev - otherwise it would be just ttyUSB0. I just can't figure out why the RUN script doesn't get run. Sebastian |
I'm pretty sure the SBo gpsd won't help with the udev problem -- it doesn't even try to do anything with udev rules. So thanks to xj25vm for poking it with a stick :)
I'll do some experiments this afternoon, and if we end up with success, I'll try to include some optional support for udev in the SBo SlackBuild -- even if it's just a new paragraph in the README. (Niels Horn just approved an update for version 2.96, so apologies to Niels if we change it again in the near future!) |
It seems there is a problem with the udev setup - either in general, or the way it is configured in Slackware. I can't run anything from a udev rule. I've tried the following simple setup which is supposed to write a simple file in /var/run during boot if the gps dongle is connected:
Code:
#/etc/udev/ruled.s/99-gpsd.rulesCode:
#!/bin/bashI don't think we stand a chance of getting the gpsd started automatically by udev during boot if the RUN argument doesn't work (although, bizarrely, it works fine if the computer is booted/running and the usb gps dongle is inserted). Sebastian |
Well, I think I know what's going on here, and it isn't pretty.
gpsd insists on having a control socket at /var/run/gpsd.sock (even if you set the relevant variable in /etc/default/gpsd to a null string). Unfortunately, neither gpsd nor /lib/udev/gpsd.hotplug can create this socket when /etc/rc.d/rc.udev is doing its coldplug thing, because the root filesystem is still read-only at this point in the boot. (Digression: you can see this happening if you dial up udev's log level and ctrl-s the display at just the right point. Code:
udevd-work[1057]: '/etc/udev/gpsd-hotplug-wrapper' startedNote also, that despite the above failure, the other part of the udev rule -- creating the extra device symlink /dev/gpsN -- actually works ok. Maybe there would be a happy ending if only gpsd.hotplug and gpsd.hotplug.wrapper exited with an error code having failed to create the socket. Then, when Slackware later invokes udevadm trigger --type=failed, the scripts would run again, and would succeed. (This stuff is complicated. Am I getting it right?!) Alas, this does not happen. The reason why it doesn't or can't return an error code might be the unrelated situation that's described in the comments in gpsd.hotplug Quote:
The best fix for booting would be to edit rc.local so that it starts gpsd if /dev/gps0 exists. You can leave everything else exactly the way it is now so that hotplug will also work. |
Here's a scrippet that might help.
Code:
while true |
Hi 55020,
I think I followed pretty much all your explanation. Thank you for that - I didn't realise the first pass of udev is done while the root filesystem is in read-only mode. I am on the gpsd mailing list - and I will try to see if there is any interest in modifying the two hotplug scripts to return a non-zero value in case of failure. The problem with starting gpsd from rc.local (which I have considered) is that once the boot is out of the way, I will end up with a running gpsd, but not with a usb gps adapter connected to it - if it was plugged in before the computer is started. That is because the hotplug script sends commands to the gpsd daemon through the socket to connect to the gps device. That unless I start gpsd with the device name (/dev/ttyUSB0) on the command line. This relies on the gps dongle being assigned the same device name everytime - which might just work in my particular setup. It's just not that elegant as the hotplug. |
I'm trying to modify the gpsd.hotplug.wrapper script to return a failure message if it can't write to the filesystem - so that it get's re-run after the filesystem is mounted rw.
I'm experimenting with a very simple script like this: Code:
#!/bin/bashCode:
What does it take to register a rule as failed with udev - so that it gets re-run later on? I was thinking an exit code of 1 for a bash script should have been enough. I've read the man page for udev and udevadm - but they don't seem to say how exactly to fail a rule. Sebastian P.S. - Sorry for being a bit OT here - but I thought I better keep all the conversation belonging to the gpsd and udev problem in one place. |
Quote:
The udev rules supplied by gpsd are neither elegant nor foolproof; they assume that more or less any serial USB converter is a GPS. I use the exact same serial cable with an eTrex and at other times with various scientific data loggers, and additionally I've got a diabetes blood glucose meter with the exact same PL2303 USB id. There is no way that udev can distinguish these use cases. And that's why I don't use gpsd hotplug. It doesn't fit my lifestyle :cool: but YMMV... |
I have used gpsd with manual start for almost two years now on my own laptop - and I would have kept on using it. But I'm currently working on a vehicle onboard tracking system, using Slack and gpsd - and that's when I stumbled over this whole $£%^$ - erm, extra complication. This computer will be physically locked in its case, will start automatically when the engine starts - so it needs a reliable way of starting gpsd without any intervention. I will probably stick with doing "gpsd -n /dev/ttyUSB0" from rc.local - and this will fit my use case this time.
I would have loved it, however, if I could have come up with a more flexible script to do things properly, from udev - which would have worked well on Slackware - so that it can be added to the SBo repository. Well, I suppose you win some, you lose some :-) . In retrospect, gpsd should really include the option to scan for usb devices itself when it starts and add the right ones automatically to it's pool. This way a gpsd startup script just doing "gpsd --watch-usb" or something similar would have been enough. At worst, a udev rule including "gpsd --rescan" to tell gpsd when to have another look for new devices should cover all situations. At least I think that would have been the neatest way. |
How about leaving 99-persistent-gpsd.rules in place, and putting this in /etc/rc.local
Code:
if [ -l /dev/gps0 -a -x /lib/udev/gpsd-hotplug ]; thenMeanwhile, to answer your earlier question: "What does it take to register a rule as failed with udev - so that it gets re-run later on?" -- apparently this is the magic invocation (but I had to look it up, and haven't tried it). Code:
ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", RUN{fail_event_on_error}="/lib/udev/gpsd.test" |
Thank you for that. In that case, I wonder if we can suggest two modifications to the gpsd team:
1. Modify their existing udev rule file to add "{fail_event_on_error}" for every line of the file. 2. Modify the gpsd.hotplug.wrapper script to include a test along the lines: Code:
This way, the gpsd.hotplug.wrapper should fail on the first udev run, and should succeed on the second run. Wouldn't the two modifications above make the upstream setup fully compatible with Slackware (in theory - I haven't tried it yet)? - while keeping it compatible with the other distros as well. I really would like if that would be the case, instead of having some modifications which only apply to one distribution. It would also be easier to package. |
I've just tried the {fail_event_on_error} option and it seems to do nothing. It runs the script on the first pass of udev (and fails to write the file to /var/run), but doesn't run it on the second pass.
|
1 Attachment(s)
OK - I think I have a compromise solution to suggest for the SBo repository. I've built an rc.gpsd script to go in /etc/rc.d and be triggered from rc.local. This will:
1. Start gpsd 2. Pass ttyUSB0 (or any other device) on the command line, in case the usb dongle was already plugged in when the computer booted. 3. Also pass -F /var/run/gpsd.sock option on the command line, so that the gpsd daemon can be interracted with by gpsctl through udev, and receive any new device plugged in after the computer boots. In conjunction with using /udev/lib/gpsd.hotplug, /udev/lib/gpsd.hotplug.wrapper, gpsd.rules (maybe renamed /etc/udev/rules.d/99-persistent-gpsd.rules to fit what seems to be Slackware naming style) - this should cover most use cases, of having the device plugged in when the computer starts, and plugging it in later. I attach the rc.gpsd here (remove .txt from the end). The other files are in the gpsd sources. What do you think? |
| All times are GMT -5. The time now is 05:47 PM. |