疑难解答
寻找错误
这个例子中的失败的服务是 systemd-modules-load
:
1. 通过 systemd 寻找启动失败的服务:
- $ systemctl --state=failed
- systemd-modules-load.service loaded failed failed Load Kernel Modules
或者使用 systemd 消息:
- $ journalctl -fp err
2. 我们发现了启动失败的 systemd-modules-load
服务. 我们想知道更多信息:
- $ systemctl status systemd-modules-load
- systemd-modules-load.service - Load Kernel Modules
- Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
- Active: failed (Result: exit-code) since So 2013-08-25 11:48:13 CEST; 32s ago
- Docs: man:systemd-modules-load.service(8).
- man:modules-load.d(5)
- Process: 15630 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=1/FAILURE)
如果没列出 Process ID
, 通过 systemctl
重新启动失败的服务 ( 例如 systemctl restart systemd-modules-load
)
3. 现在得到了 PID ,你就可以进一步探查错误的详细信息了.通过下列的命令收集日志,PID 参数是你刚刚得到的 Process ID
(例如 15630):
- $ journalctl -b _PID=15630
- -- Logs begin at Sa 2013-05-25 10:31:12 CEST, end at So 2013-08-25 11:51:17 CEST. --
- Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'blacklist usblp'
- Aug 25 11:48:13 mypc systemd-modules-load[15630]: Failed to find module 'install usblp /bin/false'
4. 我们发现有些内核模块的配置文件不正确,因此在 /etc/modules-load.d/
中检查一下:
- $ ls -Al /etc/modules-load.d/
- ...
- -rw-r--r-- 1 root root 79 1. Dez 2012 blacklist.conf
- -rw-r--r-- 1 root root 1 2. Mär 14:30 encrypt.conf
- -rw-r--r-- 1 root root 3 5. Dez 2012 printing.conf
- -rw-r--r-- 1 root root 6 14. Jul 11:01 realtek.conf
- -rw-r--r-- 1 root root 65 2. Jun 23:01 virtualbox.conf
- ...
5. 错误消息 Failed to find module 'blacklist usblp'
也许和 blacklist.conf
相关. 让我们注释掉第三步发现的错误的选项:
- /etc/modules-load.d/blacklist.conf
- # blacklist usblp
- # install usblp /bin/false
6. 最后重新启动 systemd-modules-load
服务:
- # systemctl start systemd-modules-load
如果服务成功启动,不会有任何输出.如果你还是遇到了错误,回到步骤三,获得新的 PID 来跟踪日志并解决错误.
可以像这样确认服务成功启动:
- $ systemctl status systemd-modules-load
- systemd-modules-load.service - Load Kernel Modules
- Loaded: loaded (/usr/lib/systemd/system/systemd-modules-load.service; static)
- Active: active (exited) since So 2013-08-25 12:22:31 CEST; 34s ago
- Docs: man:systemd-modules-load.service(8)
- man:modules-load.d(5)
- Process: 19005 ExecStart=/usr/lib/systemd/systemd-modules-load (code=exited, status=0/SUCCESS)
- Aug 25 12:22:31 mypc systemd[1]: Started Load Kernel Modules.
诊断启动问题
使用如下内核参数引导:systemd.log_level=debug systemd.log_target=kmsg log_buf_len=1M
更多有关调试的信息,参见该文。
诊断一个服务
如果某个 systemd 服务的工作状况不合预期,希望调试的话,设置 SYSTEMDLOG_LEVEL
环境变量 为 debug
. 例如以调试模式运行 _systemd-networkd 服务:
在此服务的配置文件片段中加入:
- [Service]
- Environment=SYSTEMD_LOG_LEVEL=debug
或者等价的,临时编辑系统单元文件,例如:
- SYSTEMDLOG_LEVEL=debug /lib/systemd/systemd-networkd
重启_systemd-networkd 服务,用—follow
选项检查日志。
关机/重启十分缓慢
如果关机特别慢(甚至跟死机了一样),很可能是某个拒不退出的服务在作怪。systemd 会等待一段时间,然后再尝试杀死它。请阅读这篇文章,确认你是否是该问题受害者。
短时进程无日志记录
若 journalctl -u foounit.service
没有显示某个短时进程的任何输出,那么改用 PID 试试。例如,若 systemd-modules-load.service
执行失败,那么先用 systemctl status systemd-modules-load
查询其 PID(比如是123),然后检索该 PID 相关的日志 journalctl -b _PID=123
。运行时进程的日志元数据(诸如 _SYSTEMD_UNIT 和 _COMM)被乱序收集在 /proc
目录。要修复该问题,必须修改内核,使其通过套接字连接来提供上述数据,该过程类似于 SCM_CREDENTIALS。
禁止在程序崩溃时转储内存
要使用老的内核转储,创建下面文件:
- /etc/sysctl.d/49-coredump.conf
- kernel.core_pattern = core
- kernel.core_uses_pid = 0
然后运行:
- # /usr/lib/systemd/systemd-sysctl
同样可能需要执行“unlimit”设置文件大小:
- $ ulimit -c unlimited
更多信息请参阅 sysctl.d 和 /proc/sys/kernel 文档。
启动的时间太长
不少用户用了 systemd-analyze
命令以后报告启动的时间比预计的要长,通常会说 systemd-analyze
分析结果表示 NetworkManager 占据了太多的启动的时间.
有些用户的问题是 /var/log/journal
文件夹似乎过大.这也许也会对像systemctl status
或 journalctl
的命令有影响.一种解决方案是删除其中的文件 (但最好将它们备份到某处) 然后限制日志文件的大小.
systemd-tmpfiles-setup.service 在启动时启动失败
从 systemd 219 开始, /usr/lib/tmpfiles.d/systemd.conf
指定 /var/log/journal
的 ACL 属性和目录, 因此日志所在的文件系统上要启用ACL.
参阅 Access Control Lists#Enabling ACL 获得如何包含 /var/log/journal
启动 ACL 的详细信息.
启动时显示的 systemd 版本和安装版本不一致
需要 重新生成 initramfs。
提示: 可以使用 pacman 钩子在更新 systemd时重新生成 initramfs。参考 这个帖子 和 Pacman#Hooks.
禁用远程机器的 emergency 模式
如果远程机器位于云主机,emergency 模式会导致系统无法远程连接,可以通过下面方式禁用紧急模式:
- # systemctl mask emergency.service
- # systemctl mask emergency.target