gpsd-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [gpsd-users] gpsd systemd troubleshooting: Draft


From: Bernd Zeimetz
Subject: Re: [gpsd-users] gpsd systemd troubleshooting: Draft
Date: Sat, 19 Oct 2019 23:14:42 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.9.0

Hi Charles,

to be honest: I think you should study the systemd documentation a bit
more...

Just a few comments:

> +<p>This is not an introduction or guide to systemd. For that, see the 
> project's <a href="https://www.freedesktop.org/wiki/Software/systemd/"; >home 
> page</a>. This is documentation for the intersection of gpsd and systemd. It 
> is for the gpsd <a href="http://hackersdictionary.com/html/entry/hacker.html"; 
> >hacker</a> who wishes to troubleshoot a gpsd installation on a computer 
> where systemd is present. Much of this you do as root. This is written for a 
> Debian 10 (buster) system.</p>
> +
> +<p>The &quot;atomic unit&quot; of systemd is called the unit, composed of 
> one or more files.

A unit file is always one file. There might be several versions of that
file (with the one in /etc/systemd/system overriding the one in
/lib/...), and there might be .conf files in
/etc/systemd/system/servicename.service.d, which may be used to
override/add configurations.

systemctl cat servicename.service is used to show which configuration is
actually active.


> There are two units for gpsd, gpsd.socket and gpsd.service. 
> <code>gpsd.socket</code> controls the socket for gpsd, usually at port 2947. 
> <code>gpsd.service</code> controls the daemon itself.</p>

You might want to mention it will listen on localhost. If people want to
change this, they'll have to edit gpsd.socket, not the service file.

It also configures systemd to listen on /var/run/gpsd.sock for gpsdctl.


> +<p>There is a third systemd file for gpsd, <code>gpsdctl@.service</code>. 
> Among other things, that file tells systemd where to get command line options 
> for the daemon. It is set up for both Debian and Red Hat environments. In the 
> gpsd git repository, the systemd files are located in the 
> <code>systemd</code> directory.</p>

Actually gpsdctl@.service has nothing to do with command line options,
absolutely nothing. It is a template service that does nothing but
runinng gpsdctl from udev to configure gpsd via /var/run/gpsd.sock to
bind to an usb gpsd device.


> +
> +<p>Your tool for interacting with systemd is <a 
> href="https://www.freedesktop.org/software/systemd/man/systemctl.html"; 
> >systemctl</a>. The typical syntax is</p>
> +
> +<pre>systemctl [OPTIONS...] COMMAND [UNIT...]</pre>
> +
> +<p>Generally useful commands include: daemon-reload, disable, enable, 
> reload, restart, show, start, status, and stop. For the gory details, see the 
> <a href="https://www.freedesktop.org/software/systemd/man/systemctl.html"; 
> >systemctl man page</a>. daemon-reload and reload are not the same command. 
> reload tells a unit to reload its configuration file (if it can do so). 
> daemon-reload has systemd reload all unit files and its own configuration 
> file.</p>
> +
> +<p>If you want to shut gpsd down, you have to shut down both units. Shutting 
> down gpsd.service alone is not sufficient because gpsd.socket could fire it 
> up again.</p>
> +
> +<pre>systemctl stop gpsd.socket gpsd.service</pre>
> +
> +<p>Also, issuing the stop command may not actually stop the service. If 
> there is a GPS receiver plugged in, something starts gpsd up again.</p>

That won't happen if gpsd.socket is stopped. If not, plugging in a usb
device will start it again via udev/gpsdctl.


> +<p>Note that <code>systemctl disable gpsd</code> stops the gpsd.socket unit 
> from running at the next boot. It does not stop it from running at the time 
> you issue the command. For that, you should stop the service. In general stop 
> a unit before you disable it. Since gpsd has two units, you should disable 
> and enable them both.</p>
> +
> +<pre>systemctl disable gpsd.socket gpsd.service<br/>
> +&#8230;<br/>
> +systemctl enable gpsd.socket gpsd.service</pre>> +
> +<p>If you are reading this, you probably want to customize one or both 
> units. The first step is to copy the unit file of interest from 
> <code>/lib/systemd/system/</code> to <code>/etc/systemd/system/</code>. This 
> will leave the packaged files alone, so that updates don't step on your 
> changes. It also mean you can revert to the packaged files by deleting or 
> moving aside your editions. Then edit the <code>/etc</code> copy.</p>

