fix: unmap targetextent before extent delete in free_image (#259)

When a VM has multiple disks on the same per-VM target, migrating one
disk while the VM is running leaves the target in use for the other
disks. TrueNAS refuses to delete an extent associated with an in-use
target even with force=true.

Fix: delete the targetextent (LUN mapping) first, then delete the
extent. Removing the mapping severs this disk's association without
touching the active session or other LUNs on the same target.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Kevin Adams 2026-05-24 16:37:33 -04:00
parent 5e2e5a8cbe
commit 415c2a250b
1 changed files with 12 additions and 3 deletions

View File

@ -430,9 +430,18 @@ sub free_image {
my $ext = _find_extent($scfg, $volname);
if ($ext) {
# force=true tells TrueNAS to disconnect any remaining iSCSI session
# before deleting. For detached disks on a running VM, QEMU has
# already closed the libiscsi connection, so this is a no-op safety net.
# Step 1: unmap the LUN from the target. This must happen before the
# extent delete when the per-VM target still has other LUNs with active
# sessions (e.g. migrating one disk while the VM is running with others).
# Removing the targetextent severs just this LUN's association without
# touching the target session or other LUNs.
if (defined $ext->{targetextent_id}) {
eval { _api($scfg, 'DELETE', "/iscsi/targetextent/id/$ext->{targetextent_id}") };
_log('warning', "free_image: could not remove targetextent $ext->{targetextent_id}: $@") if $@;
}
# Step 2: delete the extent. force=true handles any residual session
# on a single-disk per-VM target (e.g. deleting a detached disk).
eval {
_api($scfg, 'DELETE', "/iscsi/extent/id/$ext->{extent_id}",
{ force => JSON::true });