文章目录
- debian12 - systemctl 根据状态值判断服务启动成功的依据
- 概述
- 笔记
- 用配置好的原版debian12试试状态值。
- 实验结论
- END
debian12 - systemctl 根据状态值判断服务启动成功的依据
概述
和同学讨论问题,说到服务的运行状态。
拿ssh服务为例。
查询ssh服务状态
sudo systemctl status ssh
他认为,只有 active(running)的状态,才说明服务被正常启动了。
我认为,只要服务干活了,就说明服务被启动了。 e.g. 已经监听了端口,那服务没退,进程还在,就说明服务已经启动了。
笔记
systemctl在哪里?
lostspeed@debian12d4x64:~$ whereis systemctl
systemctl: /usr/bin/systemctl /usr/share/man/man1/systemctl.1.gz
用windterm连上ssh, 拷贝出来
弄出来用IDA看看。
从这2个参考点开始看。
疑似第一个参考点更靠谱。
现在对着IDA和源码比对一下。
systemctl是systemd中的一个程序。
systemd 源码在 https://github.com/systemd/systemd.git
迁出后的systemctl工程源码位置 = D:\3rd_prj\linux\systemd\src\systemctl
将D:\3rd_prj\linux\systemd\src\systemctl作为一个SI工程,查找 “Active: %s%s (%s)%s”
看到在 D:\3rd_prj\linux\systemd\src\systemctl\systemctl-show.c 中实现的, 函数为 print_status_info()。
虽然不能单步调试,但是顺着逻辑看一下,也能学到些东西。
调用链
show_one(bus, p, u->id, show_mode, new_line, ellipsized);
print_status_info()
从打印这块看不出Active状态哪个不是正常运行的状态。
要显示的服务状态信息都是调用 bus_map_all_properties()取的。
看一下 bus_map_all_properties(), 看了,看不到填状态的地方,都是从map中取值/赋值。
到此,简单的从systemctl源码看,并不知道active(XX)中的XX状态字符串,哪种不是服务正常启动的状态。
那只能去看systemctl的命令行帮助了。
man systemctl
从帮助可知,直接查看systemctl的所有状态值。
systemctl --state=help > systemctl_help.txt
Available unit load states:
stub
loaded
not-found
bad-setting
error
merged
masked
Available unit active states:
active
reloading
inactive
failed
activating
deactivating
maintenance
Available unit file states:
enabled
enabled-runtime
linked
linked-runtime
alias
masked
masked-runtime
static
disabled
indirect
generated
transient
bad
Available automount unit substates:
dead
waiting
running
failed
Available device unit substates:
dead
tentative
plugged
Available mount unit substates:
dead
mounting
mounting-done
mounted
remounting
unmounting
remounting-sigterm
remounting-sigkill
unmounting-sigterm
unmounting-sigkill
failed
cleaning
Available path unit substates:
dead
waiting
running
failed
Available scope unit substates:
dead
start-chown
running
abandoned
stop-sigterm
stop-sigkill
failed
Available service unit substates:
dead
condition
start-pre
start
start-post
running
exited
reload
stop
stop-watchdog
stop-sigterm
stop-sigkill
stop-post
final-watchdog
final-sigterm
final-sigkill
failed
auto-restart
cleaning
Available slice unit substates:
dead
active
Available socket unit substates:
dead
start-pre
start-chown
start-post
listening
running
stop-pre
stop-pre-sigterm
stop-pre-sigkill
stop-post
final-sigterm
final-sigkill
failed
cleaning
Available swap unit substates:
dead
activating
activating-done
active
deactivating
deactivating-sigterm
deactivating-sigkill
failed
cleaning
Available target unit substates:
dead
active
Available timer unit substates:
dead
waiting
running
elapsed
failed
可以看到,在running之前,还有一个start状态。
start状态说明服务已经启动了
running状态说明服务正在运行
如果服务已经启动了,但是还没有正常运行,这不也是说明服务在正常干活么?
在看systemctl帮助时,看到一些可以确定服务状态的命令。试试。
将环境切到我正常实验的openssl3.2 + openssh9.6P1的快照。
lostspeed@debian12d4x64:~$ openssl --version
OpenSSL 3.2.0 23 Nov 2023 (Library: OpenSSL 3.2.0 23 Nov 2023)
lostspeed@debian12d4x64:~$ ssh -V
OpenSSH_9.6p1, OpenSSL 3.2.0 23 Nov 2023
此时查看ssh服务状态为 activating(start).
用windterm按照ssh方式连接虚拟机中的debian12
连接正常。连接后,可以正常执行命令。
这不就说明ssh服务是正常的么? 这还用看服务激活状态是activating(start) , 还是 activating(runninng)么?
查看ssh服务是否处于激活状态?
lostspeed@debian12d4x64:~$ systemctl is-active ssh
activating
这不就是说ssh服务是激活的么? 这还用看activating(runninng)么?
查看ssh服务是否失败?
lostspeed@debian12d4x64:~$ systemctl is-failed ssh
activating
服务还是激活的。
再显示ssh服务所有信息到文件看看。
systemctl show ssh > show_ssh.txt
show_ssh.txt内容如下:
Type=notify
ExitType=main
Restart=on-failure
NotifyAccess=main
RestartUSec=100ms
TimeoutStartUSec=1min 30s
TimeoutStopUSec=1min 30s
TimeoutAbortUSec=1min 30s
TimeoutStartFailureMode=terminate
TimeoutStopFailureMode=terminate
RuntimeMaxUSec=infinity
RuntimeRandomizedExtraUSec=0
WatchdogUSec=0
WatchdogTimestampMonotonic=0
RootDirectoryStartOnly=no
RemainAfterExit=no
GuessMainPID=yes
RestartPreventExitStatus=255
MainPID=2253
ControlPID=0
FileDescriptorStoreMax=0
NFileDescriptorStore=0
StatusErrno=0
Result=success
ReloadResult=success
CleanResult=success
UID=[not set]
GID=[not set]
NRestarts=9
OOMPolicy=stop
ExecMainStartTimestamp=Mon 2024-08-26 14:22:17 CST
ExecMainStartTimestampMonotonic=819044146
ExecMainExitTimestampMonotonic=0
ExecMainPID=2253
ExecMainCode=0
ExecMainStatus=0
ExecStartPre={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -t ; ignore_errors=no ; start_time=[Mon 2024-08-26 14:22:16 CST] ; stop_time=[Mon 2024-08-26 14:22:17 CST] ; pid=2252 ; code=exited ; status=0 }
ExecStartPreEx={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -t ; flags= ; start_time=[Mon 2024-08-26 14:22:16 CST] ; stop_time=[Mon 2024-08-26 14:22:17 CST] ; pid=2252 ; code=exited ; status=0 }
ExecStart={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -D $SSHD_OPTS ; ignore_errors=no ; start_time=[Mon 2024-08-26 14:22:17 CST] ; stop_time=[n/a] ; pid=2253 ; code=(null) ; status=0/0 }
ExecStartEx={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -D $SSHD_OPTS ; flags= ; start_time=[Mon 2024-08-26 14:22:17 CST] ; stop_time=[n/a] ; pid=2253 ; code=(null) ; status=0/0 }
ExecReload={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -t ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
ExecReload={ path=/bin/kill ; argv[]=/bin/kill -HUP $MAINPID ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
ExecReloadEx={ path=/usr/sbin/sshd ; argv[]=/usr/sbin/sshd -t ; flags= ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
ExecReloadEx={ path=/bin/kill ; argv[]=/bin/kill -HUP $MAINPID ; flags= ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }
Slice=system.slice
ControlGroup=/system.slice/ssh.service
ControlGroupId=6878
MemoryCurrent=5660672
MemoryAvailable=infinity
CPUUsageNSec=19314000
TasksCurrent=5
IPIngressBytes=[no data]
IPIngressPackets=[no data]
IPEgressBytes=[no data]
IPEgressPackets=[no data]
IOReadBytes=18446744073709551615
IOReadOperations=18446744073709551615
IOWriteBytes=18446744073709551615
IOWriteOperations=18446744073709551615
Delegate=no
CPUAccounting=yes
CPUWeight=[not set]
StartupCPUWeight=[not set]
CPUShares=[not set]
StartupCPUShares=[not set]
CPUQuotaPerSecUSec=infinity
CPUQuotaPeriodUSec=infinity
IOAccounting=no
IOWeight=[not set]
StartupIOWeight=[not set]
BlockIOAccounting=no
BlockIOWeight=[not set]
StartupBlockIOWeight=[not set]
MemoryAccounting=yes
DefaultMemoryLow=0
DefaultMemoryMin=0
MemoryMin=0
MemoryLow=0
MemoryHigh=infinity
MemoryMax=infinity
MemorySwapMax=infinity
MemoryLimit=infinity
DevicePolicy=auto
TasksAccounting=yes
TasksMax=2244
IPAccounting=no
ManagedOOMSwap=auto
ManagedOOMMemoryPressure=auto
ManagedOOMMemoryPressureLimit=0
ManagedOOMPreference=none
EnvironmentFiles=/etc/default/ssh (ignore_errors=yes)
UMask=0022
LimitCPU=infinity
LimitCPUSoft=infinity
LimitFSIZE=infinity
LimitFSIZESoft=infinity
LimitDATA=infinity
LimitDATASoft=infinity
LimitSTACK=infinity
LimitSTACKSoft=8388608
LimitCORE=infinity
LimitCORESoft=0
LimitRSS=infinity
LimitRSSSoft=infinity
LimitNOFILE=524288
LimitNOFILESoft=1024
LimitAS=infinity
LimitASSoft=infinity
LimitNPROC=7480
LimitNPROCSoft=7480
LimitMEMLOCK=8388608
LimitMEMLOCKSoft=8388608
LimitLOCKS=infinity
LimitLOCKSSoft=infinity
LimitSIGPENDING=7480
LimitSIGPENDINGSoft=7480
LimitMSGQUEUE=819200
LimitMSGQUEUESoft=819200
LimitNICE=0
LimitNICESoft=0
LimitRTPRIO=0
LimitRTPRIOSoft=0
LimitRTTIME=infinity
LimitRTTIMESoft=infinity
OOMScoreAdjust=0
CoredumpFilter=0x33
Nice=0
IOSchedulingClass=2
IOSchedulingPriority=4
CPUSchedulingPolicy=0
CPUSchedulingPriority=0
CPUAffinityFromNUMA=no
NUMAPolicy=n/a
TimerSlackNSec=50000
CPUSchedulingResetOnFork=no
NonBlocking=no
StandardInput=null
StandardOutput=journal
StandardError=inherit
TTYReset=no
TTYVHangup=no
TTYVTDisallocate=no
SyslogPriority=30
SyslogLevelPrefix=yes
SyslogLevel=6
SyslogFacility=3
LogLevelMax=-1
LogRateLimitIntervalUSec=0
LogRateLimitBurst=0
SecureBits=0
CapabilityBoundingSet=cap_chown cap_dac_override cap_dac_read_search cap_fowner cap_fsetid cap_kill cap_setgid cap_setuid cap_setpcap cap_linux_immutable cap_net_bind_service cap_net_broadcast cap_net_admin cap_net_raw cap_ipc_lock cap_ipc_owner cap_sys_module cap_sys_rawio cap_sys_chroot cap_sys_ptrace cap_sys_pacct cap_sys_admin cap_sys_boot cap_sys_nice cap_sys_resource cap_sys_time cap_sys_tty_config cap_mknod cap_lease cap_audit_write cap_audit_control cap_setfcap cap_mac_override cap_mac_admin cap_syslog cap_wake_alarm cap_block_suspend cap_audit_read cap_perfmon cap_bpf cap_checkpoint_restore
DynamicUser=no
RemoveIPC=no
PrivateTmp=no
PrivateDevices=no
ProtectClock=no
ProtectKernelTunables=no
ProtectKernelModules=no
ProtectKernelLogs=no
ProtectControlGroups=no
PrivateNetwork=no
PrivateUsers=no
PrivateMounts=no
PrivateIPC=no
ProtectHome=no
ProtectSystem=no
SameProcessGroup=no
UtmpMode=init
IgnoreSIGPIPE=yes
NoNewPrivileges=no
SystemCallErrorNumber=2147483646
LockPersonality=no
RuntimeDirectoryPreserve=no
RuntimeDirectoryMode=0755
RuntimeDirectory=sshd
StateDirectoryMode=0755
CacheDirectoryMode=0755
LogsDirectoryMode=0755
ConfigurationDirectoryMode=0755
TimeoutCleanUSec=infinity
MemoryDenyWriteExecute=no
RestrictRealtime=no
RestrictSUIDSGID=no
RestrictNamespaces=no
MountAPIVFS=no
KeyringMode=private
ProtectProc=default
ProcSubset=all
ProtectHostname=no
KillMode=process
KillSignal=15
RestartKillSignal=15
FinalKillSignal=9
SendSIGKILL=yes
SendSIGHUP=no
WatchdogSignal=6
Id=ssh.service
Names=ssh.service sshd.service
Requires=-.mount system.slice sysinit.target
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=systemd-journald.socket system.slice network.target sysinit.target basic.target auditd.service -.mount
RequiresMountsFor=/run/sshd
Documentation="man:sshd(8)" "man:sshd_config(5)"
Description=OpenBSD Secure Shell server
LoadState=loaded
ActiveState=activating
FreezerState=running
SubState=start
FragmentPath=/lib/systemd/system/ssh.service
UnitFileState=enabled
UnitFilePreset=enabled
StateChangeTimestamp=Mon 2024-08-26 14:22:17 CST
StateChangeTimestampMonotonic=819044198
InactiveExitTimestamp=Mon 2024-08-26 14:22:16 CST
InactiveExitTimestampMonotonic=819034304
ActiveEnterTimestampMonotonic=0
ActiveExitTimestampMonotonic=0
InactiveEnterTimestamp=Mon 2024-08-26 14:22:16 CST
InactiveEnterTimestampMonotonic=819022694
CanStart=yes
CanStop=yes
CanReload=yes
CanIsolate=no
CanClean=runtime
CanFreeze=yes
Job=2214
StopWhenUnneeded=no
RefuseManualStart=no
RefuseManualStop=no
AllowIsolate=no
DefaultDependencies=yes
OnSuccessJobMode=fail
OnFailureJobMode=replace
IgnoreOnIsolate=no
NeedDaemonReload=no
JobTimeoutUSec=infinity
JobRunningTimeoutUSec=infinity
JobTimeoutAction=none
ConditionResult=yes
AssertResult=yes
ConditionTimestamp=Mon 2024-08-26 14:22:16 CST
ConditionTimestampMonotonic=819023037
AssertTimestamp=Mon 2024-08-26 14:22:16 CST
AssertTimestampMonotonic=819023059
Transient=no
Perpetual=no
StartLimitIntervalUSec=10s
StartLimitBurst=5
StartLimitAction=none
FailureAction=none
SuccessAction=none
InvocationID=653b73dc30c34ada8459f319bc25710a
CollectMode=inactive
可以看到ssh状态为start, ssh的冻结状态为running
冻结状态好像是电源管理用的,保存的就是进程的最后状态。
冻结状态就代表的是进程的当前状态。
现在看到ssh的冻结状态为running,说明ssh服务就是正常运行的。
用配置好的原版debian12试试状态值。
切到配置好的原版快照。
systemctl show ssh > show_ssh_org.txt
原版的冻结状态也是running
但是子状态为running
实验结论
从实际效果和show出的ssh状态可以看出,只要冻结状态为running, 就说明服务启动成功。
子状态是running 或者 start 都可以。
其实最终是要看效果,管它啥状态。(e.g. 对于ssh服务,只要用ssh方式能正常连上ssh服务,能正常执行linux命令,那就明显就是ssh服务已经正常启动并干活了,这就不需要再额外证明ssh服务状态查询时,显示的啥状态值才代表ssh服务启动正常)