170 lines
7.2 KiB
Diff
170 lines
7.2 KiB
Diff
--- /tmp/ZFSPlugin-8.4.orig 2026-05-22 08:54:24.992472212 -0400
|
|
+++ /tmp/ZFSPlugin-8.4-final.pm 2026-05-22 08:51:00.460468461 -0400
|
|
@@ -11,6 +11,7 @@
|
|
|
|
use base qw(PVE::Storage::ZFSPoolPlugin);
|
|
use PVE::Storage::LunCmd::Comstar;
|
|
+use PVE::Storage::LunCmd::FreeNAS;
|
|
use PVE::Storage::LunCmd::Istgt;
|
|
use PVE::Storage::LunCmd::Iet;
|
|
use PVE::Storage::LunCmd::LIO;
|
|
@@ -26,13 +27,14 @@
|
|
modify_lu => 1,
|
|
add_view => 1,
|
|
list_view => 1,
|
|
+ list_extent => 1,
|
|
list_lu => 1,
|
|
};
|
|
|
|
my $zfs_unknown_scsi_provider = sub {
|
|
my ($provider) = @_;
|
|
|
|
- die "$provider: unknown iscsi provider. Available [comstar, istgt, iet, LIO]";
|
|
+ die "$provider: unknown iscsi provider. Available [comstar, freenas, istgt, iet, LIO]";
|
|
};
|
|
|
|
my $zfs_get_base = sub {
|
|
@@ -44,6 +46,8 @@
|
|
return PVE::Storage::LunCmd::Istgt::get_base($scfg);
|
|
} elsif ($scfg->{iscsiprovider} eq 'iet') {
|
|
return PVE::Storage::LunCmd::Iet::get_base($scfg);
|
|
+ } elsif ($scfg->{iscsiprovider} eq 'freenas') {
|
|
+ return PVE::Storage::LunCmd::FreeNAS::get_base($scfg);
|
|
} elsif ($scfg->{iscsiprovider} eq 'LIO') {
|
|
return PVE::Storage::LunCmd::LIO::get_base($scfg);
|
|
} else {
|
|
@@ -67,6 +71,8 @@
|
|
$msg = PVE::Storage::LunCmd::Istgt::run_lun_command($scfg, $timeout, $method, @params);
|
|
} elsif ($scfg->{iscsiprovider} eq 'iet') {
|
|
$msg = PVE::Storage::LunCmd::Iet::run_lun_command($scfg, $timeout, $method, @params);
|
|
+ } elsif ($scfg->{iscsiprovider} eq 'freenas') {
|
|
+ $msg = PVE::Storage::LunCmd::FreeNAS::run_lun_command($scfg, $timeout, $method, @params);
|
|
} elsif ($scfg->{iscsiprovider} eq 'LIO') {
|
|
$msg = PVE::Storage::LunCmd::LIO::run_lun_command($scfg, $timeout, $method, @params);
|
|
} else {
|
|
@@ -158,7 +164,7 @@
|
|
sub zfs_get_lun_number {
|
|
my ($class, $scfg, $guid) = @_;
|
|
|
|
- die "could not find lun_number for guid $guid" if !$guid;
|
|
+ die "could not find lun_number for guid $guid" if !defined $guid;
|
|
|
|
if ($class->zfs_request($scfg, undef, 'list_view', $guid) =~ /^(\d+)$/) {
|
|
return $1;
|
|
@@ -167,6 +173,14 @@
|
|
die "lun_number for guid $guid is not a number";
|
|
}
|
|
|
|
+sub zfs_get_wwid_number {
|
|
+ my ($class, $scfg, $guid) = @_;
|
|
+
|
|
+ die "could not find lun_number for guid $guid" if !defined $guid;
|
|
+
|
|
+ return $class->zfs_request($scfg, undef, 'list_extent', $guid);
|
|
+}
|
|
+
|
|
# Configuration
|
|
|
|
sub type {
|
|
@@ -186,6 +200,32 @@
|
|
description => "iscsi provider",
|
|
type => 'string',
|
|
},
|
|
+ # This is for FreeNAS iscsi and API intergration
|
|
+ # And some enhancements asked by the community
|
|
+ freenas_user => {
|
|
+ description => "FreeNAS API Username",
|
|
+ type => 'string',
|
|
+ },
|
|
+ freenas_password => {
|
|
+ description => "FreeNAS API Password (Deprecated)",
|
|
+ type => 'string',
|
|
+ },
|
|
+ truenas_secret => {
|
|
+ description => "TrueNAS API Secret",
|
|
+ type => 'string',
|
|
+ },
|
|
+ truenas_token_auth => {
|
|
+ description => "TrueNAS API Authentication with Token",
|
|
+ type => 'boolean',
|
|
+ },
|
|
+ freenas_use_ssl => {
|
|
+ description => "FreeNAS API access via SSL",
|
|
+ type => 'boolean',
|
|
+ },
|
|
+ freenas_apiv4_host => {
|
|
+ description => "FreeNAS API Host",
|
|
+ type => 'string',
|
|
+ },
|
|
# this will disable write caching on comstar and istgt.
|
|
# it is not implemented for iet. iet blockio always operates with
|
|
# writethrough caching when not in readonly mode
|
|
@@ -224,6 +264,12 @@
|
|
blocksize => { fixed => 1 },
|
|
iscsiprovider => { fixed => 1 },
|
|
nowritecache => { optional => 1 },
|
|
+ freenas_user => { optional => 1 },
|
|
+ freenas_password => { optional => 1 },
|
|
+ truenas_secret => { optional => 1 },
|
|
+ truenas_token_auth => { optional => 1 },
|
|
+ freenas_use_ssl => { optional => 1 },
|
|
+ freenas_apiv4_host => { optional => 1 },
|
|
sparse => { optional => 1 },
|
|
comstar_hg => { optional => 1 },
|
|
comstar_tg => { optional => 1 },
|
|
@@ -243,6 +289,21 @@
|
|
my $base_path;
|
|
if ($scfg->{iscsiprovider} eq 'comstar') {
|
|
$base_path = PVE::Storage::LunCmd::Comstar::get_base($scfg);
|
|
+ } elsif ($scfg->{iscsiprovider} eq 'freenas') {
|
|
+ $base_path = PVE::Storage::LunCmd::FreeNAS::get_base($scfg);
|
|
+ # Auto-detect and persist correct blocksize at storage creation time.
|
|
+ # $scfg is the live config ref -- write_config() saves it after this hook returns.
|
|
+ eval {
|
|
+ my $recommended = PVE::Storage::LunCmd::FreeNAS::freenas_get_recommended_blocksize($scfg);
|
|
+ if (defined $recommended) {
|
|
+ my $configured = PVE::Storage::LunCmd::FreeNAS::freenas_parse_blocksize($scfg->{blocksize});
|
|
+ if (!$configured || $configured < $recommended) {
|
|
+ warn "freenas-proxmox: auto-correcting blocksize from " . ($configured ? $configured : 'unset') . " to $recommended for '$storeid'\n";
|
|
+ $scfg->{blocksize} = $recommended;
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ warn "freenas-proxmox: blocksize detection in on_add_hook failed: $@\n" if $@;
|
|
} elsif ($scfg->{iscsiprovider} eq 'istgt') {
|
|
$base_path = PVE::Storage::LunCmd::Istgt::get_base($scfg);
|
|
} elsif ($scfg->{iscsiprovider} eq 'iet' || $scfg->{iscsiprovider} eq 'LIO') {
|
|
@@ -349,6 +410,32 @@
|
|
|
|
$volname = $class->find_free_diskname($storeid, $scfg, $vmid, $fmt) if !$volname;
|
|
|
|
+ # Auto-detect ZFS blocksize from TrueNAS API and override if wrong.
|
|
+ # SCALE requires >= 16k; CORE works with 8k. If the configured blocksize is
|
|
+ # less than recommended (or unset), correct it now and persist to storage.cfg.
|
|
+ if ($scfg->{iscsiprovider} eq 'freenas') {
|
|
+ eval {
|
|
+ my $recommended = PVE::Storage::LunCmd::FreeNAS::freenas_get_recommended_blocksize($scfg);
|
|
+ if (defined $recommended) {
|
|
+ my $configured = PVE::Storage::LunCmd::FreeNAS::freenas_parse_blocksize($scfg->{blocksize});
|
|
+ if (!$configured || $configured < $recommended) {
|
|
+ warn "freenas-proxmox: blocksize " . ($configured ? $configured : 'unset') . " < recommended $recommended -- correcting storage '$storeid'\n";
|
|
+ $scfg->{blocksize} = $recommended;
|
|
+ eval {
|
|
+ require PVE::Storage;
|
|
+ PVE::Storage::lock_storage_config(sub {
|
|
+ my $cfg = PVE::Storage::config();
|
|
+ $cfg->{ids}{$storeid}{blocksize} = $recommended if $cfg->{ids}{$storeid};
|
|
+ PVE::Storage::write_config($cfg);
|
|
+ });
|
|
+ };
|
|
+ warn "freenas-proxmox: could not persist blocksize to storage config: $@\n" if $@;
|
|
+ }
|
|
+ }
|
|
+ };
|
|
+ warn "TrueNAS blocksize detection failed: $@" if $@;
|
|
+ }
|
|
+
|
|
$class->zfs_create_zvol($scfg, $volname, $size);
|
|
|
|
my $guid = $class->zfs_create_lu($scfg, $volname);
|