summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Zeimetz <bernd@bzed.de>2014-08-17 12:21:14 +0200
committerBernd Zeimetz <bernd@bzed.de>2014-08-17 12:21:14 +0200
commit5c7a4fe2eb6d6ce071d3c50aba76f9a9b4753931 (patch)
tree4fe620727ad494624e198cc16134a69826571a96
parentbdafaf38d1eb4cd35e1d1daf5bad842962b1aa18 (diff)
downloadgpsd-5c7a4fe2eb6d6ce071d3c50aba76f9a9b4753931.tar.gz
Bring systemd handing into a useful shape.
I'm merging the changes that were done in the gpsd packaging in Fedora and Debian. With systemd being enabled, the hotplug script is not being used anymore, instead run the gpsdctl@.service unit. /etc/default/gpsd and /etc/sysconfig/gpsd are read as EnvironmentFile to keep the shipped config useable on RedHat/Debian-like systems at least. The udev-install rule now also depends on systemd_install and systemctl_daemon_reload. With these changes, hotplugging on systemd enabled systems seems to work well on Debian and Fedora.
-rw-r--r--SConstruct49
-rw-r--r--gpsd.rules.in28
-rw-r--r--systemd/gpsd.service4
-rw-r--r--systemd/gpsd.socket1
-rw-r--r--systemd/gpsdctl@.service13
5 files changed, 74 insertions, 21 deletions
diff --git a/SConstruct b/SConstruct
index c88a39e1..0f39f5ce 100644
--- a/SConstruct
+++ b/SConstruct
@@ -90,7 +90,8 @@ def _getoutput(cmd, input=None, cwd=None, env=None):
# Start by reading configuration variables from the cache
opts = Variables('.scons-option-cache')
-systemd = os.path.exists("/usr/share/systemd/system")
+systemd_dir = '/lib/systemd/system'
+systemd = os.path.exists(systemd_dir)
# Set distribution-specific defaults here
imloads = True
@@ -289,6 +290,7 @@ def installdir(dir, add_destdir=True):
if add_destdir:
wrapped = os.path.normpath(DESTDIR + os.path.sep + wrapped)
wrapped.replace("/usr/etc", "/etc")
+ wrapped.replace("/usr/lib/systemd", "/lib/systemd")
return wrapped
# Honor the specified installation prefix in link paths.
@@ -1183,6 +1185,12 @@ if 'dev' in gpsd_version or not os.path.exists('leapseconds.cache'):
env.Precious(leapseconds_cache)
env.AlwaysBuild(leapseconds_cache)
+if env['systemd']:
+ udevcommand = 'TAG+="systemd", ENV{SYSTEMD_WANTS}="gpsdctl@%k.service"'
+else:
+ udevcommand = 'RUN+="%s/gpsd.hotplug"' %(env['udevdir'], )
+
+
# Instantiate some file templates. We'd like to use the Substfile builtin
# but it doesn't seem to work in scons 1.20
def substituter(target, source, env):
@@ -1190,7 +1198,7 @@ def substituter(target, source, env):
('@VERSION@', gpsd_version),
('@prefix@', env['prefix']),
('@libdir@', env['libdir']),
- ('@udevdir@', env['udevdir']),
+ ('@udevcommand@', udevcommand),
('@PYTHON@', sys.executable),
('@DATE@', time.asctime()),
('@MASTER@', 'DO NOT HAND_HACK! THIS FILE IS GENERATED'),
@@ -1347,6 +1355,7 @@ if qt_env:
pc_install.append(qt_env.Install(installdir('libdir'), 'libQgpsmm.prl'))
+
maninstall = []
for manpage in base_manpages.keys() + python_manpages.keys():
if not manbuilder and not os.path.exists(manpage):
@@ -1762,15 +1771,43 @@ if env['python']:
# GPS ad libitum. All is well when you get fix reports each time a GPS
# is plugged in.
#
+# In case you are a systemd user you might also need to watch the
+# journalctl output. Instead of the hotplug script the gpsdctl@.service
+# unit will handle hotplugging together with the udev rules.
+#
# Note that a udev event can be triggered with an invocation like:
# udevadm trigger --sysname-match=ttyUSB0 --action add
-Utility('udev-install', 'install', [
+if env['systemd']:
+ systemdinstall_target = [ env.Install(DESTDIR + systemd_dir, "systemd/%s" %(x,)) for x in ("gpsdctl@.service", "gpsd.service", "gpsd.socket") ]
+ systemd_install = env.Alias('systemd_install', systemdinstall_target)
+ systemd_uninstall = env.Command('systemd_uninstall', '', Flatten(Uninstall(Alias("systemd_install"))) or "")
+
+ env.AlwaysBuild(systemd_uninstall)
+ env.Precious(systemd_uninstall)
+
+
+if env['systemd']:
+ hotplug_wrapper_install = []
+else:
+ hotplug_wrapper_install = [
+ 'cp $SRCDIR/gpsd.hotplug ' + DESTDIR + env['udevdir'],
+ 'chmod a+x ' + DESTDIR + env['udevdir'] + '/gpsd.hotplug'
+ ]
+
+udev_install = Utility('udev-install', 'install', [
'mkdir -p ' + DESTDIR + env['udevdir'] + '/rules.d',
'cp $SRCDIR/gpsd.rules ' + DESTDIR + env['udevdir'] + '/rules.d/25-gpsd.rules',
- 'cp $SRCDIR/gpsd.hotplug ' + DESTDIR + env['udevdir'],
- 'chmod a+x ' + DESTDIR + env['udevdir'] + '/gpsd.hotplug',
- ])
+ ] + hotplug_wrapper_install)
+
+if env['systemd']:
+ systemctl_daemon_reload = Utility('systemctl-daemon-reload', '', [ 'systemctl daemon-reload || true'])
+ env.AlwaysBuild(systemctl_daemon_reload)
+ env.Precious(systemctl_daemon_reload)
+ env.Requires(udev_install, systemd_install)
+ env.Requires(systemctl_daemon_reload, systemd_install)
+ env.Requires(udev_install, systemctl_daemon_reload)
+
Utility('udev-uninstall', '', [
'rm -f %s/gpsd.hotplug' % env['udevdir'],
diff --git a/gpsd.rules.in b/gpsd.rules.in
index 9840a6e0..bd445bfa 100644
--- a/gpsd.rules.in
+++ b/gpsd.rules.in
@@ -22,32 +22,32 @@
SUBSYSTEM!="tty", GOTO="gpsd_rules_end"
# Prolific Technology, Inc. PL2303 Serial Port [linux module: pl2303]
-ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK+="gps%n", @udevcommand@
# ATEN International Co., Ltd UC-232A Serial Port [linux module: pl2303]
-ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="0557", ATTRS{idProduct}=="2008", SYMLINK+="gps%n", @udevcommand@
# PS-360 OEM (GPS sold with MS Street and Trips 2005) [linux module: pl2303]
-ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="067b", ATTRS{idProduct}=="aaa0", SYMLINK+="gps%n", @udevcommand@
# FTDI 8U232AM / FT232 [linux module: ftdi_sio]
-ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="gps%n", @udevcommand@
# Cypress M8/CY7C64013 (Delorme uses these) [linux module: cypress_m8]
-ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0100", SYMLINK+="gps%n", @udevcommand@
# Cypress M8/CY7C64013 (DeLorme LT-40)
-ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="1163", ATTRS{idProduct}=="0200", SYMLINK+="gps%n", @udevcommand@
# Garmin International GPSmap, various models (tested with Garmin GPS 18 USB) [linux module: garmin_gps]
-ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="091e", ATTRS{idProduct}=="0003", SYMLINK+="gps%n", @udevcommand@
# Cygnal Integrated Products, Inc. CP210x Composite Device (Used by Holux m241 and Wintec grays2 wbt-201) [linux module: cp210x]
-ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="gps%n", @udevcommand@
# Cygnal Integrated Products, Inc. [linux module: cp210x]
-ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea71", SYMLINK+="gps%n", @udevcommand@
# u-blox AG, u-blox 5 (tested with Navilock NL-402U) [linux module: cdc_acm]
-ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a5", SYMLINK+="gps%n", @udevcommand@
# u-blox AG, u-blox 6 (tested with GNSS Evaluation Kit TCXO) [linux module: cdc_acm]
-ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="1546", ATTRS{idProduct}=="01a6", SYMLINK+="gps%n", @udevcommand@
# MediaTek (tested with HOLUX M-1200E) [linux module: cdc_acm]
-ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{idVendor}=="0e8d", ATTRS{idProduct}=="3329", SYMLINK+="gps%n", @udevcommand@
# Telit wireless solutions (tested with HE910G) [linux module: cdc_acm]
-ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK+="gps%n", RUN+="@udevdir@/gpsd.hotplug"
+ATTRS{interface}=="Telit Wireless Module Port", ATTRS{bInterfaceNumber}=="06", SYMLINK+="gps%n", @udevcommand@
-ACTION=="remove", RUN+="@udevdir@/gpsd.hotplug"
+ACTION=="remove", @udevcommand@
LABEL="gpsd_rules_end"
diff --git a/systemd/gpsd.service b/systemd/gpsd.service
index 8deaf759..ef760a1e 100644
--- a/systemd/gpsd.service
+++ b/systemd/gpsd.service
@@ -3,7 +3,9 @@ Description=GPS (Global Positioning System) Daemon
Requires=gpsd.socket
[Service]
-ExecStart=/usr/sbin/gpsd -N
+EnvironmentFile=-/etc/default/gpsd
+EnvironmentFile=-/etc/sysconfig/gpsd
+ExecStart=/usr/sbin/gpsd -N $GPSD_OPTIONS $DEVICES
[Install]
Also=gpsd.socket
diff --git a/systemd/gpsd.socket b/systemd/gpsd.socket
index 4836c4ea..4c1502af 100644
--- a/systemd/gpsd.socket
+++ b/systemd/gpsd.socket
@@ -3,6 +3,7 @@ Description=GPS (Global Positioning System) Daemon Sockets
[Socket]
ListenStream=/var/run/gpsd.sock
+ListenStream=[::1]:2947
ListenStream=127.0.0.1:2947
SocketMode=0600
diff --git a/systemd/gpsdctl@.service b/systemd/gpsdctl@.service
new file mode 100644
index 00000000..58c5176d
--- /dev/null
+++ b/systemd/gpsdctl@.service
@@ -0,0 +1,13 @@
+[Unit]
+Description=Manage %I for GPS daemon
+Requires=gpsd.socket
+BindsTo=dev-%i.device
+After=dev-%i.device
+
+[Service]
+Type=oneshot
+Environment="GPSD_SOCKET=/var/run/gpsd.sock"
+EnvironmentFile=-/etc/default/gpsd
+RemainAfterExit=yes
+ExecStart=/bin/sh -c "[ \"$USBAUTO\" = true ] && /usr/sbin/gpsdctl add /dev/%I || :"
+ExecStop=/bin/sh -c "[ \"$USBAUTO\" = true ] && /usr/sbin/gpsdctl remove /dev/%I || :"