You should not do this.
The proper way to handle such things is to use
systemctl edit gpsd.service / gpsd.socket.

systemctl edit will create an override file, where you can add/change
the options you want to edit.

So if the system-wide/packaged file is ammended, you'll still receive
these changes (unless overwritten before).


> +
> +<p>Then reload systemd:</p>

> [ ......]

> +<pre>root@orca:~# ps aux | grep -i gpsd | grep -v grep ; ls /dev/ttyA*
> +gpsd     12868  0.0  0.0  18092  3640 ?        S&lt;s  14:50   0:00 
> /usr/sbin/gpsd
> +/dev/ttyACM0
> +root@orca:~#</pre>
> +
> +<p>The next thing to do is modify /etc/default/gpsd to provide the options 
> we want. One to listen on all the interfaces (-G), and don't wait for a 
> client to connect before polling (-n). The GPSD_OPTIONS stanza now looks 
> like:</p>

No, you don't want that.
For usb receivers, create a new udev rules file in /etc/udev/rules.d,
with a content similar to the one distributed with gpsd:

ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK+="gps%n",
TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"


This will make sure gpsd is configured and de-configured for the device
when it is being plugged in. Vendorid and product can be figured out
using lsusb or in /sys/bus/...


> +
> +<pre>
> +# Other options you want to pass to gpsd
> +# GPSD_OPTIONS=""
> +GPSD_OPTIONS="-Gn"
> +</pre>
> +
> +<p>We can kill gpsd. Systemd will restart it for us, this time with the 
> options in place:</p>
> +
> +<pre>root@orca:~# kill 12868
> +root@orca:~# ps aux | grep -i gpsd | grep -v grep ; ls /dev/ttyA*
> +gpsd     14547  0.5  0.0  18092  3504 ?        S&lt;sl 15:44   0:00 
> /usr/sbin/gpsd -Gn
> +/dev/ttyACM0
> +root@orca:~#</pre>

No need for that, see above. Use udev.


> +
> +<p>But we aren't there yet. gpsd may be listening on all interfaces, but 
> systemd's hold on the socket means it can't hear anything on interfaces other 
> than the loopback. So we copy <code>gpsd.socket</code> from 
> <code>/lib/systemd/system/</code> to <code>/etc/systemd/system/</code>. Then 
> we can edit it. The [Socket] stanza now looks like so:</p>
> +
> +<pre>
> +[Socket]
> +ListenStream=/var/run/gpsd.sock
> +ListenStream=[::1]:2947
> +# ListenStream=127.0.0.1:2947
> +ListenStream=0.0.0.0:2947
> +SocketMode=0600
> +</pre>

Don't copy it.

systemctl edit gpsd.socket

Add
[Socket]
ListenStream=
ListenStream=/var/run/gpsd.sock
ListenStream=2947
BindIPv6Only=both

(untested, basically does:
- reset config
- bind to the socket
- bind to port 2947
- listen on v6 and v4
)


systemctl daemon-reload might make sense here, too.


> +
> +<p>So unplug the GPS receiver and run</p>
> +
> +<pre>systemctl stop gpsd.socket gpsd.service
> +systemctl start gpsd.socket gpsd.service</pre>
> +
> +<p>Now plug the receiver back in, and check with a local client, and a 
> client on the remote computer:</p>



As you can see, there are much better ways to handle such things than
trying to tell gpsd to talk to a gps receiver that is not actually there
yet. Using gpsdctl is the way to go.



Bernd


-- 
 Bernd Zeimetz                            Debian GNU/Linux Developer
 http://bzed.de                                http://www.debian.org
 GPG Fingerprint: ECA1 E3F2 8E11 2432 D485  DD95 EB36 171A 6FF9 435F



reply via email to

[Prev in Thread] Current Thread [Next in Thread]