[pve-devel] [RFC pve-container 2/3] vzdump: suspend mode fixes
Wolfgang Bumiller
w.bumiller at proxmox.com
Wed Sep 16 16:42:03 CEST 2015
-) '-x' is '--one-file-system' (the longer version is easier
to spot.)
-) Use --relative's special handling of `/./` in paths in
order to make --one-file-system and --exclude options work
together the way they should.
Here's the issue:
Say you have thse files in your container:
/the-file
/mp0/the-file
And assume /mp0 is a mountpoint.
Naturally you want `-exclude-path /the-file` to only exclude
the first of the two files. This is hard when rsyncing each
mountpoint separately, as the rsync command for mp0 would
see files relative to /mp0, and thus both files would be
excluded unless we modify exclude paths accordingly - which
we can't as they can be arbitrary glob patterns.
Now with rsync's --relative option - assume the container is
mounted at /temp (iow: /temp/ and /temp/mp0). Passing
/temp/mp0/ to rsync would copy the contents of the mp0
mountpoint into the root directory of the destination
(essentially doing the equivalent of `mv mp0/* /` in the
container's backup.). However, rsync's special treatment of
/./ with the --relative option allows us to pass
/temp/./mp0/ which tells rsync that `/mp0` is supposed to be
included in the path, iow. we're actually copying from
/temp/, but we want only its mp0/ directory.
See rsync(1)'s section about --relative for a detailed
description.
---
src/PVE/VZDump/LXC.pm | 34 +++++++++++++++++++++++++---------
1 file changed, 25 insertions(+), 9 deletions(-)
diff --git a/src/PVE/VZDump/LXC.pm b/src/PVE/VZDump/LXC.pm
index 21dc1ce..167e5fb 100644
--- a/src/PVE/VZDump/LXC.pm
+++ b/src/PVE/VZDump/LXC.pm
@@ -24,17 +24,27 @@ my $rsync_vm = sub {
my $opts = $self->{vzdump}->{opts};
- my $base = ['rsync', '--stats', '-x', '-X', '--numeric-ids',
- '-aH', '--delete', '--no-whole-file', '--inplace'];
+ my $base = ['rsync', '--stats', '-X', '--numeric-ids',
+ '-aH', '--delete', '--no-whole-file', '--inplace',
+ '--one-file-system', '--relative'];
push @$base, "--bwlimit=$opts->{bwlimit}" if $opts->{bwlimit};
push @$base, map { "--exclude=$_" } @{$self->{vzdump}->{findexcl}};
push @$base, map { "--exclude=$_" } @{$task->{exclude_dirs}};
- # FIXME: to support --one-file-system we have to make all exclude paths
- # relative to the current mountpoint
-
my $starttime = time();
- $self->cmd([@$base, $from, $to]);
+ # See the rsync(1) manpage for --relative in conjunction with /./ in paths.
+ # This is the only way to have exclude-dirs work together with the
+ # --one-file-system option.
+ # This way we can pass multiple source paths and tell rsync which directory
+ # they're supposed to be relative to.
+ # Otherwise with eg. using multiple rsync commands means the --exclude
+ # directives need to be modified for every command as they are meant to be
+ # relative to the rootdir, while rsync treats them as relative to the
+ # source dir.
+ foreach my $disk (@$disks) {
+ push @$base, "$from/.$disk->{mp}";
+ }
+ $self->cmd([@$base, $to]);
my $delay = time () - $starttime;
$self->loginfo ("$text sync finished ($delay seconds)");
@@ -239,6 +249,7 @@ sub archive {
my ($self, $task, $vmid, $filename, $comp) = @_;
my $disks = $task->{disks};
+ my @sources;
if ($task->{mode} eq 'stop') {
my $rootdir = $default_mount_point;
@@ -246,8 +257,15 @@ sub archive {
foreach my $disk (@$disks) {
$disk->{dir} = "${rootdir}$disk->{mp}";
PVE::LXC::mountpoint_mount($disk, $rootdir, $storage_cfg);
+ # add every enabled mountpoint (since we use --one-file-system)
+ # mp already starts with a / so we only need to add the dot
+ push @sources, ".$disk->{mp}";
}
$task->{snapdir} = $rootdir;
+ } else {
+ # the data was rsynced to a temporary location, only use '.' to avoid
+ # having mountpoints duplicated
+ push @sources, '.';
}
my $opts = $self->{vzdump}->{opts};
@@ -272,9 +290,7 @@ sub archive {
push @$tar, "--directory=$snapdir";
push @$tar, map { "--exclude=.$_" } @{$self->{vzdump}->{findexcl}};
- # add every enabled mountpoint (since we use --one-file-system)
- # mp already starts with a / so we only need to add the dot
- push @$tar, map { '.' . $_->{mp} } @$disks;
+ push @$tar, @sources;
my $cmd = [ $tar ];
--
2.1.4
More information about the pve-devel
mailing list