kvm 虚拟机运行 destroy之后磁盘数据丢失恢复
一、问题
kvm启动的一个jenkins虚拟机登录不了,vnc连接虚拟机的控制台,报内存溢出错误。我登录virsh --connect qemu:///system 登录虚拟机,shutdown domain_xxxx .等了5分钟都不能关机。悲剧来了,我用destroy domain_xxxx,启动这个虚拟机之后,报如下错误:/boot/grub2/i386-pc/normal.mod not found

二、分析
普通电脑强制关机,会损坏硬盘,没有想到虚拟机强制关机,也会损坏镜像文件。网上找了一通类似情况,结果启动不了。

看到ls (hd0,msdos1)/ 有一些数据,但是没有/etc /data /boot 分区。
所以它会报错
/boot/grub2/i386-pc/normal.mod not found 。里面的是jenkins的uat数据,500G很重要,怎么办呢?
在grub 尝试修复
三、尝试先用centos7 挂载这个磁盘镜像,用xfs_repair 修复这个镜像文件
新开一个虚拟机,挂载这个损坏的镜像,用xfs_repair 修复后,发现,还是找不到/boot /etc/ /data目录。
四、不幸中的万幸,真正需要的数据还在盘里面。
快速的办法是,新开的虚拟机重新安装jenkins,做个软链接链接到jenkins的数据盘,文件解决了。
五、注意的地方是:用xfs_repair修复之前要拷贝一份数据,万一修复把盘再次损坏,原来的数据也找不回来了。还有,如果能
顺利挂载磁盘,先把重要的数据先拷贝一份出来,放在修复,的时候再次损坏磁盘。
六、附上grub 操作 参考 https://blog.csdn.net/bytxl/article/details/9253713
通过命令行来引导操作系统的流程,也没有什么难的;无非是把指令手工输入到
grub>
提示符的后面;在这个过程中,
tab
键的命令补齐功能就显得很重要了。如果您不知道有哪些命令,可以输入
help
;
1
)进入
GRUB
的命令行模式
grub>
如果开机时,
GRUB
出现的是
grub>
,说明你没有
/etc/grub/menu.lst
,您需要自己写一个才会
GRUB
的菜单,让我们来选择进入哪个系统。如果有
GRUB
的菜单,您可以按
Ctrl+c
组合键进入
GRUB
的命令行模式,会出现
grub>
提示符;
grub>
2
)获取帮助
GRUB
的
help
只要您在
grub>
提示符的后面输入
help
就能得到
GRUB
所有的命令提示;
grub> help
blocklistFILE boot
catFILE chainloader [--force] FILE
clear color NORMAL [HIGHLIGHT]
configfileFILE device DRIVE DEVICE
displayapm displaymem
findFILENAME geometry DRIVE [CYLINDER HEAD SECTOR [
halt [--no-apm] help [--all] [PATTERN ...]
hidePARTITION initrd FILE [ARG ...]
kernel[--no-mem-option] [--type=TYPE] makeactive
mapTO_DRIVEFROM_DRIVE md5crypt
moduleFILE [ARG...] modulenounzip FILE [ARG ...]
pager[FLAG] partnew PART TYPE START LEN
parttypePARTTYPE quit
reboot root [DEVICE [HDBIAS]]
rootnoverify[DEVICE [HDBIAS]] serial [--unit=UNIT][--port=PORT] [--
setkey[TO_KEYFROM_KEY] setup [--prefix=DIR] [--stage2=STAGE2_
terminal[--dumb] [--no-echo] [--no-ed terminfo [--name=NAME --cursor-address
testvbeMODE unhide PARTITION
uppermemKBYTES vbeprobe [MODE]
如果需要得到某个指令的帮助,就在
help
后面空一格,然后输入指令,比如;
grub>help kernel
3
)
cat
的用法;
cat
指令是用来查看文件内容的,有时我们不知道
Linux
的
/boot
分区,以及
/
根分区所在的位置,要查看
/etc/fstab
的内容来得知,这时,我们就要用到
cat (hd[0-n],y)/etc/fstab
来获得这些内容;注意要学会用
tab
键命令补齐的功能;
grub> cat (
按tab 键会出来hd0或hd1之类的;
grub>cat (hd0,
注:输入hd0,然后再按tab键;会出来分区之类的;
grub>cat (hd0,6)
Possiblepartitions are:
Partition num: 0, Filesystem type unknown, partition type 0x7
Partition num: 4, Filesystem type is fat, partition type 0xb
Partition num: 5, Filesystem type is reiserfs, partition type 0x83
Partition num: 6, Filesystem type is ext2fs, partition type 0x83
Partition num: 7, Filesystem type unknown, partition type 0x83
Partition num: 8, Filesystem type is reiserfs, partition type 0x83
Partition num: 9, Filesystem type unknown, partition type 0x82
grub>cat (hd0,6)/etc/fstab
注:比如我想查看一下 (hd0,6)/etc/fstab的内容就这样输入;
LABEL=/ / ext3 defaults 1 1
/dev/devpts /dev/pts devpts gid=5,mode=620 0 0
/dev/shm /dev/shm tmpfs defaults 0 0
/dev/proc /proc proc defaults 0 0
/dev/sys /sys sysfs defaults 0 0
LABEL=SWAP-hda1 swap swap defaults 0 0
/dev/hdc /media/cdrecorder auto pamconsole,exec,noauto,
managed0 0
有的弟兄可能会说,我不知道
Linux
安装在了哪个分区。那根据文件系统来判断一个一个的尝试总可以吧我;只要能
cat
出
/etc/fstab
就能为以后引导带来方便;
主要查看
/etc/fstab
中的内容,主要是
Linux
的
/
分区及
/boot
是否是独立的分区;如果没有
/boot
类似的行,证明
/boot
和
Linux
的
/
处于同一个硬盘分区;比如上面的例子中
LABEL=/
这行是极为重要的;说明
Linux
系统就安在标签为
LABEL=/
的分区中;
如果您的
Linux
系统
/boot
和
/
没有位于同一个分区,可能
cat (hd[a-n],y)
查到的是类似下面的;
LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
4
)
root (hd[0-n,y)
指令来指定
/boot
所在的分区;
其实这个
root (hd[0,n],y)
是可以省略的,如果省略了,我们要在
kerenl
命令中指定;我们前面已经说过
(hd[0-n],y)
硬盘分区的表示方法的用途;主要是用来指定
/boot
所在的分区;
比如我们确认
/boot
和
(hd0,6)
,所以就可以这样来输入
root (hd0,6)
grub> root (hd0,6)
如果发现不对,可以重新来过;没有什么大不了的;
5
)
kernel
指令,用来指定
Linux
的内核,及
/
所在的分区;
kernel
这个指令可能初学者有点怕,不知道内核在哪个分区,及内核文件名的全称是什么。不要忘记
tab
键的命令补齐的应用;
如果我们已经通过
root (hd[0-n],y)
指定了
/boot
所在的分区,语法有两个:
如果
/boot
和
Linux
的
/
位于同一个分区,应该是下面的一种格式;
kernel /boot/vmlinuz
在这里按
tab
键来补齐,就看到内核全称了
ro root=/dev/hd[a-z]X
如果
/boot
有自己独立的分区,应该是;
kernel /vmlinuz
在这里按
tab
键来补齐,就看到内核全称了
ro root=/dev/hd[a-z]X
在这里
root=/dev/hd[a-z]X
是
Linux
的
/
根所位于的分区,如果不知道是哪个分区,就用
tab
出来的来计算,一个一个的尝试;或用
cat (hd[0-n],y)/etc/fstab
中得到
Linux
的
/
所在的分区或分区的标签;
grub> kernel /boot/
在这里按tab键;这样就列出/boot中的文件了;
Possiblefiles are: grub initrd-2.6.11-1.1369_FC4.img System.map-2.6.11-1.1369
_FC4config-2.6.11-1.1369_FC4 vmlinuz-2.6.11-1.1369_FC4 grubBAK memtest86+-1.55
.1xen-syms xen.gz
grub>kernel /boot/vmlinuz-2.6.11-1.1369_FC4 ro root=LABEL=/
[Linux-bzImage, setup=0x1e00, size=0x18e473]
注解:
root=LABEL=/
是
Linux
的
/
所在的分区的文件系统的标签;如果您知道
Linux
的
/
在哪个具体的分区,用
root=/dev/hd[a-z]X
来指定也行。比如下面的一行也是可以的;
grub> kernel/boot/vmlinuz-2.6.11-1.1369_FC4 ro root=/dev/hda7
也可以把
/boot
所在的分区的指定
root (hd[0-n],y)
这行省掉,直接在
kernel
中指定
/boot
所在的分区;所以就在下面的语法;
如果是
/boot
和
Linux
的根同处一个分区;
kernel (hd[0-n],y)/boot/vmlinuz roroot=/dev/hd[a-z]X
比如:
grub>kernel
如果是
/boot
和
Linux
所在的根不在一个分区;则是;
kernel (hd[0-n],y)/vmlinuz roroot=/dev/hd[a-z]X
grub> kernel (hd0,6)/boot/vmlinuz-2.6.11-1.1369_FC4ro root=/dev/hda7
[Linux-bzImage, setup=0x1e00, size=0x18e473]
或下面的输入,以
cat
出
/etc/fstab
内容为准;
grub> kernel(hd0,6)/boot/vmlinuz-2.6.11-1.1369_FC4 ro root=LABEL=/
[Linux-bzImage, setup=0x1e00, size=0x18e473]
6
)
initrd
命令行来指定
initrd
文件;
grub> initrd /boot/initrd
在这里tab来补齐;
grub>initrd /boot/initrd-2.6.11-1.1369_FC4.img
[Linux-initrd @ 0x2e1000, 0x10e685 bytes]
如果
/boot
是独立的一个分区,应该是如下样子的语法;比如下面的;
grub> initrd /initrd
在这里tab来补齐;
grub>initrd /initrd-2.6.11-1.1369_FC4.img
[Linux-initrd @ 0x2e1000, 0x10e685 bytes]
7
)
boot
引导系统;
grub>boot
前面的几个步骤都弄好
。就进入引导;尝试一下就知道了。。