]> git.proxmox.com Git - pve-container.git/blobdiff - src/PVE/VZDump/LXC.pm
Refactor mountpoint and general conf methods
[pve-container.git] / src / PVE / VZDump / LXC.pm
index 9c40ea3d7316c866dd104a4a33028b5f179a0eef..396a94d5dfe4c4e41eab23368290ba7831738f33 100644 (file)
@@ -97,7 +97,7 @@ my $check_mountpoint_empty = sub {
 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};
 
     my $running = PVE::LXC::check_running($vmid);
@@ -110,12 +110,14 @@ sub prepare {
     my ($id_map, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf);
     $task->{userns_cmd} = PVE::LXC::userns_command($id_map);
 
-    PVE::LXC::foreach_mountpoint($conf, sub {
+    my $volids = $task->{volids} = [];
+    PVE::LXC::Config->foreach_mountpoint($conf, sub {
        my ($name, $data) = @_;
        my $volid = $data->{volume};
        my $mount = $data->{mp};
+       my $type = $data->{type};
 
-       return if !$volid || !$mount || $volid =~ m|^/|;
+       return if !$volid || !$mount;
 
        if ($name ne 'rootfs' && !$data->{backup}) {
            push @$exclude_dirs, $mount;
@@ -123,30 +125,33 @@ sub prepare {
        }
 
        push @$disks, $data;
+       push @$volids, $volid
+           if $type eq 'volume';
     });
-    my $volid_list = [map { $_->{volume} } @$disks];
 
     if ($mode eq 'snapshot') {
-       if (!PVE::LXC::has_feature('snapshot', $conf, $storage_cfg)) {
-           die "mode failure - some volumes does not support snapshots\n";
+       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', 0);
+           PVE::LXC::Config->snapshot_delete($vmid, 'vzdump', 1);
        }
 
        my $rootdir = $default_mount_point;
        mkpath $rootdir;
        &$check_mountpoint_empty($rootdir);
 
-       # set snapshot_count (freezes CT it snapshot_count > 1)
-       $task->{snapshot_count} = scalar(@$volid_list);
+       # set snapshot_count (freezes CT if snapshot_count > 1)
+       $task->{snapshot_count} = scalar(@$volids);
     } elsif ($mode eq 'stop') {
        my $rootdir = $default_mount_point;
        mkpath $rootdir;
        &$check_mountpoint_empty($rootdir);
-       PVE::Storage::activate_volumes($storage_cfg, $volid_list);
+       PVE::Storage::activate_volumes($storage_cfg, $volids);
     } elsif ($mode eq 'suspend') {
        my $pid = PVE::LXC::find_lxc_pid($vmid);
        foreach my $disk (@$disks) {
@@ -154,11 +159,12 @@ sub prepare {
        }
        $task->{snapdir} = $task->{tmpdir};
     } else {
+       unlock_vm($self, $vmid);
        die "unknown mode '$mode'\n"; # should not happen
     }
 
     if ($mode ne 'suspend') {
-       # If we preform mount operations, let's unshare the mount namespace
+       # 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', '/']);
@@ -168,36 +174,58 @@ sub prepare {
 sub lock_vm {
     my ($self, $vmid) = @_;
 
-    PVE::LXC::lock_aquire($vmid);
+    my $lockconfig = sub {
+       my ($self, $vmid) = @_;
+
+       my $conf = PVE::LXC::Config->load_config($vmid);
+
+       PVE::LXC::Config->check_lock($conf);
+       $conf->{lock} = 'backup';
+
+       PVE::LXC::Config->write_config($vmid, $conf);
+    };
+
+    PVE::LXC::Config->lock_config($vmid, $lockconfig, ($self, $vmid));
 }
 
 sub unlock_vm {
     my ($self, $vmid) = @_;
 
-    PVE::LXC::lock_release($vmid);
+    my $unlockconfig = sub {
+       my ($self, $vmid) = @_;
+
+       my $conf = PVE::LXC::Config->load_config($vmid);
+
+       if ($conf->{lock} && $conf->{lock} eq 'backup') {
+           delete $conf->{lock};
+           PVE::LXC::Config->write_config($vmid, $conf);
+       }
+    };
+
+    PVE::LXC::Config->lock_config($vmid, $unlockconfig, ($self, $vmid));
 }
 
 sub snapshot {
     my ($self, $task, $vmid) = @_;
 
-    $self->loginfo("create storage snapshot snapshot");
+    $self->loginfo("create storage snapshot 'vzdump'");
 
     # todo: freeze/unfreeze if we have more than one volid
-    PVE::LXC::snapshot_create($vmid, 'vzdump', "vzdump backup snapshot");
+    PVE::LXC::Config->snapshot_create($vmid, 'vzdump', 0, "vzdump backup snapshot");
     $task->{cleanup}->{remove_snapshot} = 1;
     
     # reload config
-    my $conf = $self->{vmlist}->{$vmid} = PVE::LXC::load_config($vmid);
-    die "unable to read vzdump shanpshot config - internal error"
+    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});
 
     my $disks = $task->{disks};
-    my $volid_list = [map { $_->{volume} } @$disks];
+    my $volids = $task->{volids};
 
     my $rootdir = $default_mount_point;
     my $storage_cfg = $self->{storecfg};
 
-    PVE::Storage::activate_volumes($storage_cfg, $volid_list, 'vzdump');
+    PVE::Storage::activate_volumes($storage_cfg, $volids, 'vzdump');
     foreach my $disk (@$disks) {
        $disk->{dir} = "${rootdir}$disk->{mp}";
        PVE::LXC::mountpoint_mount($disk, $rootdir, $storage_cfg, 'vzdump');
@@ -230,6 +258,9 @@ sub stop_vm {
     my ($self, $task, $vmid) = @_;
 
     $self->cmd("lxc-stop -n $vmid");
+
+    # make sure container is stopped
+    $self->cmd("lxc-wait -n $vmid -s STOPPED");
 }
 
 sub start_vm {
@@ -257,11 +288,18 @@ 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'};
 
     PVE::Tools::file_set_contents("$tmpdir/etc/vzdump/pct.conf", PVE::LXC::write_pct_config("/lxc/$vmid.conf", $conf));
+
+    my $firewall ="/etc/pve/firewall/$vmid.fw";
+    if (-e  $firewall) {
+       PVE::Tools::file_copy($firewall, "$tmpdir/etc/vzdump/pct.fw");
+       $task->{fw} = 1;
+    }
 }
 
 sub archive {
@@ -281,6 +319,12 @@ sub archive {
            push @sources, ".$disk->{mp}";
        }
        $task->{snapdir} = $rootdir;
+    } elsif ($task->{mode} eq 'snapshot') {
+       # mounting the vzdump snapshots and setting $snapdir is already done,
+       # but we need to include all mountpoints here!
+       foreach my $disk (@$disks) {
+           push @sources, ".$disk->{mp}";
+       }
     } else {
        # the data was rsynced to a temporary location, only use '.' to avoid
        # having mountpoints duplicated
@@ -299,15 +343,18 @@ sub archive {
     # note: --remove-files does not work because we do not 
     # backup all files (filters). tar complains:
     # Cannot rmdir: Directory not empty
-    # we we disable this optimization for now
+    # we disable this optimization for now
     #if ($snapdir eq $task->{tmpdir} && $snapdir =~ m|^$opts->{dumpdir}/|) {
     #       push @$tar, "--remove-files"; # try to save space
     #}
 
-    # The directory parameter can give a alternative directory as source.
+    # The directory parameter can give an alternative directory as source.
     # the second parameter gives the structure in the tar.
     push @$tar, "--directory=$tmpdir", './etc/vzdump/pct.conf';
+    push @$tar, "./etc/vzdump/pct.fw" if $task->{fw};
     push @$tar, "--directory=$snapdir";
+    push @$tar, '--no-anchored', '--exclude=lost+found' if $userns_cmd;
+    push @$tar, '--anchored';
     push @$tar, map { "--exclude=.$_" } @{$self->{vzdump}->{findexcl}};
 
     push @$tar, @sources;
@@ -316,7 +363,7 @@ sub archive {
 
     my $bwl = $opts->{bwlimit}*1024; # bandwidth limit for cstream
     push @$cmd, [ 'cstream', '-t', $bwl ] if $opts->{bwlimit};
-    push @$cmd, [ $comp ] if $comp;
+    push @$cmd, [ split(/\s+/, $comp) ] if $comp;
 
     if ($opts->{stdout}) {
        push @{$cmd->[-1]}, \(">&" . fileno($opts->{stdout}));
@@ -329,7 +376,7 @@ sub archive {
 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;
@@ -341,7 +388,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);
     }
 }