systemd/init 绑定到端口

systemd/init 绑定到端口

我在 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/initgspd 在这方面做得比我好。

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

我试过了:

  1. 修改为从/lib/systemd/system/gpsd.socket更改为,但是当我重新启动时,却绑定到那个(如上面的代码块所示)。 ListenStream127.0.0.1:29470.0.0.0:2947init
  2. sudo killall gspd然后再次重新启动,但这似乎没有帮助。
  3. 修改/etc/default/gpsd为以下内容:

    START_DAEMON="true"
    GPSD_OPTIONS=""
    DEVICES="/dev/ttyUSB0"
    USBAUTO="false"
    GPSD_SOCKET="/var/run/gpsd.sock"
    
  4. 自定义启动脚本/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 并设置第二个的竞争方法。

您使用的第一个方法是systemdsocket activation。在此设计中,systemd设置第二个并等待与套接字的连接。当某些东西连接到套接字时,systemd激活服务以便它可以响应。这就是“套接字激活”。如果您想使用此方法,推荐阅读包括这篇博文关于套接字激活以及官方文档systemd 套接字文件

您使用的第二种方法是gpsd通过 开始持续运行rc.local并设置您自己的套接字。此方法目前systemd已尝试为您执行此操作,但失败了。如果您希望使用此方法并禁用systemd,您可以运行:

systemctl stop gpsd
systemctl disable gpsd

我建议使用systemd。如果不想,则不必使用套接字激活功能。systemd可以处理gpsd将处理守护进程崩溃时的重新启动,而您的rc.local脚本不会这样做。systemd还将处理守护进程可能执行的任何日志记录,而您的rc.local脚本也不会处理。

相关内容