Fix dangling extent on failed LUN creation (issue #214)

Two problems in run_create_lu:
1. If freenas_iscsi_create_extent returned undef, the next line accessed
   $extent->{'id'} unconditionally, causing a crash rather than a clean error.
2. If freenas_iscsi_create_target_to_extent failed after a successful extent
   creation, the code just died with "Unable to create lun", leaving the
   newly created extent orphaned on TrueNAS with no target association.
   Subsequent delete_lu calls could not find or clean up this extent because
   it was never in the LUN list, requiring manual TrueNAS cleanup.

Fix: check extent creation result before dereferencing; on target-to-extent
failure, call freenas_iscsi_remove_extent to roll back the extent before
dying. The rollback is best-effort (failure is logged but not re-thrown)
so a secondary API error does not mask the primary failure message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Kevin Adams 2026-05-15 14:43:46 -04:00
parent 43a8efd125
commit af737128d2
1 changed files with 8 additions and 6 deletions

View File

@ -263,16 +263,18 @@ sub run_create_lu {
# Create the extent # Create the extent
my $extent = freenas_iscsi_create_extent($scfg, $lun_path); my $extent = freenas_iscsi_create_extent($scfg, $lun_path);
die "Unable to create extent for $lun_path" if !defined($extent);
# Associate the new extent to the target # Associate the new extent to the target; roll back the extent if this fails
# to avoid leaving a dangling extent on TrueNAS (issue #214)
my $link = freenas_iscsi_create_target_to_extent($scfg, $target_id, $extent->{'id'}, $lun_id); my $link = freenas_iscsi_create_target_to_extent($scfg, $target_id, $extent->{'id'}, $lun_id);
if (!defined($link)) {
if (defined($link)) { syslog("err", (caller(0))[3] . " : target-to-extent failed for $lun_path -- rolling back extent $extent->{'id'}");
syslog("info","FreeNAS::create_lu(lun_path=$lun_path, lun_id=$lun_id) : successful"); freenas_iscsi_remove_extent($scfg, $extent->{'id'});
} else { die "Unable to create lun $lun_path (extent rolled back)";
die "Unable to create lun $lun_path";
} }
syslog("info", (caller(0))[3] . "(lun_path=$lun_path, lun_id=$lun_id) : successful");
return ""; return "";
} }