前言
那些所谓的坑, 一大半都是欠下的技术债, 迟早是要还的. -- 雨夜狂奔的蜗牛
背景
前后3人零零散散大约耗时3小时, 发现问题原来不过是rc.local的一个特性, 所谓优秀的工程师和普通的工程师的效率可以相差百倍, 这个时候感触是最深的, 虽然之前也一直在定位问题, 但直到现在才慢慢开始意识到定位问题在平常工作中所耗费的时间. 虽然问题算不上高大上, 甚至有点low, 记录下来一来是记录自己的成长过程, 二来也算是对自己的一种鞭策, 下次再遇到类似的问题, 能不能高效定位出问题的关键所在?
结论
使用rc.local时要将自己的命令等放到exit 0前
过程
下午代码写的正起劲, 忽然身后的小h让我查看一个问题, 说是在装机的过程当中物理机设备发现不了了, 但是同样的环境, 同样的脚本在另外一个产品线却是好的. 这一下子就激起了我的好奇心.
按照以往的思路当然是先重现问题,然后才有思路看如何解决问题嘛.
一开始尽然没复现, 开始让我怀疑是不是复现用的虚拟机网卡太少了,网络接口启动以及IP获取太快导致问题没有复现. 然而当我再仔细对比两处的rc.local文件时才发现测试用的虚拟机上面少复制了最关键的一行
加上之后, 复现了!!! 突然间自己也激动起来了, 只要能复现的问题就不是什么大问题.
然后分别进行了以下尝试
- 增加日志打印
- 怀疑跟网络相关->改脚本为启动一个HTTP server
- 改脚本为一般脚本,仅仅打印hello world
- 改为shell
经历了以上方法的折腾陷入了短暂的无思路状态
回想到/var/log/message里面同一时刻的网络接口启动报错, 突然灵光一闪, 大胆猜测, 是否跟网络接口启动失败有关? 网络接口启动失败退出码非0导致rc.local失效? 但后迅速验证, 改systemctl restart network为exit 1, 问题复现, 验证了心中的猜测, 然后再将exit 1改为exit 0重复验证猜测, 启动成功, 这下基本可以确认问题所在了, 然后又去Google了一把发现一堆讲使用rc.local时要将自己的命令放在exit 0之前, 但是就是没有找到为什么要这么做的原因, 或者说rc.local的退出码最终是由谁来处理并没有讲清楚, 待解惑.
参考
https://www.freebsd.org/cgi/man.cgi?query=rc.local&sektion=8