]>
git.proxmox.com Git - pve-storage.git/blob - PVE/Storage/NFSPlugin.pm
14aa4ed2bc4ad35b480ca66895ac86aae44b87c1
1 package PVE
::Storage
::NFSPlugin
;
8 use PVE
::Tools
qw(run_command);
9 use PVE
::Storage
::Plugin
;
10 use PVE
::JSONSchema
qw(get_standard_option);
12 use base
qw(PVE::Storage::Plugin);
14 # NFS helper functions
16 sub read_proc_mounts
{
18 local $/; # enable slurp mode
21 if (my $fd = IO
::File-
>new("/proc/mounts", "r")) {
30 my ($server, $export, $mountpoint, $mountdata) = @_;
32 $server = "[$server]" if Net
::IP
::ip_is_ipv6
($server);
33 my $source = "$server:$export";
35 $mountdata = read_proc_mounts
() if !$mountdata;
37 if ($mountdata =~ m
|^\Q
$source\E/?\s\Q$mountpoint\E\snfs|m
) {
45 my ($server, $export, $mountpoint, $options) = @_;
47 $server = "[$server]" if Net
::IP
::ip_is_ipv6
($server);
48 my $source = "$server:$export";
50 my $cmd = ['/bin/mount', '-t', 'nfs', $source, $mountpoint];
52 push @$cmd, '-o', $options;
55 run_command
($cmd, errmsg
=> "mount error");
66 content
=> [ { images
=> 1, rootdir
=> 1, vztmpl
=> 1, iso
=> 1, backup
=> 1},
68 format
=> [ { raw
=> 1, qcow2
=> 1, vmdk
=> 1 } , 'raw' ],
75 description
=> "NFS export path.",
76 type
=> 'string', format
=> 'pve-storage-path',
79 description
=> "Server IP or DNS name.",
80 type
=> 'string', format
=> 'pve-storage-server',
83 description
=> "NFS mount options (see 'man nfs')",
84 type
=> 'string', format
=> 'pve-storage-options',
91 path
=> { fixed
=> 1 },
92 server
=> { fixed
=> 1 },
93 export
=> { fixed
=> 1 },
94 nodes
=> { optional
=> 1 },
95 disable
=> { optional
=> 1 },
96 maxfiles
=> { optional
=> 1 },
97 options
=> { optional
=> 1 },
98 content
=> { optional
=> 1 },
99 format
=> { optional
=> 1 },
105 my ($class, $sectionId, $config, $create, $skipSchemaCheck) = @_;
107 $config->{path
} = "/mnt/pve/$sectionId" if $create && !$config->{path
};
109 return $class->SUPER::check_config
($sectionId, $config, $create, $skipSchemaCheck);
112 # Storage implementation
115 my ($class, $storeid, $scfg, $cache) = @_;
117 $cache->{mountdata
} = read_proc_mounts
() if !$cache->{mountdata
};
119 my $path = $scfg->{path
};
120 my $server = $scfg->{server
};
121 my $export = $scfg->{export
};
123 return undef if !nfs_is_mounted
($server, $export, $path, $cache->{mountdata
});
125 return $class->SUPER::status
($storeid, $scfg, $cache);
128 sub activate_storage
{
129 my ($class, $storeid, $scfg, $cache) = @_;
131 $cache->{mountdata
} = read_proc_mounts
() if !$cache->{mountdata
};
133 my $path = $scfg->{path
};
134 my $server = $scfg->{server
};
135 my $export = $scfg->{export
};
137 if (!nfs_is_mounted
($server, $export, $path, $cache->{mountdata
})) {
139 # NOTE: only call mkpath when not mounted (avoid hang
140 # when NFS server is offline
144 die "unable to activate storage '$storeid' - " .
145 "directory '$path' does not exist\n" if ! -d
$path;
147 nfs_mount
($server, $export, $path, $scfg->{options
});
150 $class->SUPER::activate_storage
($storeid, $scfg, $cache);
153 sub deactivate_storage
{
154 my ($class, $storeid, $scfg, $cache) = @_;
156 $cache->{mountdata
} = read_proc_mounts
() if !$cache->{mountdata
};
158 my $path = $scfg->{path
};
159 my $server = $scfg->{server
};
160 my $export = $scfg->{export
};
162 if (nfs_is_mounted
($server, $export, $path, $cache->{mountdata
})) {
163 my $cmd = ['/bin/umount', $path];
164 run_command
($cmd, errmsg
=> 'umount error');
168 sub check_connection
{
169 my ($class, $storeid, $scfg) = @_;
171 my $server = $scfg->{server
};
173 # test connection to portmapper
174 my $cmd = ['/usr/sbin/rpcinfo', '-p', $server];
177 run_command
($cmd, timeout
=> 2, outfunc
=> sub {}, errfunc
=> sub {});