为什么我的 systemd 服务无法在启动时启动,但可以手动启动?

为什么我的 systemd 服务无法在启动时启动,但可以手动启动?

我编写了一个 systemd 服务,以便在机器启动时启动无线接入点。我的问题是,机器启动时它实际上并未启动,我似乎无法找出原因。手动启动服务效果很好。

我的wap.service系统单元文件:

[Unit]
Description=Enable the Wireless Access Point
Requires=dnsmasq.service iptables.service NetworkManager.service
Before=dnsmasq.service
After=iptables.service NetworkManager.service

[Service]
Type=oneshot
RemainAfterExit=true
ExecStart=/project/wap.sh
TimeoutStartSec=0

[Install]
WantedBy=default.target

/project/wap.sh(大括号是 Ansible/Jinja2 变量替换):

#!/usr/bin/env bash

set -Eeuo pipefail

# Allow incoming DNS requests.
iptables -I INPUT -p udp --dport 53 -j ACCEPT -m comment --comment "DNS"

# Allow incoming DHCP requests.
iptables -I INPUT -p udp --dport 67 -j ACCEPT -m comment --comment "DHCP"

# Relinquish NetworkManager control over the wireless network interface.
nmcli r wifi off
rfkill unblock wifi

# Up and configure the wireless network interface.
ifconfig {{ap_interface}} 192.168.2.1 up
route add -net 0.0.0.0 netmask 255.255.255.0 gw 192.168.2.1 || true

# Restart hostapd so it can successfully bind to the newly configured wireless network interface.
service hostapd restart

相关/usr/lib/systemd/systemd --test --system --unit=default.target输出:

    -> Unit wap.service:
        Description: Enable the Wireless Access Point
        Instance: n/a
        Unit Load State: loaded
        Unit Active State: inactive
        Inactive Exit Timestamp: n/a
        Active Enter Timestamp: n/a
        Active Exit Timestamp: n/a
        Inactive Enter Timestamp: n/a
        GC Check Good: no
        Need Daemon Reload: no
        Transient: no
        Slice: system.slice
        CGroup: n/a
        CGroup realized: no
        CGroup mask: 0x0
        CGroup members mask: 0x0
        Name: wap.service
        Fragment Path: /etc/systemd/system/wap.service
        Requires: dnsmasq.service
        Requires: NetworkManager.service
        Requires: basic.target
        Requires: iptables.service
        Wants: system.slice
        WantedBy: multi-user.target
        Conflicts: shutdown.target
        Before: dnsmasq.service
        Before: multi-user.target
        Before: shutdown.target
        After: systemd-journald.socket
        After: iptables.service
        After: NetworkManager.service
        After: system.slice
        After: basic.target
        References: systemd-journald.socket
        References: iptables.service
        References: NetworkManager.service
        References: system.slice
        References: dnsmasq.service
        References: shutdown.target
        References: basic.target
        ReferencedBy: multi-user.target
        StopWhenUnneeded: no
        RefuseManualStart: no
        RefuseManualStop: no
        DefaultDependencies: yes
        OnFailureJobMode: replace
        IgnoreOnIsolate: no
        IgnoreOnSnapshot: no
        Service State: dead
        Result: success
        Reload Result: success
        PermissionsStartOnly: no
        RootDirectoryStartOnly: no
        RemainAfterExit: yes
        GuessMainPID: yes
        Type: oneshot
        Restart: no
        NotifyAccess: none
        NotifyState: unknown
        KillMode: control-group
        KillSignal: SIGTERM
        SendSIGKILL: yes
        SendSIGHUP:  no
        UMask: 0022
        WorkingDirectory: /
        RootDirectory: /
        NonBlocking: no
        PrivateTmp: no
        PrivateNetwork: no
        PrivateDevices: no
Loaded units and determined initial transaction in 75ms.        ProtectHome: no
        ProtectSystem: no

        IgnoreSIGPIPE: yes
        LimitNOFILE: 1024 4096
        StandardInput: null
        StandardOutput: journal
        StandardError: inherit
        SyslogFacility: daemon
        SyslogLevel: info
        -> ExecStart:
            Command Line: /project/wap.sh

重启后服务状态:

$ sudo service wap status -l
Redirecting to /bin/systemctl status  -l wap.service
● wap.service - Enable the Wireless Access Point
   Loaded: loaded (/etc/systemd/system/wap.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

手动启动后服务状态:

$ sudo service wap start
Redirecting to /bin/systemctl start wap.service
$ sudo service wap status -l
Redirecting to /bin/systemctl status  -l wap.service
● wap.service - Enable the Wireless Access Point
   Loaded: loaded (/etc/systemd/system/wap.service; enabled; vendor preset: disabled)
   Active: active (exited) since do 2019-09-26 12:10:40 BST; 6s ago
  Process: 8589 ExecStart=/project/wap.sh (code=exited, status=0/SUCCESS)
 Main PID: 8589 (code=exited, status=0/SUCCESS)

sep 26 12:10:40 localhost.localdomain systemd[1]: Starting Enable the Wireless Access Point...
sep 26 12:10:40 localhost.localdomain wap.sh[8589]: Redirecting to /bin/systemctl restart hostapd.service
sep 26 12:10:40 localhost.localdomain systemd[1]: Started Enable the Wireless Access Point.

journalctl输出:

$ journalctl -u wap
-- No entries --

我已确认wap.sh在机器启动时永远不会运行,但我无法在系统日志中找到有关此服务的任何信息,例如尝试启动该服务。

太长了;我的服务应该在启动时启动,但没有启动,我不明白为什么。

答案1

也许就像这样简单?:

systemctl 启用 wap.service

答案2

我的问题的原因原来是一个不存在的目标。我应该使用 ,而不是default.target(它是一个符号链接,至少在 CentOS 上,但不对应于运行级别),multi-user.target它对应于运行级别 3。正确的配置将变为:

[Install]
WantedBy=multi-user.target

谢谢大家的时间和反馈!

答案3

Systemd 服务文件仅在启用时被读取,并且它们的顺序和依赖关系链接到图表中,通常通过在其目标或服务的所需目录之一中包含符号链接(通常在 /etc/systemd/system/ 中用于用户创建的服务) )。 systemctl 启用操作将从服务文件的 [Install] 部分中列出的链接实例化这些链接。

答案4

修复系统单元后,我必须禁用并重新启用该服务

# systemctl disable etcd
Removed /etc/systemd/system/multi_user.target.wants/etcd.service.


# systemctl enable etcd
Created symlink /etc/systemd/system/multi-user.target.wants/etcd.service → /etc/systemd/system/etcd.service.
## note the path changed 

相关内容