Google Compute Engine VM 实例:VFS:无法在未知块上挂载根 fs
Google Compute Engine VM instance: VFS: Unable to mount root fs on unknown-block
我在 Google Compute Engine 上的实例由于某些启动顺序问题而无法启动。
所以,我创建了另一个实例并重新配置了我的机器。
我的问题:
- 托管一些网站时如何处理这些问题?
- 如何从旧磁盘恢复数据?
日志
[ 0.348577] Key type trusted registered
[ 0.349232] Key type encrypted registered
[ 0.349769] AppArmor: AppArmor sha1 policy hashing enabled
[ 0.350351] ima: No TPM chip found, activating TPM-bypass!
[ 0.351070] evm: HMAC attrs: 0x1
[ 0.351549] Magic number: 11:333:138
[ 0.352077] block ram3: hash matches
[ 0.352550] rtc_cmos 00:00: setting system clock to 2015-12-19 17:06:53 UTC (1450544813)
[ 0.353492] BIOS EDD facility v0.16 2004-Jun-25, 0 devices found
[ 0.354108] EDD information not available.
[ 0.536267] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input2
[ 0.537862] md: Waiting for all devices to be available before autodetect
[ 0.538979] md: If you don't use raid, use raid=noautodetect
[ 0.539969] md: Autodetecting RAID arrays.
[ 0.540699] md: Scanned 0 and added 0 devices.
[ 0.541565] md: autorun ...
[ 0.542093] md: ... autorun DONE.
[ 0.542723] VFS: Cannot open root device "sda1" or unknown-block(0,0): error -6
[ 0.543731] Please append a correct "root=" boot option; here are the available partitions:
[ 0.545011] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[ 0.546199] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.19.0-39-generic #44~14.04.1-Ubuntu
[ 0.547579] Hardware name: Google Google, BIOS Google 01/01/2011
[ 0.548728] ffffea00008ae140 ffff880024ee7db8 ffffffff817af92b 000000000000111e
[ 0.549004] ffffffff81a7c7c8 ffff880024ee7e38 ffffffff817a976b ffff880024ee7dd8
[ 0.549004] ffffffff00000010 ffff880024ee7e48 ffff880024ee7de8 ffff880024ee7e38
[ 0.549004] Call Trace:
[ 0.549004] [] dump_stack+0x45/0x57
[ 0.549004] [] panic+0xc1/0x1f5
[ 0.549004] [] mount_block_root+0x210/0x2a9
[ 0.549004] [] mount_root+0x54/0x58
[ 0.549004] [] prepare_namespace+0x16d/0x1a6
[ 0.549004] [] kernel_init_freeable+0x1f6/0x20b
[ 0.549004] [] ? initcall_blacklist+0xc0/0xc0
[ 0.549004] [] ? rest_init+0x80/0x80
[ 0.549004] [] kernel_init+0xe/0xf0
[ 0.549004] [] ret_from_fork+0x58/0x90
[ 0.549004] [] ? rest_init+0x80/0x80
[ 0.549004] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[ 0.549004] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
- How to handle these issues when I host some websites?
我不确定您是如何遇到这种情况的,但最好能提供更多信息(请参阅我上面的评论)以便能够理解触发此问题的原因。
- How to recover my data from old disk?
附加并装载磁盘
假设您在删除实例时没有删除原始磁盘,您可以简单地从另一个VM挂载该磁盘以读取其中的数据。为此:
attach the disk to another VM instance,例如,
gcloud compute instances attach-disk $INSTANCE --disk $DISK
挂载磁盘:
sudo mkdir -p /mnt/disks/[MNT_DIR]
sudo mount [OPTIONS] /dev/disk/by-id/google-[DISK_NAME] /mnt/disks/[MNT_DIR]
注意:您需要将适当的值替换为:
MNT_DIR
:目录
OPTIONS
:适合您的磁盘和文件系统的选项
DISK_NAME
: 附加到虚拟机后的磁盘id
卸载和分离磁盘
当您使用完磁盘后,反向执行以下步骤:
注意:在分离非根磁盘之前,请先卸载该磁盘。分离已安装的磁盘可能会导致 I/O 操作不完整和数据损坏。
卸载磁盘
sudo umount /dev/disk/by-id/google-[DISK_NAME]
-
gcloud compute instances detach-disk $INSTANCE --device-name my-new-device
这是什么原因造成的?
这是百万美元的问题。检查我的 GCE VM 后,我发现安装了 14 个不同的内核,占用了数百 MB space。大多数内核没有相应的 initrd.img 文件,因此无法启动(包括 3.19.0-39-generic)。
我当然从来没有四处尝试安装随机内核,一旦删除,它们就不再显示为可用升级,所以我不确定发生了什么。说真的,发生了什么事?
Edit: New response from Google Cloud Support.
I received another disconcerting response. This may explain the additional, errant kernels.
"On rare occasions, a VM needs to be migrated from one physical host to another. In such case, a kernel upgrade and security patches might be applied by Google."
1。 "How can I handle these issues when I host some websites?"
我的第一直觉是推荐使用 AWS 而不是 GCE。但是,GCE 更便宜。在进行 任何 升级之前,请确保拍摄快照,并尝试重新启动服务器以查看升级是否有任何问题。
2。如何从旧磁盘恢复我的数据?
更好 - 如何恢复您的实例...
经过几封 back-and-forth 电子邮件后,我终于收到支持人员的回复,让我得以解决问题。请注意,您必须进行更改以匹配您独特的 VM。
首先拍摄磁盘快照,以防我们需要回滚以下任何更改。
编辑损坏实例的属性以禁用此选项:"Delete boot disk when instance is deleted"
删除损坏的实例。
重要提示:确保不要select删除启动盘的选项。否则,磁盘将被永久删除!!
启动一个新的临时实例。
将损坏的磁盘(这将显示为 /dev/sdb1
)附加到临时实例
启动临时实例后,执行以下操作:
在临时实例中:
# Run fsck to fix any disk corruption issues
$ sudo fsck.ext4 -a /dev/sdb1
# Mount the disk from the broken vm
$ sudo mkdir /mnt/sdb
$ sudo mount /dev/sdb1 /mnt/sdb/ -t ext4
# Find out the UUID of the broken disk. In this case, the uuid of sdb1 is d9cae47b-328f-482a-a202-d0ba41926661
$ ls -alt /dev/disk/by-uuid/
lrwxrwxrwx. 1 root root 10 Jan 6 07:43 d9cae47b-328f-482a-a202-d0ba41926661 -> ../../sdb1
lrwxrwxrwx. 1 root root 10 Jan 6 05:39 a8cf6ab7-92fb-42c6-b95f-d437f94aaf98 -> ../../sda1
# Update the UUID in grub.cfg (if necessary)
$ sudo vim /mnt/sdb/boot/grub/grub.cfg
注意:这里^^^是我偏离支持说明的地方。
我没有修改所有的引导条目以设置 root=UUID=[uuid character string]
,而是查找所有设置 root=/dev/sda1
的条目并将它们删除。我还删除了所有未设置 initrd.img
文件的条目。在我的案例中,具有正确参数的顶级引导条目最终是 3.19.0-31-generic。但你的可能不一样。
# Flush all changes to disk
$ sudo sync
# Shut down the temporary instance
$ sudo shutdown -h now
最后,将硬盘与临时实例分离,并基于固定磁盘创建一个新实例。它有望启动。
假设它确实启动了,您还有很多工作要做。如果你有一半的未使用内核,那么你可能想要清除未使用的内核(特别是因为有些可能缺少相应的 initrd.img 文件)。
我在 this askubuntu question 中使用了 第二个 答案(terminal-based 一个)来清除其他内核。
注意:确保您没有清除启动时使用的内核!
在我的例子中,grub 的 (/boot/grub/grub.cfg) 第一个菜单条目 (3.19.0-51-generic) 缺少一个 initrd 条目并且无法启动。
经过进一步调查,查看特定内核的 dpkg,它被标记为失败和未配置
dpkg -l | grep 3.19.0-51-generic
iF linux-image-3.19.0-51-generic 3.19.0-51.58~14.04.1
iU linux-image-extra-3.19.0-51-generic 3.19.0-51.58~14.04.1
这一切都源于 Google 提供的 Ubuntu 图像,启用了无人值守升级。由于某种原因,initrd 在构建时被杀死,并且出现了其他东西 运行 update-grub2.
unattended-upgrades-dpkg_2016-03-10_06:49:42.550403.log:update-initramfs: Generating /boot/initrd.img-3.19.0-51-generic
Killed
E: mkinitramfs failure cpio 141 xz -8 --check=crc32 137
unattended-upgrades-dpkg_2016-03-10_06:49:42.550403.log:update-initramfs: failed for /boot/initrd.img-3.19.0-51-generic with 1.
解决眼前的问题 运行。
dpkg --force-confold --configure -a
虽然理论上无人值守升级是个好主意,但默认启用它可能会产生无人值守的后果。
在少数情况下,内核无法处理 initrdless 启动。禁用 GRUB_FORCE_PARTUUID 选项,以便它使用 initrd 引导。
我在 Google Compute Engine 上的实例由于某些启动顺序问题而无法启动。
所以,我创建了另一个实例并重新配置了我的机器。
我的问题:
- 托管一些网站时如何处理这些问题?
- 如何从旧磁盘恢复数据?
日志
[ 0.348577] Key type trusted registered [ 0.349232] Key type encrypted registered [ 0.349769] AppArmor: AppArmor sha1 policy hashing enabled [ 0.350351] ima: No TPM chip found, activating TPM-bypass! [ 0.351070] evm: HMAC attrs: 0x1 [ 0.351549] Magic number: 11:333:138 [ 0.352077] block ram3: hash matches [ 0.352550] rtc_cmos 00:00: setting system clock to 2015-12-19 17:06:53 UTC (1450544813) [ 0.353492] BIOS EDD facility v0.16 2004-Jun-25, 0 devices found [ 0.354108] EDD information not available. [ 0.536267] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input2 [ 0.537862] md: Waiting for all devices to be available before autodetect [ 0.538979] md: If you don't use raid, use raid=noautodetect [ 0.539969] md: Autodetecting RAID arrays. [ 0.540699] md: Scanned 0 and added 0 devices. [ 0.541565] md: autorun ... [ 0.542093] md: ... autorun DONE. [ 0.542723] VFS: Cannot open root device "sda1" or unknown-block(0,0): error -6 [ 0.543731] Please append a correct "root=" boot option; here are the available partitions: [ 0.545011] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) [ 0.546199] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.19.0-39-generic #44~14.04.1-Ubuntu [ 0.547579] Hardware name: Google Google, BIOS Google 01/01/2011 [ 0.548728] ffffea00008ae140 ffff880024ee7db8 ffffffff817af92b 000000000000111e [ 0.549004] ffffffff81a7c7c8 ffff880024ee7e38 ffffffff817a976b ffff880024ee7dd8 [ 0.549004] ffffffff00000010 ffff880024ee7e48 ffff880024ee7de8 ffff880024ee7e38 [ 0.549004] Call Trace: [ 0.549004] [] dump_stack+0x45/0x57 [ 0.549004] [] panic+0xc1/0x1f5 [ 0.549004] [] mount_block_root+0x210/0x2a9 [ 0.549004] [] mount_root+0x54/0x58 [ 0.549004] [] prepare_namespace+0x16d/0x1a6 [ 0.549004] [] kernel_init_freeable+0x1f6/0x20b [ 0.549004] [] ? initcall_blacklist+0xc0/0xc0 [ 0.549004] [] ? rest_init+0x80/0x80 [ 0.549004] [] kernel_init+0xe/0xf0 [ 0.549004] [] ret_from_fork+0x58/0x90 [ 0.549004] [] ? rest_init+0x80/0x80 [ 0.549004] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff) [ 0.549004] ---[ end Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
- How to handle these issues when I host some websites?
我不确定您是如何遇到这种情况的,但最好能提供更多信息(请参阅我上面的评论)以便能够理解触发此问题的原因。
- How to recover my data from old disk?
附加并装载磁盘
假设您在删除实例时没有删除原始磁盘,您可以简单地从另一个VM挂载该磁盘以读取其中的数据。为此:
attach the disk to another VM instance,例如,
gcloud compute instances attach-disk $INSTANCE --disk $DISK
挂载磁盘:
sudo mkdir -p /mnt/disks/[MNT_DIR]
sudo mount [OPTIONS] /dev/disk/by-id/google-[DISK_NAME] /mnt/disks/[MNT_DIR]
注意:您需要将适当的值替换为:
MNT_DIR
:目录OPTIONS
:适合您的磁盘和文件系统的选项DISK_NAME
: 附加到虚拟机后的磁盘id
卸载和分离磁盘
当您使用完磁盘后,反向执行以下步骤:
注意:在分离非根磁盘之前,请先卸载该磁盘。分离已安装的磁盘可能会导致 I/O 操作不完整和数据损坏。
卸载磁盘
sudo umount /dev/disk/by-id/google-[DISK_NAME]
-
gcloud compute instances detach-disk $INSTANCE --device-name my-new-device
这是什么原因造成的?
这是百万美元的问题。检查我的 GCE VM 后,我发现安装了 14 个不同的内核,占用了数百 MB space。大多数内核没有相应的 initrd.img 文件,因此无法启动(包括 3.19.0-39-generic)。
我当然从来没有四处尝试安装随机内核,一旦删除,它们就不再显示为可用升级,所以我不确定发生了什么。说真的,发生了什么事?
Edit: New response from Google Cloud Support.
I received another disconcerting response. This may explain the additional, errant kernels.
"On rare occasions, a VM needs to be migrated from one physical host to another. In such case, a kernel upgrade and security patches might be applied by Google."
1。 "How can I handle these issues when I host some websites?"
我的第一直觉是推荐使用 AWS 而不是 GCE。但是,GCE 更便宜。在进行 任何 升级之前,请确保拍摄快照,并尝试重新启动服务器以查看升级是否有任何问题。
2。如何从旧磁盘恢复我的数据?
更好 - 如何恢复您的实例...
经过几封 back-and-forth 电子邮件后,我终于收到支持人员的回复,让我得以解决问题。请注意,您必须进行更改以匹配您独特的 VM。
首先拍摄磁盘快照,以防我们需要回滚以下任何更改。
编辑损坏实例的属性以禁用此选项:"Delete boot disk when instance is deleted"
删除损坏的实例。
重要提示:确保不要select删除启动盘的选项。否则,磁盘将被永久删除!!
启动一个新的临时实例。
将损坏的磁盘(这将显示为
/dev/sdb1
)附加到临时实例启动临时实例后,执行以下操作:
在临时实例中:
# Run fsck to fix any disk corruption issues
$ sudo fsck.ext4 -a /dev/sdb1
# Mount the disk from the broken vm
$ sudo mkdir /mnt/sdb
$ sudo mount /dev/sdb1 /mnt/sdb/ -t ext4
# Find out the UUID of the broken disk. In this case, the uuid of sdb1 is d9cae47b-328f-482a-a202-d0ba41926661
$ ls -alt /dev/disk/by-uuid/
lrwxrwxrwx. 1 root root 10 Jan 6 07:43 d9cae47b-328f-482a-a202-d0ba41926661 -> ../../sdb1
lrwxrwxrwx. 1 root root 10 Jan 6 05:39 a8cf6ab7-92fb-42c6-b95f-d437f94aaf98 -> ../../sda1
# Update the UUID in grub.cfg (if necessary)
$ sudo vim /mnt/sdb/boot/grub/grub.cfg
注意:这里^^^是我偏离支持说明的地方。
我没有修改所有的引导条目以设置 root=UUID=[uuid character string]
,而是查找所有设置 root=/dev/sda1
的条目并将它们删除。我还删除了所有未设置 initrd.img
文件的条目。在我的案例中,具有正确参数的顶级引导条目最终是 3.19.0-31-generic。但你的可能不一样。
# Flush all changes to disk
$ sudo sync
# Shut down the temporary instance
$ sudo shutdown -h now
最后,将硬盘与临时实例分离,并基于固定磁盘创建一个新实例。它有望启动。
假设它确实启动了,您还有很多工作要做。如果你有一半的未使用内核,那么你可能想要清除未使用的内核(特别是因为有些可能缺少相应的 initrd.img 文件)。
我在 this askubuntu question 中使用了 第二个 答案(terminal-based 一个)来清除其他内核。
注意:确保您没有清除启动时使用的内核!
在我的例子中,grub 的 (/boot/grub/grub.cfg) 第一个菜单条目 (3.19.0-51-generic) 缺少一个 initrd 条目并且无法启动。
经过进一步调查,查看特定内核的 dpkg,它被标记为失败和未配置
dpkg -l | grep 3.19.0-51-generic
iF linux-image-3.19.0-51-generic 3.19.0-51.58~14.04.1
iU linux-image-extra-3.19.0-51-generic 3.19.0-51.58~14.04.1
这一切都源于 Google 提供的 Ubuntu 图像,启用了无人值守升级。由于某种原因,initrd 在构建时被杀死,并且出现了其他东西 运行 update-grub2.
unattended-upgrades-dpkg_2016-03-10_06:49:42.550403.log:update-initramfs: Generating /boot/initrd.img-3.19.0-51-generic
Killed
E: mkinitramfs failure cpio 141 xz -8 --check=crc32 137
unattended-upgrades-dpkg_2016-03-10_06:49:42.550403.log:update-initramfs: failed for /boot/initrd.img-3.19.0-51-generic with 1.
解决眼前的问题 运行。
dpkg --force-confold --configure -a
虽然理论上无人值守升级是个好主意,但默认启用它可能会产生无人值守的后果。
在少数情况下,内核无法处理 initrdless 启动。禁用 GRUB_FORCE_PARTUUID 选项,以便它使用 initrd 引导。