diff --git a/www/troubleshooting.html b/www/troubleshooting.html index 948b0102b..8dc49bd8a 100644 --- a/www/troubleshooting.html +++ b/www/troubleshooting.html @@ -5,7 +5,7 @@ - + Troubleshooting GPSD @@ -78,6 +78,7 @@ commands and section 8 to administrative commands.

  • Start at Boot Troubleshooting
  • Telnet
  • Udev Hotplug Troubleshooting
  • +
  • Systemd Troubleshooting
  • First Try

    @@ -472,6 +473,101 @@ matching expectations about the location of the control socket.

    If you do see these device file opens and closes logged, the udev end of the configuration is working.

    +

    Systemd Troubleshooting

    + +

    Introduction

    + +

    This is not an introduction or guide to systemd. For that, see the project's home page. This is documentation for the intersection of gpsd and systemd. It is for the gpsd hacker who wishes to troubleshoot a gpsd installation on a computer where systemd is present.

    + +

    The "atomic unit" of systemd is called the unit, composed of one or more files. There are two units for gpsd, gpsd.socket and gpsd.service. gpsd.socket controls the socket for gpsd, usually at port 2947. gpsd.service controls the daemon itself.

    + +

    There is a third systemd file for gpsd, gpsdctl@.service. 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 systemd directory.

    + +

    Your tool for interacting with systemd is systemctl. The typical syntax is

    + +
    systemctl [OPTIONS...] COMMAND [UNIT...]
    + +

    Generally useful commands include: daemon-reload, disable, enable, reload, restart, show, start, status, and stop. For the gory details, see the systemctl man page. 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.

    + +

    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.

    + +
    systemctl stop gpsd.socket gpsd.service
    + +

    Also, issuing the stop command may not actually stop the service. Something (systemd?) starts gpsd up again.

    + +

    Note that systemctl disable gpsd 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.

    + +
    +systemctl stop gpsd.socket gpsd.service
    +systemctl disable gpsd.socket gpsd.service
    +…
    +systemctl enable gpsd.socket gpsd.service
    +systemctl start gpsd.socket gpsd.service
    +
    + +

    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 /lib/systemd/system/ to /etc/systemd/system/. 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 /etc copy.

    + +

    Then reload systemd and restart the service:

    + +
    +systemctl daemon-reload
    +systemctl stop gpsd.socket gpsd.service
    +systemctl start gpsd.socket gpsd.service
    +
    + +

    Real World Example

    + +

    For security, gpsd by default is set up to listen only on the loopback interface, thereby restricting its audience to clients on the same computer. We'd like to allow other computers to listen in as well. This means:

    + + + +

    The first thing, if you haven't already done so, is to install gpsd. We want gpsd itself and the gpsd clients, at least cgps and possibly xgps. We also want one or both clients on another computer.

    + +

    Then we verify that gpsd is running and reading from the GPS receiver. If gpsd isn't running, check other parts of this document, and INSTALL in the root of the git repo.

    + +

    Once we know gpsd is running, we modify /etc/default/gpsd to provide the options we want. One to listen on all the interfaces (-G), and one to tell gpsd not to wait for a client to connect before polling (-n). The GPSD_OPTIONS stanza now looks like:

    + +
    +# Other options you want to pass to gpsd
    +# GPSD_OPTIONS=""
    +GPSD_OPTIONS="-Gn"
    +
    + +

    We can kill gpsd. Systemd will restart it for us, this time with the options in place. We verify that the options are there:

    + +
    root@orca:~# kill 12868
    +root@orca:~# ps aux | grep -i gpsd | grep -v grep
    +gpsd     14547  0.5  0.0  18092  3504 ?        S<sl 15:44   0:00 /usr/sbin/gpsd -Gn
    +root@orca:~#
    + +

    But we aren't there yet. gpsd may be listening on all interfaces, but systemd's hold on the socket means gpsd can't hear anything on interfaces other than the loopback. We have to tell systemd to allow gpsd to hear other interfaces. So we copy gpsd.socket from /lib/systemd/system/ to /etc/systemd/system/. Then we can edit it. The [Socket] stanza now looks like so:

    + +
    +[Socket]
    +ListenStream=/var/run/gpsd.sock
    +ListenStream=[::1]:2947
    +# ListenStream=127.0.0.1:2947
    +ListenStream=0.0.0.0:2947
    +SocketMode=0600
    +
    + +

    So we now run

    + +
    +systemctl daemon-reload
    +systemctl stop gpsd.socket gpsd.service
    +systemctl start gpsd.socket gpsd.service
    + +

    Now check with a local client, and a client on the remote computer:

    + +
    xgps <host>
    + +

    Where <host> in our example is orca.

    +