[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gpsd-users
Subject:    Re: [gpsd-users] gpsd systemd troubleshooting: Draft
From:       Bernd Zeimetz <bernd () bzed ! de>
Date:       2019-10-19 21:14:42
Message-ID: 0f05e437-ca55-1429-2c81-5bcff0eba565 () bzed ! de
[Download RAW message or body]

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic