From f0150c225e93c123a97837e308a85296cac8e7cc Mon Sep 17 00:00:00 2001 From: Kevin Adams Date: Mon, 8 Jun 2026 12:48:39 -0400 Subject: [PATCH] fix: delegate qemu_blockdev_options to Plugin.pm for host_device path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TrueNAS.pm::qemu_blockdev_options returns an iscsi:// blockdev — wrong for multipath where path() returns /dev/mapper/. Simply removing the override caused the parent's iscsi driver to be inherited instead. Fix: explicitly call PVE::Storage::Plugin::qemu_blockdev_options (the grandparent). It calls path(), sees /dev/mapper/ starts with '/', stats it as S_ISBLK, and returns { driver => 'host_device', filename => ... }. QEMU receives: "driver":"host_device","filename":"/dev/mapper/" Tested: VM 103 started with multipath disk (vm-103-disk-0 on TrueNAS-Scale01-MP). QEMU confirmed using host_device driver on /dev/mapper/36589cfc000000ad... Co-Authored-By: Claude Sonnet 4.6 --- perl5/PVE/Storage/Custom/TrueNASMultipath.pm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/perl5/PVE/Storage/Custom/TrueNASMultipath.pm b/perl5/PVE/Storage/Custom/TrueNASMultipath.pm index 6259593..d7da0b9 100644 --- a/perl5/PVE/Storage/Custom/TrueNASMultipath.pm +++ b/perl5/PVE/Storage/Custom/TrueNASMultipath.pm @@ -104,11 +104,19 @@ sub path { return ("/dev/mapper/$wwid", $ext->{lun_id}, $storeid); } -# ── qemu_blockdev_options — not used (path returns a block device) ──────────── +# ── qemu_blockdev_options — delegate to Plugin.pm (host_device for /dev/mapper) ─ -# The base class qemu_blockdev_options builds an iscsi:// blockdev. -# For multipath we return undef so PVE uses path() instead. -sub qemu_blockdev_options { return; } +# TrueNAS.pm overrides qemu_blockdev_options to return an iscsi:// blockdev — +# that's wrong for multipath where path() returns /dev/mapper/. +# We skip the parent and call the grandparent (PVE::Storage::Plugin) directly. +# Plugin.pm calls path(), sees /dev/mapper/ starts with '/', stats it as a +# block device (S_ISBLK), and returns { driver => 'host_device', filename => ... }. +# QEMU then accesses the dm-multipath block device directly. +sub qemu_blockdev_options { + my ($class, $scfg, $storeid, $volname, $machine_version, $options) = @_; + return PVE::Storage::Plugin::qemu_blockdev_options( + $class, $scfg, $storeid, $volname, $machine_version, $options // {}); +} # ── activate_volume — login via all portals, wait for mapper device ───────────