我在 Beaglebone Green 上启动 GPSD 时遇到问题。我收到套接字绑定错误:
root@BBG1:/etc/init# gpsd -D3 -n -N /dev/ttyUSB0
gpsd:INFO: launching (Version 3.16)
gpsd:ERROR: can't bind to IPv4 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:ERROR: can't bind to IPv6 port gpsd, Address already in use
gpsd:ERROR: maybe gpsd is already running!
gpsd:INFO: command sockets creation failed, netlib errors -1, -1
看来这个问题在这些迷你开发板上很常见(包括 Raspberry Pi),但对大多数人来说似乎可以解决问题的方法对我来说却不起作用。据我所知,这是因为systemd/init
gspd 在这方面做得比我好。
root@BBG1:/etc/init# netstat -lnpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:2947 0.0.0.0:* LISTEN 1/init
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 375/connmand
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 493/sshd
tcp6 0 0 ::1:2947 :::* LISTEN 1/init
tcp6 0 0 :::8080 :::* LISTEN 631/apache2
tcp6 0 0 :::80 :::* LISTEN 1/init
tcp6 0 0 ::1:53 :::* LISTEN 375/connmand
tcp6 0 0 :::22 :::* LISTEN 493/sshd
tcp6 0 0 :::1880 :::* LISTEN 1/init
tcp6 0 0 :::3000 :::* LISTEN 1/init
我试过了:
- 修改为从
/lib/systemd/system/gpsd.socket
更改为,但是当我重新启动时,却绑定到那个(如上面的代码块所示)。ListenStream
127.0.0.1:2947
0.0.0.0:2947
init
sudo killall gspd
然后再次重新启动,但这似乎没有帮助。修改
/etc/default/gpsd
为以下内容:START_DAEMON="true" GPSD_OPTIONS="" DEVICES="/dev/ttyUSB0" USBAUTO="false" GPSD_SOCKET="/var/run/gpsd.sock"
自定义启动脚本
/etc/rc.local
(用于延迟 gpsd 的启动,但由于 startgpsd.txt 文件从未更新,因此似乎没有运行)#Start the gpsd daemon /etc/booted/startgpsd.sh exit 0
指向startgpsd.sh
#!/bin/sh -e
#Need to wait past boot so everything is done
date "+%Y-%m-%d %H:%M:%S" > /startgpsd.txt
sleep 2
echo "Starting GPSD" >> /startgpsd.txt
/usr/local/sbin/gpsd /dev/ttyUSB0 -G -n -F /var/run/gpsd.sock
date "+%Y-%m-%d %H:%M:%S" >> /startgpsd.txt
exit 0
p
有一次,当我将 GSPD 从 v 3.11(使用 下载apt-get
)升级到 v 3.16(下载了二进制文件和一大堆其他垃圾,以便我可以构建它)时,它开始工作,但只要我重新启动,我就会回到同样的问题。
有没有办法阻止 systemd 绑定到端口,以便 gpsd 可以绑定(或者这是我的问题)? 杀死 PID 1 似乎不是一个明智的做法,所以我还没有尝试过。 我几乎要清除所有内容并重新开始,但我想我会首先尝试利用这里的“天才的集体力量”(因为我过去已经在这里找到了其他问题的几个答案)。
谢谢!
编辑:添加内容/lib/systemd/system/gpsd.socket
[Unit]
Description=GPS (Global Positioning System) Daemon Sockets
[Socket]
ListenStream=/var/run/gpsd.sock
ListenStream=[::1]:2947
ListenStream=0.0.0.0:2947
SocketMode=0600
[Install]
WantedBy=sockets.target
答案1
这里的问题是,您有尝试启动 gpsd 并设置第二个的竞争方法。
您使用的第一个方法是systemd
和socket activation
。在此设计中,systemd
设置第二个并等待与套接字的连接。当某些东西连接到套接字时,systemd
激活服务以便它可以响应。这就是“套接字激活”。如果您想使用此方法,推荐阅读包括这篇博文关于套接字激活以及官方文档systemd 套接字文件。
您使用的第二种方法是gpsd
通过 开始持续运行rc.local
并设置您自己的套接字。此方法目前systemd
已尝试为您执行此操作,但失败了。如果您希望使用此方法并禁用systemd
,您可以运行:
systemctl stop gpsd
systemctl disable gpsd
我建议使用systemd
。如果不想,则不必使用套接字激活功能。systemd
可以处理gpsd
将处理守护进程崩溃时的重新启动,而您的rc.local
脚本不会这样做。systemd
还将处理守护进程可能执行的任何日志记录,而您的rc.local
脚本也不会处理。