openSUSE:Systemd 侦错
systemd-analyze 安装
sudo zypper in systemd-analyze
The "Blame" Game
优化前我们需要先来玩一场「推诿」的游戏,就是看看是哪个 service 占用了最多的开机时间。
systemd-analyze blame | head
systemd-analyze blame 是把服务按运行时间的长短排序,最长的在最上面。head 是返回时间最长的 10 个,如:
238588ms systemd-tmpfiles-setup.service 3037ms NetworkManager.service 1953ms avahi-daemon.service 1762ms systemd-logind.service 1686ms postfix.service 1255ms fglrxrebuild.service 1132ms systemd-vconsole-setup.service 1071ms systemd-udev-root-symlink.service 974ms cycle.service 931ms dev-mqueue.mount
更加先进的还有:
systemd-analyze plot > systemd.svg
这将生成一个 svg 图片,告诉你哪些服务是并行启动的,它们又占用了多长时间。
揪出元凶
知道了哪个服务慢是不够的,你还要知道那个服务为什么慢。所以就因服务而异了。
如果你耗时的服务是如 NetworkManager.service 这种自身提供了日志的程序,那么去 /var/log 检查它的日志。否则你要用到 strace。
strace 大显神威
首先我们要去 /usr/lib/systemd/system 下找到耗时的 .service 文件,把它复制到 /etc/systemd/system。这一过程又叫做 mask(遮挡),因为对 systemd 来说,/usr/lib/systemd/system 是给发行版用的,/etc/systemd/system 是给系统管理员用的。后者的优先级比前者高(便于管理),这样 /etc 里有同名服务,就不会去跑 /usr 里的服务,于是 /usr 里的服务就被「遮挡」掉了。
下面打开那个服务,查找 ExecStart= 这行:
ExecStart=/usr/bin/systemd-tmpfiles --create --remove
在前面加上 /usr/bin/strace -f -tt -o /var/run/%N.strace,变成:
ExecStart=/usr/bin/strace -f -tt -o /var/run/%N.strace /usr/bin/systemd-tmpfiles --create --remove
重启。
这时遮挡生效,于是 /var/run 里有了一个 systemd-tmpfiles-setup.strace 的文本文件,内容是 strace 记录的 /usr/bin/systemd-tmpfiles 进行的磁盘读写、打开文件等操作。
打开它,找出耗时最长的操作,如:
463 19:37:42.939174 getdents(4, /* 586 entries */, 32768) = 32752 463 19:41:39.007576 getdents(4, /* 585 entries */, 32768) = 32760
我们可以看出将近 4 分钟的时间里,这个 service 只干了一件事,那就是:
getdents(4, /* 586 entries */, 32768)
于是我们要去 google 这个操作究竟是干嘛的。
getdents - get directory entries
它一直在获取某个文件夹。究竟获取哪个文件夹呢?
21124 21:47:35.935581 openat(AT_FDCWD, "/home/marguerite/Documents/KDE", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 3 21124 21:47:35.935662 getdents(3, /* 26 entries */, 32768) = 832 21124 21:47:35.935776 getdents(3, /* 0 entries */, 32768) = 0
在它最上访的 openat 函数的第二个参数说明了这个文件夹的路径。
于是问题找到。可能是你的某个 tmp 文件夹太大(好长时间没清理了),或者是权限不对(没有读取权限)之类的。相应找方法处理下(用 tmpwatch 啊,chmod 啊之类的)。
重启。再用 systemd-analyze blame | grep systemd-tmpfiles-setup.service 查看:
222ms systemd-tmpfiles-setup.service
成功!
这时删除掉我们之前进行的遮挡:
sudo rm -rf /etc/systemd/system/systemd-tmpfiles-setup.service
收工!
参考链接
作者
MargueriteSu 2013年6月25日 (二) 08:30 (MDT)