use PVE::Storage;
use PVE::VZDump;
use PVE::LXC;
+use PVE::LXC::Config;
use PVE::Tools;
use base qw (PVE::VZDump::Plugin);
my $default_mount_point = "/mnt/vzsnap0";
my $rsync_vm = sub {
- my ($self, $task, $to, $text) = @_;
+ my ($self, $task, $to, $text, $first) = @_;
my $disks = $task->{disks};
my $from = $disks->[0]->{dir} . '/';
my @xattr = $task->{no_xattrs} ? () : ('-X', '-A');
my $rsync = ['rsync', '--stats', @xattr, '--numeric-ids',
- '-aH', '--delete', '--no-whole-file', '--inplace',
+ '-aH', '--delete', '--no-whole-file',
+ ($first ? '--sparse' : '--inplace'),
'--one-file-system', '--relative'];
push @$rsync, "--bwlimit=$opts->{bwlimit}" if $opts->{bwlimit};
push @$rsync, map { "--exclude=$_" } @{$self->{vzdump}->{findexcl}};
my $check_mountpoint_empty = sub {
my ($mountpoint) = @_;
- die "mountpoint '$mountpoint' is not a directory\n" if ! -d $mountpoint;
+ die "mount point '$mountpoint' is not a directory\n" if ! -d $mountpoint;
PVE::Tools::dir_glob_foreach($mountpoint, qr/.*/, sub {
my $entry = shift;
return if $entry eq '.' || $entry eq '..';
- die "mountpoint '$mountpoint' not empty\n";
+ die "mount point '$mountpoint' not empty\n";
});
};
sub prepare {
my ($self, $task, $vmid, $mode) = @_;
- my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::load_config($vmid);
+ my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::Config->load_config($vmid);
my $storage_cfg = $self->{storecfg};
+ $self->loginfo("CT Name: $conf->{hostname}")
+ if defined($conf->{hostname});
+
my $running = PVE::LXC::check_running($vmid);
my $disks = $task->{disks} = [];
$task->{userns_cmd} = PVE::LXC::userns_command($id_map);
my $volids = $task->{volids} = [];
- PVE::LXC::foreach_mountpoint($conf, sub {
+ PVE::LXC::Config->foreach_mountpoint($conf, sub {
my ($name, $data) = @_;
my $volid = $data->{volume};
my $mount = $data->{mp};
return if !$volid || !$mount;
- if ($name ne 'rootfs' && !$data->{backup}) {
+ if (!PVE::LXC::Config->mountpoint_backup_enabled($name, $data)) {
push @$exclude_dirs, $mount;
+ $self->loginfo("excluding $type mount point $name ('$mount') from backup");
return;
}
});
if ($mode eq 'snapshot') {
- if (!PVE::LXC::has_feature('snapshot', $conf, $storage_cfg, undef, undef, 1)) {
+ if (!PVE::LXC::Config->has_feature('snapshot', $conf, $storage_cfg, undef, undef, 1)) {
die "mode failure - some volumes do not support snapshots\n";
}
- unlock_vm($self, $vmid);
if ($conf->{snapshots} && $conf->{snapshots}->{vzdump}) {
$self->loginfo("found old vzdump snapshot (force removal)");
- PVE::LXC::snapshot_delete($vmid, 'vzdump', 1);
+ PVE::LXC::Config->lock_config($vmid, sub {
+ $self->unlock_vm($vmid);
+ PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 1);
+ $self->lock_vm($vmid);
+ });
}
my $rootdir = $default_mount_point;
# If we perform mount operations, let's unshare the mount namespace
# to not influence the running host.
PVE::Tools::unshare(PVE::Tools::CLONE_NEWNS);
- PVE::Tools::run_command(['mount', '--make-rprivate', '/']);
+ PVE::Tools::run_command(['mount', '--make-rslave', '/']);
}
}
sub lock_vm {
my ($self, $vmid) = @_;
- my $lockconfig = sub {
- my ($self, $vmid) = @_;
-
- my $conf = PVE::LXC::load_config($vmid);
-
- PVE::LXC::check_lock($conf);
- $conf->{lock} = 'backup';
-
- PVE::LXC::write_config($vmid, $conf);
- };
-
- PVE::LXC::lock_config($vmid, $lockconfig, ($self, $vmid));
+ PVE::LXC::Config->set_lock($vmid, 'backup');
}
sub unlock_vm {
my ($self, $vmid) = @_;
- my $unlockconfig = sub {
- my ($self, $vmid) = @_;
-
- my $conf = PVE::LXC::load_config($vmid);
-
- if ($conf->{lock} && $conf->{lock} eq 'backup') {
- delete $conf->{lock};
- PVE::LXC::write_config($vmid, $conf);
- }
- };
-
- PVE::LXC::lock_config($vmid, $unlockconfig, ($self, $vmid));
+ PVE::LXC::Config->remove_lock($vmid, 'backup')
}
sub snapshot {
$self->loginfo("create storage snapshot 'vzdump'");
# todo: freeze/unfreeze if we have more than one volid
- PVE::LXC::snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot");
+ PVE::LXC::Config->lock_config($vmid, sub {
+ $self->unlock_vm($vmid);
+ PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot");
+ $self->lock_vm($vmid);
+ });
$task->{cleanup}->{remove_snapshot} = 1;
# reload config
- my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::load_config($vmid);
+ my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::Config->load_config($vmid);
die "unable to read vzdump snapshot config - internal error"
if !($conf->{snapshots} && $conf->{snapshots}->{vzdump});
}
}
- $self->$rsync_vm($task, $task->{snapdir}, "first");
+ $self->$rsync_vm($task, $task->{snapdir}, "first", 1);
}
sub copy_data_phase2 {
my ($self, $task) = @_;
- $self->$rsync_vm($task, $task->{snapdir}, "final");
+ $self->$rsync_vm($task, $task->{snapdir}, "final", 0);
}
sub stop_vm {
my ($self, $task, $vmid) = @_;
- $self->cmd("lxc-stop -n $vmid");
+ my $opts = $self->{vzdump}->{opts};
+ my $timeout = $opts->{stopwait} * 60;
- # make sure container is stopped
- $self->cmd("lxc-wait -n $vmid -s STOPPED");
+ PVE::LXC::vm_stop($vmid, 0, $timeout);
}
sub start_vm {
my ($self, $task, $vmid) = @_;
- $self->cmd ("lxc-start -n $vmid");
+ $self->cmd(['systemctl', 'start', "pve-container\@$vmid"]);
}
sub suspend_vm {
mkpath "$tmpdir/etc/vzdump/";
- my $conf = PVE::LXC::load_config($vmid);
+ my $conf = PVE::LXC::Config->load_config($vmid);
delete $conf->{lock};
delete $conf->{snapshots};
- delete $conf->{'pve.parent'};
+ delete $conf->{parent};
- PVE::Tools::file_set_contents("$tmpdir/etc/vzdump/pct.conf", PVE::LXC::write_pct_config("/lxc/$vmid.conf", $conf));
+ PVE::Tools::file_set_contents("$tmpdir/etc/vzdump/pct.conf", PVE::LXC::Config::write_pct_config("/lxc/$vmid.conf", $conf));
my $firewall ="/etc/pve/firewall/$vmid.fw";
if (-e $firewall) {
my $userns_cmd = $task->{userns_cmd};
my $tar = [@$userns_cmd, 'tar', 'cpf', '-', '--totals',
- @$PVE::LXC::COMMON_TAR_FLAGS,
+ @PVE::Storage::Plugin::COMMON_TAR_FLAGS,
'--one-file-system', '--warning=no-file-ignored'];
# note: --remove-files does not work because we do not
push @$cmd, [ split(/\s+/, $comp) ] if $comp;
if ($opts->{stdout}) {
- push @{$cmd->[-1]}, \(">&" . fileno($opts->{stdout}));
+ $self->cmd($cmd, output => ">&" . fileno($opts->{stdout}));
} else {
push @{$cmd->[-1]}, \(">" . PVE::Tools::shellquote($filename));
+ $self->cmd($cmd);
}
- $self->cmd($cmd);
}
sub cleanup {
my ($self, $task, $vmid) = @_;
- my $conf = PVE::LXC::load_config($vmid);
+ my $conf = PVE::LXC::Config->load_config($vmid);
if ($task->{mode} ne 'suspend') {
my $rootdir = $default_mount_point;
if ($task->{cleanup}->{remove_snapshot}) {
$self->loginfo("remove vzdump snapshot");
- PVE::LXC::snapshot_delete($vmid, 'vzdump', 0);
+ PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 0);
}
}