今天看到 Unraid 7.3.0 正式版发布,更新日志里最吸引我的就是终于可以不用 U 盘启动了,想着这还整挺好,就直接更新了,结果更新完之后 WebGUI 直接打不开了,服务也都没启动,搜了一下简中互联网还没什么人讨论这个,就在这里记录一下。
问题原因可以参考 Unraid 论坛的这个帖子:https://forums.unraid.net/topic/198869-diagnosed-workaround-730-emhttpd-enoflash4-flash-rejected-guid-null-on-legacy-whole-device-fat-superfloppy-usbs/(话说这个帖子都已经好几天了,正式版居然还没修好吗)
简单来说就是 Unraid 7.3.0 的 emhttpd 对 USB 启动盘的识别逻辑变严格了,要求 U 盘必须有正规的分区表结构(MBR + FAT32 分区),而不接受以前的 superfloppy 格式(整盘直接格式化为 FAT32、没有分区表),而我的 U 盘刚好就是这种格式。
排查
虽然 WebGUI 打不开了,但 SSH 还是通的,先进去看看 syslog:
grep -i "emhttpd\|ENOFLASH\|EGUID\|no partitions\|flash" /var/log/syslog输出里出现了这几行:
emhttpd: Unregistered Pro - invalid key - invalid key (EGUID)
emhttpd: online: SanDisk_Cruzer_Blade_... => no partitions
emhttpd: Error: (/dev/sde) not knownemhttpd 扫描 U 盘发现没有分区,直接退出了。
再用 fdisk 看一下 U 盘的分区表:
fdisk -l /dev/sdeDisk /dev/sde: 29.81 GiB, 32010928128 bytes, 62521344 sectors
Disk model: Cruzer Blade
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x********
Device Boot Start End Sectors Size Id Type
/dev/sde1 3224498923 3657370039 432871117 206.4G 7 HPFS/NTFS/exFAT
/dev/sde2 3272020941 5225480974 1953460034 931.5G 16 Hidden FAT16
/dev/sde3 0 0 0 0B 6f unknown
/dev/sde4 50200576 974536369 924335794 440.8G 0 Empty
Partition table entries are not in disk order.一块 30GB 的 U 盘,分区表里出现了 206G、931G 这种明显超出物理容量的条目,很明显这就是问题所在了,不过 7.2.x 之前居然都是没问题的。
修复
虽然我有云备份,但我还是希望在尽量不重做启动盘的情况下修好,因此全部流程都是直接 SSH 进已经启动的机器里完成的。
Unraid 启动后内核和 /usr 都以 loop mount 的形式加载在内存里了,所以 /boot 是可以安全卸载的,不需要拔 U 盘。
首先确认一下是 UEFI 还是 Legacy 启动:
ls /sys/firmware/eficonfig_table efivars/ esrt/ fw_platform_size fw_vendor runtime systab有输出就是 UEFI,我这里是 UEFI,以下流程针对 UEFI,Legacy 还需要额外处理 syslinux 引导,这里就不展开了。
一、备份 /boot
mkdir /root/boot-backup
cp -a /boot/. /root/boot-backup/
ls /root/boot-backup/ # 确认文件完整再往下走二、卸载 /boot
直接 umount /boot 会因为内核 mount 记录报 busy,用 lazy 模式绕过:
umount -l /boot三、重新分区
parted /dev/sde --script mklabel msdos
parted /dev/sde --script mkpart primary fat32 1MiB 100%
parted /dev/sde --script set 1 boot on四、格式化
这里有个坑,因为内核还缓存着旧的分区信息,直接格式化 /dev/sde1 会报 busy,partprobe、blockdev --rereadpt 都没用,用 losetup 以偏移量的方式绕过就好了:
losetup -f --show -o $((1*1024*1024)) /dev/sde
# 记下输出的设备名,比如 /dev/loop2
mkfs.fat -F 32 -n UNRAID /dev/loop2
losetup -d /dev/loop2五、挂载并还原文件
同样因为内核缓存问题,mount /dev/sde1 /boot 也会失败,改用 offset 方式挂载:
mount -o offset=$((1*1024*1024)) /dev/sde /boot
cp -a /root/boot-backup/. /boot/
sync # 这一步时间可能会比较长,取决于 U 盘写入速度六、重启
reboot重启后如果一切正常,emhttpd 找到合法的分区结构,WebGUI 就回来了。
验证一下
重启后 SSH 进去确认几件事:
fdisk -l /dev/sde应该只有一个干净的 sde1:
Disk /dev/sde: 29.81 GiB, 32010928128 bytes, 62521344 sectors
Disk model: Cruzer Blade
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x********
Device Boot Start End Sectors Size Id Type
/dev/sde1 * 2048 62521343 62519296 29.8G c W95 FAT32 (LBA)grep -i "emhttpd\|flash\|GUID" /var/log/syslog | head -20应该能看到 key 被正常读取,EGUID 和 no partitions 不再出现:
emhttpd: Pro key detected, GUID: XXXX-XXXX-XXXX-XXXXXXXXXXXX FILE: /boot/config/Pro.key
emhttpd: online: SanDisk_Cruzer_Blade_XXXXXXXXXXXXXXXXXXXX-0:0 (sde) 512 62521344 => data partition: sde1 type: dos start: 2048 size: 31259648 code: 0xc (4)cat /proc/mounts | grep sde应该显示 /dev/sde1 正常挂载在 /boot,而不是之前的 offset 方式。
影响范围
凡是以前用 Windows 直接右键格式化 U 盘为 FAT32 然后手动解压 Unraid 文件的用法,基本上都是 superfloppy 格式,升级 7.3.0 前建议先检查一下:
fdisk -l /dev/sdX # X 换成你的 U 盘盘符如果输出里分区大小明显异常,或者根本没有子分区行,就是这个问题,建议先用官方的 USB Creator 工具或者 Rufus(FreeDOS 模式、卷标 UNRAID、FAT32)重新制盘再升级。
用官方 USB Creator 工具制盘的用户不受影响,这个工具生成的一直都是正规分区结构。
虽然可以修好,不过还是建议启用 Unraid Connect 云备份,或者在更新前手动备份启动盘。