已索引
该文章已被其它文章引用。
2023.12.06 公务卡日终跑批时报错说缺少一个文件,该文件通过 crontab 计划任务于每天 21:01 分执行生成。
之前该文件一直正常生成,/var/log/crond 日志中也有计划任务之前的执行记录。
2023.12.06 21:01 没有生成文件,/var/log/crond 日志中也没有执行记录。
查看 /var/log/messages, 无报错信息。
systemctl status crond,无报错信息。
不论是用 root 用户还是该用户,都可以使用 crontab -l 查看到该计划任务。
手工执行 crontab -l 的输出,正常执行完成。
与应用负责人沟通,表示最近该用户并没有修改计划任务。
最后,我们通过 journalctl -u crond.service
查看 crond 的日志,发现有如下内容:
Dec 06 16:19:01 cupdatacard01 crond[24371]: (root) RELOAD (/var/spool/cron/root)
Dec 06 16:19:01 cupdatacard01 crond[24371]: (dumusr) WRONG FILE OWNER (/var/spool/cron/dumusr)
Dec 06 16:19:01 cupdatacard01 crond[24371]: (CRON) INFO (running with inotify support)
Dec 06 16:20:01 cupdatacard01 crond[24371]: (dumusr) WRONG FILE OWNER (/var/spool/cron/dumusr)
Dec 07 09:31:01 cupdatacard01 crond[24371]: (dumusr) WRONG FILE OWNER (/var/spool/cron/dumusr)
查看文件属主和修改时间信息:
# ll /var/spool/cron/dumusr
-rw------- 1 1011 1011 132 Nov 23 2021 /var/spool/cron/dumusr
# stat /var/spool/cron/dumusr
File: ‘/var/spool/cron/dumusr’
Size: 132 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 35440875 Links: 1
Access: (0600/-rw-------) Uid: ( 1011/ UNKNOWN) Gid: ( 1011/ UNKNOWN)
Access: 2023-12-06 16:19:31.344703652 +0800
Modify: 2021-11-23 14:25:05.787139067 +0800
Change: 2021-11-23 14:25:05.787139067 +0800
Birth: -
可以看到,文件名 owner和group 不匹配,且该文件两年来从未改变过。
那为什么一直运行正常,但突然就不行了呢?
是因为当天 root 用户修改了 crontab 任务,导致 crond 重新加载了 /var/spool/cron/ 目录下的所有内容,发现文件属主出错。
Cron searches /var/spool/cron for crontab files which are named after accounts in /etc/passwd; The found crontabs are loaded into the memory.
[root@cupdatacard01 ~]# stat /var/spool/cron/root
File: ‘/var/spool/cron/root’
Size: 472 Blocks: 8 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 35440914 Links: 1
Access: (0600/-rw-------) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2023-12-06 16:18:10.434579420 +0800
Modify: 2023-12-06 16:18:10.405579017 +0800
Change: 2023-12-06 16:18:10.405579017 +0800
Birth: -
再回想一下,两年前上线的时候,为了统一同一套业务系统多台主机的 NFS 文件权限,该用户修改了 uid。
下面是问题重现实验:
准备一个全局可写的文件,备用:
# touch /tmp/testfile.out
# chmod 777 /tmp/testfile.out
新建用户并创建计划任务:
# useradd cy10086
# id cy10086
uid=2003(cy10086) gid=2003(cy10086) groups=2003(cy10086)
# su - cy10086
$ crontab -e
* * * * * /bin/date >> /tmp/testfile.out
观察几分钟,可见每分钟会在 /tmp/testfile.out 中生成一条记录。/var/log/cron 中产生相应的执行记录。
修改用户 uid(计划任务不受影响):
# groupmod -g 3000 cy10086; usermod -u 3000 cy10086; ll /var/spool/cron/ ; date
total 12
-rw------- 1 2003 2003 41 Dec 27 17:14 cy10086
-rw------- 1 root root 109 Dec 19 16:43 root
Wed Dec 27 17:17:54 CST 2023 <--- 修改后的时间
可以看到,cy10086 的计划任务仍然在执行:
# tail -f /tmp/testfile.out
Wed Dec 27 17:15:01 CST 2023
Wed Dec 27 17:16:01 CST 2023
Wed Dec 27 17:17:01 CST 2023
Wed Dec 27 17:18:02 CST 2023 <--- 17点17分修改完成后,计划任务仍然继续执行
Wed Dec 27 17:19:01 CST 2023
Wed Dec 27 17:20:01 CST 2023
Wed Dec 27 17:21:01 CST 2023
现在 root 用户去修改自己的计划任务:
# echo '* * * * * /bin/date' >> /var/spool/cron/root ; date
Wed Dec 27 17:27:07 CST 2023
可以看到,cy10086 的计划任务不再执行,就停留在 root 修改前的最后一次执行记录:
Wed Dec 27 17:26:01 CST 2023
Wed Dec 27 17:27:01 CST 2023
<--- 17点27分修改完成后,计划任务不再执行
通过 journalctl 检查日志,可以看到,17:28:01 时报 WRONG FILE OWNER 错误。
# journalctl -u crond.service
Dec 19 17:39:01 zabbix-server-dev.bot.com crond[1160]: (root) RELOAD (/var/spool/cron/root)
Dec 19 17:42:01 zabbix-server-dev.bot.com crond[1160]: (xuwang) RELOAD (/var/spool/cron/xuwang)
Dec 27 17:13:01 zabbix-server-dev.bot.com crond[1160]: (cy10086) RELOAD (/var/spool/cron/cy10086)
Dec 27 17:15:01 zabbix-server-dev.bot.com crond[1160]: (cy10086) RELOAD (/var/spool/cron/cy10086)
Dec 27 17:28:01 zabbix-server-dev.bot.com crond[1160]: (root) RELOAD (/var/spool/cron/root)
Dec 27 17:28:01 zabbix-server-dev.bot.com crond[1160]: (cy10086) WRONG FILE OWNER (/var/spool/cron/cy10086)
You have new mail in /var/spool/mail/root
更改其属主后,计划任务再次运行:
# chown cy10086.cy10086 /var/spool/cron/cy10086; date
Wed Dec 27 17:34:21 CST 2023
# tail -f /tmp/testfile.out
……
Wed Dec 27 17:26:01 CST 2023
Wed Dec 27 17:27:01 CST 2023
Wed Dec 27 17:35:01 CST 2023
Wed Dec 27 17:36:01 CST 2023
总结:
一个已经存在的计划任务,即因为该用户id被修改导致其对应的 crond 文件属主信息不正确,其计划任务仍能正常执行。
但只要有用户修改了计划任务,或者 crond 进行了重启,都会识别到 WRONG FILE OWNER,计划任务不再正常执行。
修改其属主信息为正常信息后,恢复正常运行。