正在进行的项目所用的系统是基于ubuntu构建的,前文也有说明。由于某些原因,需要在一块主板上用dd命令拷贝已经做好的系统镜像到硬盘,然后将这个硬盘换到另一块板子上使用。近期发现一个问题,就是将拷贝好系统的硬盘换到新的主板上使用,启动时系统变成只读系统。变成只读系统时,只读系统的提示信息如下:

1/etc/rc3.d/S99myscript: 25: /etc/rc3.d/S99myscript: cannot create /etc/udev/rules.d/70-persistent-net.rules: Read-only file system

其实很早就遇到过一次,只是那时又由于某些原因,没有过多的样机进行那种方式的测试,因此没有引起重视。对于出现机率小又无法解释的问题,一般不花心思。比如最近有一台设备的网络状态表现十分诡异,在有的电脑上可以正常连接,有的电脑上连接不了,连接不了的电脑连其它同版本的设备又可以,什么升级同版本、直连、过交换机,改百兆全双工等,都试过。这类问题不知从何下手,即使项目经理催也没用。

当时出问题的信息还保留,如下:

sck from util-linux 2.20.1
swapon: /dev/disk/by-uuid/22f27499-7be5-4b06-8a21-67b135c79fea: swapon failed: Invalid argument
mountall: swapon /dev/disk/by-uuid/22f27499-7be5-4b06-8a21-67b135c79fea [2375] terminated with status 255
mountall: Problem activating swap: /dev/disk/by-uuid/22f27499-7be5-4b06-8a21-67b135c79fea
/dev/sdb2: Superblock last mount time (Mon Dec 15 11:04:01 2014,
now = Sun Feb 16 09:08:04 2014) is in the future.
/dev/sdb2: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
(i.e., without -a or -p options)
mountall: fsck /opt [2339] terminated with status 4
mountall: Filesystem has errors: /opt
mountall: Skipping mounting /opt since Plymouth is not available

当时的解决方法是按提示的做。手动执行fsck。

root@localhost:~# fsck /opt
fsck from util-linux 2.20.1
e2fsck 1.42.9 (4-Feb-2014)
Superblock last mount time (Mon Dec 15 11:04:01 2014,
now = Sun Feb 16 09:10:26 2014) is in the future.
Fix? yes
/dev/sdb2 contains a file system with errors, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
/lost+found not found. Create? yes
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb2: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sdb2: 27/327680 files (0.0% non-contiguous), 56800/1310720 blocks

最关键的信息就是“Superblock last mount time is in the future”,直译过来,是超级块最后一次的挂载时间在未来。就是说,现在这个系统的时间,比上一次使用硬盘的时间,要早,在make编译时,也会遇到这种类似的问题。

网上有这方面的资料,无一例外都是修复磁盘。修复一次后,再也不出现这个问题了。

因此,上文提到的问题的解决,就是在出现只读时,用脚本去修复。因为系统上有2个分区,一个分区挂到根目录/,真正的程序在另一个分区,挂载到/app,当系统启动后,会运行/app/run.sh脚本。如果出现问题,这个分区是挂载不了的,但根分区还是可以挂载的。所以,在根分区中也创建同样的目录、同样的脚本中执行下面的脚本来修改。fsck -y表示直接修复,不用确认。

#!/bin/sh
echo "run internal script and run fsck...."
fsck / -y
fsck /app -y
sleep 1
reboot

实际上,这个问题的确是系统时间造成的。假如将正常的硬盘换到一块bios时间错误(主要是时间比实际时间要小)的主板上,就是出现这个问题。将同一块主板的bios时间往前改,一样出现问题。因此,只能说被bios时间坑了。这个bios时间可不能由上级程序去自动识别,自动修改。——那个时候,硬盘上还未升级有ntp功能的程序。

李迟