]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/VZDump/LXC.pm
add vm_stop helper
[pve-container.git] / src / PVE / VZDump / LXC.pm
index 4401f50b85a3d0cce06c2f81c94697190f200816..e58a00e357c42c3d01521041b8ce992aa508f0c6 100644 (file)
@@ -9,6 +9,7 @@ use PVE::Cluster qw(cfs_read_file);
 use PVE::Storage;
 use PVE::VZDump;
 use PVE::LXC;
+use PVE::LXC::Config;
 use PVE::Tools;
 
 use base qw (PVE::VZDump::Plugin);
@@ -16,7 +17,7 @@ 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} . '/';
@@ -27,7 +28,8 @@ my $rsync_vm = sub {
     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}};
@@ -85,21 +87,24 @@ sub vm_status {
 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} = [];
@@ -111,7 +116,7 @@ sub prepare {
     $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};
@@ -119,8 +124,9 @@ sub prepare {
 
        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;
        }
 
@@ -130,15 +136,18 @@ sub prepare {
     });
 
     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;
@@ -167,42 +176,20 @@ sub prepare {
        # 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 {
@@ -211,11 +198,15 @@ 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});
 
@@ -245,28 +236,28 @@ sub copy_data_phase1 {
        }
     }
 
-    $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 {
@@ -288,12 +279,12 @@ sub assemble {
 
     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) {
@@ -337,7 +328,7 @@ sub archive {
 
     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 
@@ -366,17 +357,17 @@ sub archive {
     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;
@@ -388,7 +379,7 @@ sub cleanup {
 
     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);
     }
 }