我们有bash脚本(作业包装器)写入文件,启动作业,然后在作业完成时,它附加到有关作业的文件信息.包装器在几千个批处理节点中的一个上运行,但只有多个批处理机器(我相信RHEL6)访问一个NFS服务器,并且至少有一个已知的不同批处理作业的实例使用不同的批处理节点NFS服务器.在所有情况下,只有一个客户端主机正在写入相关文件.有些工作需要数小时才能运行,有些则需要几分钟
在发生这种情况的同一时期,100,000多个工作岗位中似乎有10-50个问题.
以下是我认为有效的作业包装器的(蒸馏)版本:
#!/bin/bash
## cwd is /nfs/path/to/jobwd
## This file is /nfs/path/to/jobwd/job_wrapper
gotEXIT()
{
## end of script, however gotEXIT is called because we trap EXIT
END="EndTime: `date`\nStatus: Ended”
echo -e "${END}" >> job_info
cat job_info | sendmail jobtracker@example.com
}
trap gotEXIT EXIT
function jobSetVar { echo "job.$1: $2" >> job_info; }
export -f jobSetVar
MSG=“${email_metadata}\n${job_metadata}”
echo -e "${MSG}\nStatus: Started" | sendmail jobtracker@example.com
echo -e "${MSG}" > job_info
## At the job’s end, the output from `time` command is the first non-corrupt data in job_info
/usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command
## 10-360 minutes later…
RC=$?
echo -e "ExitCode: ${RC}" >> job_info
所以我认为有两种可能性:
echo -e "${MSG}" > job_info
此命令会抛出损坏的数据.
/usr/bin/time -f "Elapsed: %e\nUser: %U\nSystem: %S" -a -o job_info job_command
这会破坏现有数据,然后正确输出数据.
但是,一些工作,但不是全部工作,调用jobSetVar,它最终不会被破坏.
所以,我深入研究time.c(从GNU时间1.7开始),看看文件何时打开.总而言之,time.c实际上是这样的:
FILE *outfp;
void main (int argc, char** argv) {
const char **command_line;
RESUSE res;
/* internally, getargs opens “job_info”, so outfp = fopen ("job_info", "a”) */
command_line = getargs (argc, argv);
/* run_command doesn't care about outfp */
run_command (command_line, &res);
/* internally, summarize calls fprintf and putc on outfp FILE pointer */
summarize (outfp, output_format, command_line, &res); /
fflush (outfp);
}
所以,时间FILE *outfp
(job_info句柄)打开了整个工作时间.然后它在作业结束时写下摘要,然后实际上似乎没有关闭文件(不确定fflush是否有必要?)我不知道bash是否同时打开文件句柄.
编辑:
损坏的文件通常会由损坏的部分组成,然后是未损坏的部分,可能如下所示:
在未损坏的部分之前发生的损坏部分通常主要是一堆0x0000,可能有一些循环垃圾混合在:
这是一个示例hexdump:
40000000 00000000 00000000 00000000 00000000 00000000 C8B450AC 772B0000 01000000 00000000 C8B450AC 772B0000 [ 361 x 0x00]
然后,在第409个字节,它继续未损坏的部分:
Elapsed: 879.07 User: 0.71 System: 31.49 ExitCode: 0 EndTime: Fri Dec 6 15:29:27 PST 2013 Status: Ended
另一个文件看起来像这样:
01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000 [96 x 0x00] [Repeat above 3 times ] 01000000 04000000 805443FC 9D2B0000 E04144FC 9D2B0000 E04144FC 9D2B0000
其次是未损坏的部分:
Elapsed: 12621.27 User: 12472.32 System: 40.37 ExitCode: 0 EndTime: Thu Nov 14 08:01:14 PST 2013 Status: Ended
还有其他文件具有更多随机损坏部分,但不止一些文件具有与上述类似的周期性.
编辑2:从echo -e
声明发送的第一封电子邮件正常.由于没有损坏的电子邮件元数据,因此永远不会发送最后一封电 所以MSG
在那一点上没有被破坏.假设job_info 在这一点上可能没有损坏,但我们还没有能够验证.这是一个没有重大代码修改的生产系统,我已通过审核验证没有同时运行的任何作业会触及此文件.问题似乎有些近期(最近2个月),但它可能发生在之前并且已经滑落.此错误确实会阻止报告,这意味着作业被视为失败,因此通常会重新提交,但是特定的一个用户有~9小时的作业,其中此错误尤其令人沮丧.我希望我可以提出更多的信息或者随意复制这个,但我希望有人可能会看到类似的问题,特别是最近.我不管理NFS服务器,但我会尝试与管理员交谈,看看在这些问题(我相信RHEL6)运行时NFS服务器的更新.