已索引

该文章已被其它文章引用。

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,计划任务不再正常执行。
修改其属主信息为正常信息后,恢复正常运行。

-- By 许望(RHCA、OCM、VCP)
最后修改:2023 年 12 月 29 日 04 : 01 PM
如果觉得我的文章对你有用,请随意赞赏