故事:
昨晚在实验室写了一篇文档,写完临走时,想回
寝室登录到实验室机器上来把今天写的文档拷到
寝室电脑上,又怕忘记了登录白开一晚上机器浪费电,所以临走
之前使用 shutdown -h 22:40 命令,计划在 22:40 关闭计算机。
回去后经过吃饭、喜羊羊等一系列活动,想起这个事情已经是 22:35 左右了,于是赶快 ssh,登录后不久,终端就显示 5
分钟内即将关机的字样,拷贝完文档,我就很自觉地切到 root,直接命令 init 0 关机了。
故障:
今天早晨来到实验室,登录时就出问题了:
普通用户输入用户名密码后,显示“The system is going down on Mon Apr 26 22:40:06
2010”,然后拒绝登录;
切换到 tty1 使用 root,还可以登录,但同样会显示上面的消息。
寻找解决方案:
幸好有 w3m,Google 了一番,找到如下解决方案:“删除 /etc/nologin 文件即可。”
我习惯不删除不懂的东西,所以把该文件移动到了 root 的家目录,问题解决。
附:/etc/nologin 文件的内容正是“The system is going down on Mon Apr 26 22:40:06
2010”,关于这个 nologin 文件的作用,请 man 一下即可。
寻找问题出现的原因:
问题解决以后,开始寻找出现这个问题的原因,为什么会出现 /etc/nologin 这个文件呢?当然立刻想到跟 shutdown
的过程有关,本着追本溯源的精神,我去寻找 shutdown 的源代码,Google 说在包 sysvinit(附源码包)里面。
|
文件: | sysvinit-2.88.tar.gz |
大小: | 122KB |
下载: | 下载 |
|
在这个源码包里,找到 shutdown.c 文件,通读 main(),发现问题的答案,第 750 行到第 758 行:
while(wt) {
if (wt <= 5 && !didnolog) {
donologin(wt);
didnolog++;
}
if (needwarning(wt)) warn(wt);
hardsleep(60);
wt--;
}
|
可以看到当 wt 小于 5 的时候,会执行 donologin() 这个函数。
wt 是计时器,单位是分钟,在第 742 行可以看到我这条命令 “shutdown -h 22:40” 走到给 wt 赋值的分支时执行的语句:
wt = (60*hours + mins) - (60*lt->tm_hour + lt->tm_min);
|
最后是 donologin() 的内容:
void donologin(int min)
{
FILE *fp;
time_t t;
time(&t);
t += 60 * min;
if ((fp = fopen(NOLOGIN, "w")) != NULL) {
fprintf(fp, "\rThe system is going down on %s\r\n", ctime(&t ));
if (message[0]) fputs(message, fp);
fclose(fp);
}
}
|
这里 NOLOGIN 就是 /etc/nologin 文件,可见 shutdown 命令在计划关机时间小于 5
分钟的时候,会通过生成 NOLOGIN 文件阻止新的用户登录。
当倒计时归零时,shutdown 调用 shutdown() 函数关闭计算机,shutdown() 函数会 unlink(NOLOGIN),第
434 行:
删除 /etc/nologin。
所以,在距离关机小于 5 分钟的时候,我手工关闭了计算机,并且没有使用命令 shutdown 而是使用了 init 0,使得 nologin
文件没有被正确删除掉,残留的 nologin 文件导致了不能正确登录。
完。
阅读(2074) | 评论(3) | 转发(0) |