为什么 NBD 要嵌套 NBD?qcow2 镜像链解析原理

创建 NBD 镜像时,为什么要把 backing 的所有镜像全部设置为 NBD? 因为镜像链的解析是 qemu driver 负责的,NBD 和本地 file 都只是独立的块设备,没有解析能力。 现象 创建 NBD 镜像时报错: cmd [qemu-img create -f qcow2 -b nbd://10.0.0.10:54195 -F qcow2 /dev/qbd/vol/vol-example.img] on [local] failed: ret[1] out[] err[qemu-img: /dev/qbd/vol/vol-example.img: Could not open backing file: Could not open '/data/image/centos79x64a': No such file or directory Could not open backing image.]. exec_time is [0.093]s 怪不得创建 NBD 镜像的时候,会把 backing 的所有镜像全部设置为 NBD。之前很费解。 有一个误区 以为通过 NBD 找到 nbd://10.0.0.10:54195 head 镜像,那么 NBD 镜像的 backing 镜像,自然通过 NBD head 链接一起使用了。 ...

July 18, 2026 · 2 min · 223 words · 文叨叨

为什么 Linux 只读 remount 失败,只能重启?

文件系统只读有两种:卷只读和 Linux 只读。卷只读是存储侧控制,能恢复;Linux 只读是存储 IO 错误触发的保护机制,remount 基本失败,只能重启。 现象 虚拟机文件系统变成只读: root@host:~# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT vda 253:0 0 20G 0 disk └─vda1 253:1 0 20G 0 part / vdb 253:16 0 4G 0 disk [SWAP] vdc 253:32 0 100G 0 disk root@host:~# touch test touch: cannot touch 'test': Read-only file system 同事说另一个类型的虚拟机只读了能恢复,这个怎么恢复。 排查 先要分清是"卷只读"还是"Linux 只读",两者恢复方式完全不同。 再确认存储是否中断过,因为 Linux 只读通常由存储 IO 错误触发。 根因 同事那个能恢复,是因为不是 Linux 只读,而是卷只读。那个卷是我们公司自己的存储,能控制其读写权限。 但这里 Linux 只读,一般是存储读写有 IO error,触发了 Linux 保护机制,系统只读。 我问他是不是存储中断过,他说是的。 这种 Linux 只读没法恢复,remount 基本失败,只能重启虚拟机。 小结 Linux 文件系统只读,通常是存储 IO 错误触发的保护机制; 卷只读(存储侧控制)可以恢复,Linux 只读(IO 错误触发)基本无法 remount 恢复; 排查时先确认是"卷只读"还是"Linux 只读",两者恢复方式完全不同; Linux 只读只能重启虚拟机恢复。

July 11, 2026 · 1 min · 93 words · 文叨叨

nbd-server 连接被误清理:tcp6 双栈的坑

虚拟机通过 nbd 秒级启动,但 nbd-server 连接总被误清理。根因是新版本 nbd-server 默认用 tcp6 双栈监听,而清理代码用 netstat -4 只过滤 tcp4,把 tcp6 上的连接误判为"无连接"而误清理。 现象 虚拟机通过 nbd 可以实现秒级启动,之前跑的好好的。 最近一个测试环境,总是会出现 nbd 连接丢失的情况。 排查是 base img 的 nbd-server 进程被 kill。 且通过日志看,就是我们的程序给 kill 的。 但是我们的程序是正常的清理,会判断这个 nbd-server 没有连接,才会去 kill。 到底是哪里的问题?是真没有连接了,还是哪里判断有问题。 排查 代码会先检查已经有连接的,这些是肯定不会去 kill: exec_cmd("netstat -4 --tcp -p -n | grep ESTABLISHED | grep nbd-server | awk '{print $4}' | awk -F':' '{print $2}' | sort -u > %s" % tmp_file) 代码已经十年了,看着也很完善,没出过类似问题。 后发现是 tcp6 和 tcp4 的原因,和 nbd-server 的版本有关系: ...

July 5, 2026 · 2 min · 247 words · 文叨叨

ZFS 副本为什么比主本占用大:raidZ 条带与块大小不适配

ZFS 副本通过 zfs send 从主本复制过来,逻辑数据一样,但物理占用却大很多。根因是副本节点的 raidZ 布局(高可用 + 条带)与 16k 块大小不适配,造成空间膨胀。 现象 ZFS 副本比主本大很多。主本数据: root@node1:~# zfs get all vpool/vol-example NAME PROPERTY VALUE SOURCE vpool/vol-example type filesystem - vpool/vol-example creation Thu Apr 24 13:59 2025 - vpool/vol-example used 3.94T - vpool/vol-example available 6.02T - vpool/vol-example referenced 3.94T 上面是主本数据,下面是副本数据。 副本是通过 zfs send 过来的,按道理两者应该是一样的。 但是副本的 used 是 4.75T,主本是 3.94T: root@node2:~# zfs get all vpool/vol-example NAME PROPERTY VALUE SOURCE vpool/vol-example type filesystem - vpool/vol-example creation Sun Aug 23 10:48 2026 - vpool/vol-example used 4.75T - vpool/vol-example available 627G - vpool/vol-example referenced 4.75T 排查 后排查了解发现,实际逻辑数据也是一样的,都是 3.92T: ...

June 21, 2026 · 1 min · 126 words · 文叨叨

qemu-img commit 的链为什么必须完整?-d 参数又是什么

qemu-img commit 的链必须是完整的,虽然 commit 的是 head,看起来和底层几级镜像没关系,但实际还是需要。commit 链的关系还可以是临时的,-d 参数决定 commit 后是否清空文件。 现象 qemu-img commit 的链,必须是完整的。 虽然你 commit 的是 head,看起来和底层几级的镜像没有关系,但实际还是需要的: root@host:~/tmp# qemu-img commit -f qcow2 /root/tmp/vm-example_tmp.img qemu-img: Could not open '/root/tmp/vm-example_tmp.img': Could not open backing file: Could not open backing file: Could not open '/root/tmp/focal1x64a': No such file or directory 排查 commit 链的关系还可以是临时的 下面命令不会改变 /dev/vg2/vm-example_lss-sjjgi703 的 backing file,但是确可以提交数据到其他链上,非常方便: qemu-img commit --image-opts file.filename=/dev/vg2/vm-example_lss-sjjgi703,backing.file.filename=/root/tmp/vm-example.img 底层链有 nbd 镜像也会失败 如果底层的链中有 nbd 镜像,那么即便 commit 没到 nbd img,也会失败: 2024-12-09 18:08:26,809 INFO -139636383823616- commit_snap command is [qemu-img commit -f qcow2 -d /data/container/vm-example/vm-example.resize_tmp.img] ret is [(1, '', u"qemu-img: Block format 'nbd' used by node '#block817' does not support reopening files")] 如果底层的链中有 nbd 镜像,那么即便 commit 没到 nbd img,也会失败。 ...

January 18, 2026 · 2 min · 224 words · 文叨叨

multipath 的 wwids 被手动改,导致盘一直加不上

sdf 设备总是加不到 multipath 下,配置没问题,重启 multipathd 也不行。根因是 /etc/multipath/wwids 被人手动加了个 # 注释,导致对应的盘一直加载不上。 现象 sdf 的设备总是加不到 multipath 下。 /etc/multipath.conf 的配置没有问题,重启 multipathd 依然不行,报错也不明显。 排查 后来发现是 /etc/multipath/wwids 下有人手动改了: # Multipath wwids, Version : 1.0 # NOTE: This file is automatically maintained by multipath and multipathd. # You should not need to edit this file in normal circumstances. # # Valid WWIDs: /wwid-example-0001/ /wwid-example-0002/ /wwid-example-0003/ #wwid-example-0004/ # 这里多一个 # 导致对应的 sdf 一直记载不上 /wwid-example-0005/ /wwid-example-0006/ 问题就出在那一行多了一个 #,导致对应的 sdf 一直加载不上。 ...

January 17, 2026 · 1 min · 103 words · 文叨叨

pvscan 没返回信息别慌:Global lock failed 的排查

pvscan 报 Global lock failed 且没有返回信息,不一定是数据没了。停掉 sanlock 和 lvmlockd 再 pvscan,只要 pv 在,一切都好说。 现象 在 ubuntu18 arm 上,pvscan 没有返回信息: root@host:/etc/lvm/archive# pvscan Global lock failed: error -210 No matching physical volumes found 这个时候不要慌,不一定是数据没了。 排查 把 sanlock 和 lvmlockd 停掉,再 pvscan 看看是否有,一般来说是在的: root@host:/etc/lvm/archive# pvscan WARNING: lvmlockd process is not running. Reading without shared global lock. Reading VG vg_b without a lock. PV /dev/mapper/mpath-b VG vg_b lvm2 [<500.00 GiB / <499.00 GiB free] Reading VG vg_a without a lock. PV /dev/mapper/mpath-a VG vg_a lvm2 [<1000.00 GiB / <545.00 GiB free] Total: 2 [1.46 TiB] / in use: 2 [1.46 TiB] / in no VG: 0 [0 ] 只要 pv 在,那么一切都好说。 ...

January 11, 2026 · 2 min · 247 words · 文叨叨

sanlock 的 wdmd 为什么在多 vg 场景下要禁用?

sanlock 的 wdmd 看门狗在多 vg 场景下不适合启用:只要一个锁空间续约失败,wdmd 就不喂狗,导致宿主机被强制重启。上层的事应该上层做,双写并发控制应该用业务全局锁,而不是依赖底层存储机制。 现象 sanlock 这里,还是应该把 wdmd 给禁用了。尤其是在多 vg 场景下,不太适合。 根因 wdmd 是什么 wdmd 是 Watchdog Multiplexing Daemon(看门狗多路复用守护进程)。 为什么多 vg 场景下不适合 一个锁空间,sanlock 会和 wdmd 建立一个连接。一个 vg 一个锁空间。 只要有一个锁空间续约失败,wdmd 就不会喂狗。 所以,如果一个 vg 断联了,其他 vg 正常,客户其实不希望关闭宿主机。 哪些情况会触发 reset 存储 IO 压力大,也会导致 sanlock 续约失败,但是上面的虚拟机是正常的; 如果 wdmd 自身异常了,也会触发 watchdog reset; 如果 sanlock 服务异常了,也会触发 watchdog reset; 有些慢存储,sanlock 容易锁过期、失效,也会触发 reset。 这些都不是用户想看到的。 设计思考 sanlock 是个底层存储锁,但是上层应用有自己的场景和控制逻辑。 底层做,只能一刀切: 要么很严格,动不动就关宿主机了; 要么很宽松,那可能还是会造成双写数据不安全。 上层的事上层做。 双写,终究是因为有两个虚拟机。 所以,要在创建虚拟机那里使用业务的全局锁,来做并发控制,而不是依赖底层存储机制。 小结 wdmd 看门狗在多 vg 场景下不适合启用; 只要一个锁空间续约失败,wdmd 就不喂狗,导致宿主机被强制重启; 存储 IO 压力大、wdmd 异常、sanlock 异常、慢存储锁过期,都可能触发 reset; 底层锁只能一刀切,双写并发控制应该用业务全局锁,上层的事上层做。

January 10, 2026 · 1 min · 82 words · 文叨叨