# CIFS helper functions
-sub cifs_is_mounted {
- my ($server, $share, $mountpoint, $mountdata) = @_;
+sub cifs_is_mounted : prototype($$) {
+ my ($scfg, $mountdata) = @_;
+
+ my ($mountpoint, $server, $share) = $scfg->@{'path', 'server', 'share'};
+ my $subdir = $scfg->{subdir} // "/";
$server = "[$server]" if Net::IP::ip_is_ipv6($server);
- my $source = "//${server}/$share";
+ my $source = "//${server}/$share$subdir";
$mountdata = PVE::ProcFSTools::parse_proc_mounts() if !$mountdata;
return $mountpoint if grep {
return undef;
}
-sub cifs_mount {
- my ($server, $share, $mountpoint, $storeid, $smbver, $user, $domain) = @_;
+sub cifs_mount : prototype($$$$$) {
+ my ($scfg, $storeid, $smbver, $user, $domain) = @_;
+
+ my ($mountpoint, $server, $share) = $scfg->@{'path', 'server', 'share'};
+ my $subdir = $scfg->{subdir} // "/";
$server = "[$server]" if Net::IP::ip_is_ipv6($server);
- my $source = "//${server}/$share";
+ my $source = "//${server}/$share$subdir";
my $cmd = ['/bin/mount', '-t', 'cifs', $source, $mountpoint, '-o', 'soft', '-o'];
push @$cmd, 'guest,username=guest';
}
- push @$cmd, '-o', defined($smbver) ? "vers=$smbver" : "vers=3.0";
+ push @$cmd, '-o', defined($smbver) ? "vers=$smbver" : "vers=default";
run_command($cmd, errmsg => "mount error");
}
maxLength => 256,
},
smbversion => {
- description => "SMB protocol version",
+ description => "SMB protocol version. 'default' if not set, negotiates the highest SMB2+"
+ ." version supported by both the client and server.",
type => 'string',
+ default => 'default',
enum => ['default', '2.0', '2.1', '3', '3.0', '3.11'],
optional => 1,
},
sub options {
return {
path => { fixed => 1 },
+ 'content-dirs' => { optional => 1 },
server => { fixed => 1 },
share => { fixed => 1 },
+ subdir => { optional => 1 },
nodes => { optional => 1 },
disable => { optional => 1 },
maxfiles => { optional => 1 },
'prune-backups' => { optional => 1 },
+ 'max-protected-backups' => { optional => 1 },
content => { optional => 1 },
format => { optional => 1 },
username => { optional => 1 },
smbversion => { optional => 1},
mkdir => { optional => 1 },
bwlimit => { optional => 1 },
+ preallocation => { optional => 1 },
};
}
$cache->{mountdata} = PVE::ProcFSTools::parse_proc_mounts()
if !$cache->{mountdata};
- my $path = $scfg->{path};
- my $server = $scfg->{server};
- my $share = $scfg->{share};
-
return undef
- if !cifs_is_mounted($server, $share, $path, $cache->{mountdata});
+ if !cifs_is_mounted($scfg, $cache->{mountdata});
return $class->SUPER::status($storeid, $scfg, $cache);
}
if !$cache->{mountdata};
my $path = $scfg->{path};
- my $server = $scfg->{server};
- my $share = $scfg->{share};
- if (!cifs_is_mounted($server, $share, $path, $cache->{mountdata})) {
+ if (!cifs_is_mounted($scfg, $cache->{mountdata})) {
mkpath $path if !(defined($scfg->{mkdir}) && !$scfg->{mkdir});
die "unable to activate storage '$storeid' - " .
"directory '$path' does not exist\n" if ! -d $path;
- cifs_mount($server, $share, $path, $storeid, $scfg->{smbversion},
+ cifs_mount($scfg, $storeid, $scfg->{smbversion},
$scfg->{username}, $scfg->{domain});
}
if !$cache->{mountdata};
my $path = $scfg->{path};
- my $server = $scfg->{server};
- my $share = $scfg->{share};
- if (cifs_is_mounted($server, $share, $path, $cache->{mountdata})) {
+ if (cifs_is_mounted($scfg, $cache->{mountdata})) {
my $cmd = ['/bin/umount', $path];
run_command($cmd, errmsg => 'umount error');
}
my $servicename = '//'.$scfg->{server}.'/'.$scfg->{share};
- my $cmd = ['/usr/bin/smbclient', $servicename, '-d', '0', '-m'];
+ my $cmd = ['/usr/bin/smbclient', $servicename, '-d', '0'];
- push @$cmd, $scfg->{smbversion} ? "smb".int($scfg->{smbversion}) : 'smb3';
+ if (defined($scfg->{smbversion}) && $scfg->{smbversion} ne 'default') {
+ # max-protocol version, so basically only relevant for smb2 vs smb3
+ push @$cmd, '-m', "smb" . int($scfg->{smbversion});
+ }
if (my $cred_file = get_cred_file($storeid)) {
push @$cmd, '-U', $scfg->{username}, '-A', $cred_file;
if (my $err = $@) {
die "$out_str\n" if defined($out_str) &&
- ($out_str =~ m/NT_STATUS_ACCESS_DENIED/);
+ ($out_str =~ m/NT_STATUS_(ACCESS_DENIED|LOGON_FAILURE)/);
return 0;
}
return 1;
}
+# FIXME remove on the next APIAGE reset.
+# Deprecated, use get_volume_attribute instead.
sub get_volume_notes {
my $class = shift;
PVE::Storage::DirPlugin::get_volume_notes($class, @_);
}
+
+# FIXME remove on the next APIAGE reset.
+# Deprecated, use update_volume_attribute instead.
sub update_volume_notes {
my $class = shift;
PVE::Storage::DirPlugin::update_volume_notes($class, @_);
}
+sub get_volume_attribute {
+ return PVE::Storage::DirPlugin::get_volume_attribute(@_);
+}
+
+sub update_volume_attribute {
+ return PVE::Storage::DirPlugin::update_volume_attribute(@_);
+}
+
1;