当前位置: 首页 > 科技观察

记一次被Multipath困住的惨痛经历

时间:2023-03-19 21:37:27 科技观察

本文转载自微信公众号《int32bit》,作者int32bit。转载本文请联系int32bit公众号。今天我使用Packer创建了一个SUSE镜像。磁盘格式以前是IDE,这次改成了SCSI。由于磁盘类型发生了变化,我重新生成了initramfs来加载ahci驱动,以支持在启动阶段加载SATA。BINARY_DEPS="tailheadawkifconfigcutexrroutepingncwgettftpgrep"DRACUT_DRIVERS="virtiovirtio_netvirtio_blk"dracut-f-N\--install"$BINARY_DEPS"\--kernel-cmdline"rd.shellrd.driver.pre=ahci"\--kver"$(uname-r)"\--add-drivers"$DRACUT_DRIVERS"\--addlvm\--mdadmconf\--lvmconf\-o"dashplymouth"\initrd-$(uname-r)至于为什么要加载lvm模块,这是环境要求根文件系统必须是LVM,在云环境下其实不推荐。fstab使用所有块设备UUID而不是逻辑卷路径(/dev/sdX)。我担心逻辑卷路径会因磁盘驱动器而改变。谁知道它是否会从/dev/sda1变为/dev/vda1。当时,我认为这样做一定是安全的。启动虚拟机进行验证后,结果出乎意料,系统进入了紧急模式。还好我在initramfs里面配置了rd.shell,不然都不知道怎么进入调试了。输入root密码进入bash,发现原因是/boot没有挂载。尝试手动挂载,看看有什么问题:mount-a#Reinstallfstab挂载卷,提示设备已经挂载或挂载点忙。一定是挂载点/boot没有挂载,所以肯定是设备问题。错误提示磁盘设备已经挂载,但是df和lsblk无论如何都找不到挂载记录。尝试了各种lsof和fuser命令,发现没有进程占用设备。很明显只有一种情况,我猜这个设备是被dm(devicemapper)映射的。使用dmsetup查看所有dm列表,除了lv映射,确实有很多0QEMU_QEMU_HARDDISK开头的dm设备:0QEMU_QEMU_HARDDISK_bcd82475-9f57-43e6-a-partlVM会被dm映射,这没问题,但是/boot是一个physicalpartition,DidnotaddPVtoanyVG,sowhodmthisdevice?Usedmsetupinfotochecktheclues:dmsetupinfo0QEMU_QEMU_HARDDISK_bcd82475-9f57-43e6-a-partName:0QEMU_QEMU_HARDDISK_bcd82475-9f57-43e6-a-partState:ACTIVERead4resspent:102LIVEMajor,minor:254,1Numberoftargets:1UUID:part1-mpath-0QEMU_QEMU_HARDDISK_bcd82475-9f57-43e6-a-part其他信息没什么用,只是UUID中包含mpath,可能是多路径导致的。使用multipath-l命令查看结果:size=40Gfeatures='0'hwhandler='0'wp=rwpolicy='service-time0'prio=0status=active2:0:0:0sda8:0activeundefrunning实际上是整个sda由multipath映射。找到原因并思考解决方案后,就清楚了。检查了multipathd服务,发现是disabled,所以开机后应该没有启动multipathd服务。使用lsmod发现确实加载了多路径内核模块。是否被其他依赖模块拉取?为了确认是多路径服务引起的,运行如下命令确保多路径停止,并强制将多路径内核模块加入黑名单。systemctldisablemultipathdecho"blacklistmultipath">>/etc/modprobe.d/50-blacklist.conf修改/etc/multipath.conf配置文件,明确将sda加入黑名单。blacklist{devnode"^(td|hd|vd)[a-z]"devnode"sda"}重启了虚拟机,结果还是一样的问题,multipath还是强。是不是其他服务启动了多路径?为了排除这种可能性,删除了/usr/lib/systemd/system/multipathd.service。现在没有人可以启动这项服务。重启虚拟机,结果还是出乎意料。多路径还是up,这就够神秘了。更有什者,我把/sbin/multipath和/sbin/multipathd都删掉了,导致服务无法再次运行。再次重启虚拟机,让人怀疑multipathd服务还在像打不倒的小强一样在运行。Google发现了一个类似的问题Systemexittoemergencyshellatbootwithmultipathenabled(SLES12,MPIO)[1]。解决方法无非就是关闭多路径服务或者将设备加入多路径黑名单,但是一点作用都没有。在百思不得其解的情况下,突然灵光一闪,是不是initramfs的问题?这个多路径已经挂载到initramfs上去挂载rootfs了?按照这个想法,唯一的办法就是重新创建initramfs映像并添加多路径模块。进入omit黑名单列表:dracut-f-N\...-o"...multipath"\...替换原来的initrd-xxx文件启动虚拟机后,虚拟机终于神奇的启动成功了。归根结底,原来是在initramfs启动阶段加载了多路径模块,所以在用户态修改和禁用多路径是没有用的。后来在SUSE文档中也找到了相关说明:AlwaysKeeptheinitrdinSynchronizationwiththeSystemConfiguration[2]。这个问题折腾了两个多小时。虽然问题很简单,但是我在OS的踪迹上花了不少时间。我从来没有想过initramfs是问题的根源。参考[1]系统在启用多路径(SLES12、MPIO)的情况下在引导时退出到紧急shell:https://www.suse.com/support/kb/doc/?id=000019607[2]始终保持initrd与系统配置:https://documentation.suse.com/sles/15-SP1/html/SLES-all/cha-multipath.html#sec-multipath-planning-initrd