]>
Commit | Line | Data |
---|---|---|
d14a9a1b DM |
1 | package PVE::VZDump::LXC; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
8ebb49ee | 5 | |
d14a9a1b | 6 | use File::Basename; |
8ebb49ee | 7 | use File::Path; |
2862bbe5 | 8 | use POSIX qw(strftime); |
8ebb49ee | 9 | |
d14a9a1b | 10 | use PVE::Cluster qw(cfs_read_file); |
8ebb49ee | 11 | use PVE::INotify; |
86ee2a21 | 12 | use PVE::LXC::Config; |
8ebb49ee TL |
13 | use PVE::LXC; |
14 | use PVE::Storage; | |
514b5f82 | 15 | use PVE::Tools; |
8ebb49ee | 16 | use PVE::VZDump; |
d14a9a1b DM |
17 | |
18 | use base qw (PVE::VZDump::Plugin); | |
19 | ||
4ca61ce8 DM |
20 | my $default_mount_point = "/mnt/vzsnap0"; |
21 | ||
d14a9a1b | 22 | my $rsync_vm = sub { |
50ee6ffe | 23 | my ($self, $task, $to, $text, $first) = @_; |
d14a9a1b | 24 | |
59a999af | 25 | my $disks = $task->{disks}; |
5582b0c3 | 26 | my $from = $disks->[0]->{dir}; |
d14a9a1b DM |
27 | $self->loginfo ("starting $text sync $from to $to"); |
28 | ||
d14a9a1b DM |
29 | my $opts = $self->{vzdump}->{opts}; |
30 | ||
9c9a3b8c WB |
31 | my @xattr = $task->{no_xattrs} ? () : ('-X', '-A'); |
32 | ||
5582b0c3 | 33 | my $rsync = ['rsync', '--stats', '-h', @xattr, '--numeric-ids', |
50ee6ffe WB |
34 | '-aH', '--delete', '--no-whole-file', |
35 | ($first ? '--sparse' : '--inplace'), | |
bd8e1739 WB |
36 | '--one-file-system', '--relative']; |
37 | push @$rsync, "--bwlimit=$opts->{bwlimit}" if $opts->{bwlimit}; | |
38 | push @$rsync, map { "--exclude=$_" } @{$self->{vzdump}->{findexcl}}; | |
39 | push @$rsync, map { "--exclude=$_" } @{$task->{exclude_dirs}}; | |
d14a9a1b | 40 | |
5a8a3087 WB |
41 | # See the rsync(1) manpage for --relative in conjunction with /./ in paths. |
42 | # This is the only way to have exclude-dirs work together with the | |
43 | # --one-file-system option. | |
44 | # This way we can pass multiple source paths and tell rsync which directory | |
45 | # they're supposed to be relative to. | |
46 | # Otherwise with eg. using multiple rsync commands means the --exclude | |
47 | # directives need to be modified for every command as they are meant to be | |
48 | # relative to the rootdir, while rsync treats them as relative to the | |
49 | # source dir. | |
50 | foreach my $disk (@$disks) { | |
bd8e1739 | 51 | push @$rsync, "$from/.$disk->{mp}"; |
5a8a3087 | 52 | } |
5582b0c3 TL |
53 | |
54 | my $transferred = ''; | |
55 | my $logfunc = sub { | |
56 | return if $_[0] !~ /^Total transferred file size: (.+)$/; | |
57 | $transferred = $1; | |
58 | }; | |
59 | ||
60 | my $starttime = time(); | |
61 | PVE::Tools::run_command([@$rsync, $to], logfunc => $logfunc); | |
d14a9a1b DM |
62 | my $delay = time () - $starttime; |
63 | ||
5582b0c3 | 64 | $self->loginfo ("$text sync finished - transferred $transferred in ${delay}s"); |
d14a9a1b DM |
65 | }; |
66 | ||
67 | sub new { | |
68 | my ($class, $vzdump) = @_; | |
7808afef | 69 | |
d14a9a1b DM |
70 | PVE::VZDump::check_bin('lxc-stop'); |
71 | PVE::VZDump::check_bin('lxc-start'); | |
d14a9a1b DM |
72 | |
73 | my $self = bless {}; | |
74 | ||
75 | $self->{vzdump} = $vzdump; | |
76 | $self->{storecfg} = PVE::Storage::config(); | |
7808afef | 77 | |
d14a9a1b DM |
78 | $self->{vmlist} = PVE::LXC::config_list(); |
79 | ||
80 | return $self; | |
81 | } | |
82 | ||
83 | sub type { | |
84 | return 'lxc'; | |
85 | } | |
86 | ||
87 | sub vm_status { | |
88 | my ($self, $vmid) = @_; | |
89 | ||
90 | my $running = PVE::LXC::check_running($vmid) ? 1 : 0; | |
7808afef AL |
91 | |
92 | return wantarray ? ($running, $running ? 'running' : 'stopped') : $running; | |
d14a9a1b DM |
93 | } |
94 | ||
4ca61ce8 | 95 | my $check_mountpoint_empty = sub { |
b739f640 DM |
96 | my ($mountpoint) = @_; |
97 | ||
235dbdf3 | 98 | die "mount point '$mountpoint' is not a directory\n" if ! -d $mountpoint; |
4ca61ce8 | 99 | |
b739f640 DM |
100 | PVE::Tools::dir_glob_foreach($mountpoint, qr/.*/, sub { |
101 | my $entry = shift; | |
102 | return if $entry eq '.' || $entry eq '..'; | |
235dbdf3 | 103 | die "mount point '$mountpoint' not empty\n"; |
b739f640 | 104 | }); |
d14a9a1b DM |
105 | }; |
106 | ||
107 | sub prepare { | |
108 | my ($self, $task, $vmid, $mode) = @_; | |
109 | ||
67afe46e | 110 | my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::Config->load_config($vmid); |
57ed5ed0 | 111 | my $storage_cfg = $self->{storecfg}; |
d14a9a1b | 112 | |
05812a36 WL |
113 | $self->loginfo("CT Name: $conf->{hostname}") |
114 | if defined($conf->{hostname}); | |
115 | ||
d14a9a1b DM |
116 | my $running = PVE::LXC::check_running($vmid); |
117 | ||
2e57a9f6 WB |
118 | my $disks = $task->{disks} = []; |
119 | my $exclude_dirs = $task->{exclude_dirs} = []; | |
d14a9a1b | 120 | |
27916659 | 121 | $task->{hostname} = $conf->{'hostname'} || "CT$vmid"; |
d14a9a1b | 122 | |
01dce99b WB |
123 | my ($id_map, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf); |
124 | $task->{userns_cmd} = PVE::LXC::userns_command($id_map); | |
4c98d66c FG |
125 | $task->{rootuid} = $rootuid; |
126 | $task->{rootgid} = $rootgid; | |
127 | ||
5040d81c | 128 | my $volids = $task->{volids} = []; |
d14a9a1b | 129 | |
efd1706d | 130 | my $backup_volumes = PVE::LXC::Config->get_backup_volumes($conf); |
2e57a9f6 | 131 | |
501a9f9f TL |
132 | for my $volume (@{$backup_volumes}) { |
133 | my $name = $volume->{key}; | |
134 | my $included = $volume->{included}; | |
135 | my $volume_config = $volume->{volume_config}; | |
efd1706d | 136 | |
501a9f9f | 137 | my $volid = $volume_config->{volume}; |
efd1706d | 138 | my $mount = $volume_config->{mp}; |
efd1706d | 139 | |
501a9f9f | 140 | next if !$volid || !$mount; |
efd1706d AL |
141 | |
142 | if (!$included) { | |
501a9f9f | 143 | my $type = $volume_config->{type}; |
2e57a9f6 | 144 | push @$exclude_dirs, $mount; |
db773fab | 145 | $self->loginfo("excluding $type mount point $name ('$mount') from backup ($volume->{reason})"); |
efd1706d | 146 | next; |
2e57a9f6 WB |
147 | } |
148 | ||
efd1706d | 149 | $volume_config->{name} = $name; |
362a853a FG |
150 | |
151 | # immutable raw base images need RO mount | |
efd1706d AL |
152 | if ($conf->{template} && !defined($volume_config->{ro})) { |
153 | $volume_config->{ro} = 1; | |
362a853a | 154 | } |
efd1706d AL |
155 | |
156 | $self->loginfo("including mount point $name ('$mount') in backup"); | |
157 | push @$disks, $volume_config; | |
501a9f9f | 158 | push @$volids, $volid if $included; |
efd1706d | 159 | } |
d14a9a1b | 160 | |
d14a9a1b | 161 | if ($mode eq 'snapshot') { |
4518000b | 162 | if (!PVE::LXC::Config->has_feature('snapshot', $conf, $storage_cfg, undef, undef, 1)) { |
c31ad455 | 163 | die "mode failure - some volumes do not support snapshots\n"; |
4ca61ce8 | 164 | } |
d14a9a1b | 165 | |
2d3f23be | 166 | |
4ca61ce8 DM |
167 | if ($conf->{snapshots} && $conf->{snapshots}->{vzdump}) { |
168 | $self->loginfo("found old vzdump snapshot (force removal)"); | |
91458f71 FG |
169 | PVE::LXC::Config->lock_config($vmid, sub { |
170 | $self->unlock_vm($vmid); | |
171 | PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 1); | |
172 | $self->lock_vm($vmid); | |
173 | }); | |
4ca61ce8 | 174 | } |
d14a9a1b | 175 | |
22a91261 WB |
176 | my $rootdir = $default_mount_point; |
177 | mkpath $rootdir; | |
178 | &$check_mountpoint_empty($rootdir); | |
d14a9a1b | 179 | |
c31ad455 | 180 | # set snapshot_count (freezes CT if snapshot_count > 1) |
5040d81c | 181 | $task->{snapshot_count} = scalar(@$volids); |
f5313774 | 182 | } elsif ($mode eq 'stop') { |
22a91261 WB |
183 | my $rootdir = $default_mount_point; |
184 | mkpath $rootdir; | |
185 | &$check_mountpoint_empty($rootdir); | |
f5313774 | 186 | } elsif ($mode eq 'suspend') { |
632eca5a | 187 | my $pid = PVE::LXC::find_lxc_pid($vmid); |
2e57a9f6 WB |
188 | foreach my $disk (@$disks) { |
189 | $disk->{dir} = "/proc/$pid/root$disk->{mp}"; | |
190 | } | |
f5313774 DM |
191 | $task->{snapdir} = $task->{tmpdir}; |
192 | } else { | |
2d3f23be | 193 | unlock_vm($self, $vmid); |
f5313774 | 194 | die "unknown mode '$mode'\n"; # should not happen |
d14a9a1b | 195 | } |
b6c491ee WB |
196 | |
197 | if ($mode ne 'suspend') { | |
c31ad455 | 198 | # If we perform mount operations, let's unshare the mount namespace |
b6c491ee WB |
199 | # to not influence the running host. |
200 | PVE::Tools::unshare(PVE::Tools::CLONE_NEWNS); | |
a78425d7 | 201 | PVE::Tools::run_command(['mount', '--make-rslave', '/']); |
b6c491ee | 202 | } |
d14a9a1b DM |
203 | } |
204 | ||
205 | sub lock_vm { | |
206 | my ($self, $vmid) = @_; | |
2d3f23be | 207 | |
ad408fe1 | 208 | PVE::LXC::Config->set_lock($vmid, 'backup'); |
d14a9a1b DM |
209 | } |
210 | ||
211 | sub unlock_vm { | |
212 | my ($self, $vmid) = @_; | |
2d3f23be | 213 | |
ad408fe1 | 214 | PVE::LXC::Config->remove_lock($vmid, 'backup') |
d14a9a1b DM |
215 | } |
216 | ||
4ca61ce8 DM |
217 | sub snapshot { |
218 | my ($self, $task, $vmid) = @_; | |
219 | ||
c31ad455 | 220 | $self->loginfo("create storage snapshot 'vzdump'"); |
4ca61ce8 DM |
221 | |
222 | # todo: freeze/unfreeze if we have more than one volid | |
91458f71 FG |
223 | PVE::LXC::Config->lock_config($vmid, sub { |
224 | $self->unlock_vm($vmid); | |
225 | PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot"); | |
226 | $self->lock_vm($vmid); | |
227 | }); | |
4ca61ce8 | 228 | $task->{cleanup}->{remove_snapshot} = 1; |
7808afef | 229 | |
4ca61ce8 | 230 | # reload config |
67afe46e | 231 | my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::Config->load_config($vmid); |
c31ad455 | 232 | die "unable to read vzdump snapshot config - internal error" |
4ca61ce8 DM |
233 | if !($conf->{snapshots} && $conf->{snapshots}->{vzdump}); |
234 | ||
2e57a9f6 | 235 | my $disks = $task->{disks}; |
5040d81c | 236 | my $volids = $task->{volids}; |
4ca61ce8 | 237 | |
22a91261 | 238 | my $rootdir = $default_mount_point; |
2e57a9f6 WB |
239 | my $storage_cfg = $self->{storecfg}; |
240 | ||
5040d81c | 241 | PVE::Storage::activate_volumes($storage_cfg, $volids, 'vzdump'); |
2e57a9f6 WB |
242 | foreach my $disk (@$disks) { |
243 | $disk->{dir} = "${rootdir}$disk->{mp}"; | |
4c98d66c | 244 | PVE::LXC::mountpoint_mount($disk, $rootdir, $storage_cfg, 'vzdump', $task->{rootuid}, $task->{rootgid}); |
2e57a9f6 WB |
245 | } |
246 | ||
247 | $task->{snapdir} = $rootdir; | |
4ca61ce8 DM |
248 | } |
249 | ||
d14a9a1b DM |
250 | sub copy_data_phase1 { |
251 | my ($self, $task) = @_; | |
252 | ||
9c9a3b8c WB |
253 | if (my $mntinfo = PVE::VZDump::get_mount_info($task->{snapdir})) { |
254 | if ($mntinfo->{fstype} =~ /^nfs4?/) { | |
b67c14c0 WB |
255 | $self->loginfo( |
256 | "temporary directory is on NFS, disabling xattr and acl" | |
257 | ." support, consider configuring a local tmpdir via" | |
258 | ." /etc/vzdump.conf\n"); | |
9c9a3b8c WB |
259 | $task->{no_xattrs} = 1; |
260 | } | |
261 | } | |
262 | ||
50ee6ffe | 263 | $self->$rsync_vm($task, $task->{snapdir}, "first", 1); |
d14a9a1b DM |
264 | } |
265 | ||
266 | sub copy_data_phase2 { | |
267 | my ($self, $task) = @_; | |
268 | ||
50ee6ffe | 269 | $self->$rsync_vm($task, $task->{snapdir}, "final", 0); |
d14a9a1b DM |
270 | } |
271 | ||
272 | sub stop_vm { | |
273 | my ($self, $task, $vmid) = @_; | |
274 | ||
f90f7e53 TL |
275 | my $opts = $self->{vzdump}->{opts}; |
276 | my $timeout = $opts->{stopwait} * 60; | |
277 | ||
b1bad293 | 278 | PVE::LXC::vm_stop($vmid, 0, $timeout); |
d14a9a1b DM |
279 | } |
280 | ||
281 | sub start_vm { | |
282 | my ($self, $task, $vmid) = @_; | |
283 | ||
05db033f OB |
284 | my $conf = PVE::LXC::Config->load_config($vmid); |
285 | PVE::LXC::vm_start($vmid, $conf); | |
d14a9a1b DM |
286 | } |
287 | ||
288 | sub suspend_vm { | |
289 | my ($self, $task, $vmid) = @_; | |
290 | ||
89424a8b | 291 | PVE::LXC::freeze($vmid); |
d14a9a1b DM |
292 | } |
293 | ||
294 | sub resume_vm { | |
295 | my ($self, $task, $vmid) = @_; | |
296 | ||
89424a8b | 297 | PVE::LXC::thaw($vmid); |
d14a9a1b DM |
298 | } |
299 | ||
300 | sub assemble { | |
301 | my ($self, $task, $vmid) = @_; | |
302 | ||
99a0bcb0 | 303 | my $opts = $self->{vzdump}->{opts}; |
514b5f82 | 304 | |
67afe46e | 305 | my $conf = PVE::LXC::Config->load_config($vmid); |
48314d4e | 306 | delete $conf->{lock}; |
514b5f82 | 307 | delete $conf->{snapshots}; |
f626ac9d | 308 | delete $conf->{parent}; |
53fafd3f | 309 | delete $conf->{pending}; |
514b5f82 | 310 | |
99a0bcb0 DM |
311 | my $tmpdir = $task->{tmpdir}; |
312 | ||
313 | mkpath "$tmpdir/etc/vzdump/"; | |
314 | ||
1b4cf758 | 315 | PVE::Tools::file_set_contents("$tmpdir/etc/vzdump/pct.conf", PVE::LXC::Config::write_pct_config("/lxc/$vmid.conf", $conf)); |
bf040874 WL |
316 | |
317 | my $firewall ="/etc/pve/firewall/$vmid.fw"; | |
d1671a80 | 318 | my $fwconftmp = "$tmpdir/etc/vzdump/pct.fw"; |
99a0bcb0 | 319 | |
3ae05e19 | 320 | if ($self->{vzdump}->{opts}->{pbs}) { |
99a0bcb0 DM |
321 | # fixme: do not store pct.conf and fw.conf into $tmpdir |
322 | if (-e $firewall) { | |
323 | PVE::Tools::file_copy($firewall, $fwconftmp); | |
324 | } | |
d1671a80 | 325 | } else { |
99a0bcb0 DM |
326 | if (-e $firewall) { |
327 | PVE::Tools::file_copy($firewall, $fwconftmp); | |
328 | } else { | |
329 | PVE::Tools::file_set_contents($fwconftmp, ''); | |
330 | } | |
331 | $task->{fw} = 1; | |
bf040874 | 332 | } |
d14a9a1b DM |
333 | } |
334 | ||
335 | sub archive { | |
336 | my ($self, $task, $vmid, $filename, $comp) = @_; | |
cbd6753d | 337 | |
b7ec90ed | 338 | my $disks = $task->{disks}; |
5a8a3087 | 339 | my @sources; |
b7ec90ed | 340 | |
459fd4d2 | 341 | if ($task->{mode} eq 'stop') { |
2e57a9f6 | 342 | my $storage_cfg = $self->{storecfg}; |
8ebb49ee | 343 | |
00cc0416 | 344 | PVE::Storage::activate_volumes($storage_cfg, $task->{volids}); |
8ebb49ee TL |
345 | |
346 | my $rootdir = $default_mount_point; | |
2e57a9f6 WB |
347 | foreach my $disk (@$disks) { |
348 | $disk->{dir} = "${rootdir}$disk->{mp}"; | |
4c98d66c | 349 | PVE::LXC::mountpoint_mount($disk, $rootdir, $storage_cfg, undef, $task->{rootuid}, $task->{rootgid}); |
5a8a3087 WB |
350 | # add every enabled mountpoint (since we use --one-file-system) |
351 | # mp already starts with a / so we only need to add the dot | |
352 | push @sources, ".$disk->{mp}"; | |
2e57a9f6 WB |
353 | } |
354 | $task->{snapdir} = $rootdir; | |
5040d81c FG |
355 | } elsif ($task->{mode} eq 'snapshot') { |
356 | # mounting the vzdump snapshots and setting $snapdir is already done, | |
357 | # but we need to include all mountpoints here! | |
358 | foreach my $disk (@$disks) { | |
359 | push @sources, ".$disk->{mp}"; | |
360 | } | |
5a8a3087 WB |
361 | } else { |
362 | # the data was rsynced to a temporary location, only use '.' to avoid | |
363 | # having mountpoints duplicated | |
364 | push @sources, '.'; | |
459fd4d2 DM |
365 | } |
366 | ||
d14a9a1b | 367 | my $opts = $self->{vzdump}->{opts}; |
d14a9a1b | 368 | my $snapdir = $task->{snapdir}; |
cbd6753d | 369 | my $tmpdir = $task->{tmpdir}; |
d14a9a1b | 370 | |
01dce99b | 371 | my $userns_cmd = $task->{userns_cmd}; |
99a0bcb0 | 372 | |
3ae05e19 | 373 | if ($self->{vzdump}->{opts}->{pbs}) { |
99a0bcb0 | 374 | |
99a0bcb0 | 375 | my $param = []; |
99a0bcb0 DM |
376 | push @$param, "pct.conf:$tmpdir/etc/vzdump/pct.conf"; |
377 | ||
378 | my $fw_conf = "$tmpdir/etc/vzdump/pct.fw"; | |
379 | if (-f $fw_conf) { | |
380 | push @$param, "fw.conf:$fw_conf"; | |
381 | } | |
382 | ||
2862bbe5 | 383 | my $rootdir = $snapdir; |
99a0bcb0 DM |
384 | push @$param, "root.pxar:$rootdir"; |
385 | ||
ef7f785c TL |
386 | foreach my $disk (@sources) { |
387 | push @$param, '--include-dev', "$snapdir/$disk"; | |
99a0bcb0 DM |
388 | } |
389 | ||
390 | push @$param, '--skip-lost-and-found' if $userns_cmd; | |
391 | ||
392 | push @$param, '--backup-type', 'ct'; | |
393 | push @$param, '--backup-id', $vmid; | |
394 | push @$param, '--backup-time', $task->{backup_time}; | |
395 | ||
2862bbe5 TL |
396 | my @storage = ($opts->{scfg}, $opts->{storage}); |
397 | ||
398 | my $logfunc = sub { my $line = shift; $self->loginfo($line) }; | |
399 | PVE::Storage::PBSPlugin::run_raw_client_cmd(@storage, 'backup', $param, | |
99a0bcb0 DM |
400 | logfunc => $logfunc, userns_cmd => $userns_cmd); |
401 | ||
2862bbe5 TL |
402 | # FIXME: move to a pve-common helper, storage has a similar one |
403 | my $time_iso8601 = strftime('%FT%TZ', gmtime($task->{backup_time})); | |
404 | my $snapshot_id = "ct/$vmid/$time_iso8601"; | |
405 | my $res = eval { PVE::Storage::PBSPlugin::run_client_cmd(@storage, 'files', [$snapshot_id]) } // []; | |
406 | $task->{size} = 0; | |
407 | $task->{size} += $_->{size} for @$res; | |
408 | ||
d14a9a1b | 409 | } else { |
99a0bcb0 DM |
410 | |
411 | my $tar = [@$userns_cmd, 'tar', 'cpf', '-', '--totals', | |
412 | @PVE::Storage::Plugin::COMMON_TAR_FLAGS, | |
413 | '--one-file-system', '--warning=no-file-ignored']; | |
414 | ||
415 | # note: --remove-files does not work because we do not | |
416 | # backup all files (filters). tar complains: | |
417 | # Cannot rmdir: Directory not empty | |
418 | # we disable this optimization for now | |
419 | #if ($snapdir eq $task->{tmpdir} && $snapdir =~ m|^$opts->{dumpdir}/|) { | |
420 | # push @$tar, "--remove-files"; # try to save space | |
421 | #} | |
422 | ||
423 | # The directory parameter can give an alternative directory as source. | |
424 | # the second parameter gives the structure in the tar. | |
425 | push @$tar, "--directory=$tmpdir", './etc/vzdump/pct.conf'; | |
426 | push @$tar, "./etc/vzdump/pct.fw" if $task->{fw}; | |
427 | push @$tar, "--directory=$snapdir"; | |
428 | push @$tar, '--no-anchored', '--exclude=lost+found' if $userns_cmd; | |
429 | push @$tar, '--anchored'; | |
430 | push @$tar, map { "--exclude=.$_" } @{$self->{vzdump}->{findexcl}}; | |
431 | ||
432 | push @$tar, @sources; | |
433 | ||
434 | my $cmd = [ $tar ]; | |
435 | ||
436 | my $bwl = $opts->{bwlimit}*1024; # bandwidth limit for cstream | |
437 | push @$cmd, [ 'cstream', '-t', $bwl ] if $opts->{bwlimit}; | |
438 | push @$cmd, [ split(/\s+/, $comp) ] if $comp; | |
439 | ||
440 | if ($opts->{stdout}) { | |
441 | $self->cmd($cmd, output => ">&" . fileno($opts->{stdout})); | |
442 | } else { | |
443 | push @{$cmd->[-1]}, \(">" . PVE::Tools::shellquote($filename)); | |
444 | $self->cmd($cmd); | |
445 | } | |
d14a9a1b DM |
446 | } |
447 | } | |
448 | ||
449 | sub cleanup { | |
450 | my ($self, $task, $vmid) = @_; | |
451 | ||
67afe46e | 452 | my $conf = PVE::LXC::Config->load_config($vmid); |
d14a9a1b | 453 | |
0c44de7b | 454 | if ($task->{mode} ne 'suspend') { |
96d20be2 DM |
455 | my $rootdir = $default_mount_point; |
456 | my $disks = $task->{disks}; | |
457 | foreach my $disk (reverse @$disks) { | |
458 | PVE::Tools::run_command(['umount', '-l', '-d', $disk->{dir}]) if $disk->{dir}; | |
459 | } | |
2e57a9f6 | 460 | } |
b739f640 | 461 | |
4ca61ce8 | 462 | if ($task->{cleanup}->{remove_snapshot}) { |
02e1a9c5 | 463 | $self->loginfo("cleanup temporary 'vzdump' snapshot"); |
4518000b | 464 | PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 0); |
d14a9a1b | 465 | } |
d14a9a1b DM |
466 | } |
467 | ||
468 | 1; |