if the mountpoint configuration is not explicitly provided
via -rootfs or -mpX , recreate all volume mountpoints on the
provided -storage , restore the archive and then finally add
non-volume mountpoints back to the configuration.

if -rootfs (and optionally any -mpX) are provided, the old
configuration contained in the backup archive is completely
ignored. this allows reconfiguration of mountpoints when
restoring a backup, e.g. to change mountpoint paths or other
mountpoint options.
---
 src/PVE/API2/LXC.pm          | 51 ++++++++++++++++++++++++++++++++------------
 src/PVE/LXC/Create.pm        | 20 +++++++++++------
 src/PVE/VZDump/ConvertOVZ.pm |  4 ++--
 3 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 95932a9..d2b03ea 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -256,11 +256,18 @@ __PACKAGE__->register_method({
        my $conf = {};
 
        my $no_disk_param = {};
+       my $mp_param = {};
+       my $storage_only_mode = 1;
        foreach my $opt (keys %$param) {
            my $value = $param->{$opt};
            if ($opt eq 'rootfs' || $opt =~ m/^mp\d+$/) {
                # allow to use simple numbers (add default storage in that case)
-               $param->{$opt} = "$storage:$value" if $value =~ 
m/^\d+(\.\d+)?$/;
+               if ($value =~ m/^\d+(\.\d+)?$/) {
+                   $mp_param->{$opt} = "$storage:$value";
+               } else {
+                   $mp_param->{$opt} = $value;
+               }
+               $storage_only_mode = 0;
            } elsif ($opt =~ m/^unused\d+$/) {
                warn "ignoring '$opt', cannot create/restore with unused 
volume\n";
                delete $param->{$opt};
@@ -269,8 +276,12 @@ __PACKAGE__->register_method({
            }
        }
 
+       die "mountpoints configured, but 'rootfs' not set - aborting\n"
+           if !$storage_only_mode && !defined($mp_param->{rootfs});
+
        # check storage access, activate storage
-       PVE::LXC::Config->foreach_mountpoint($param, sub {
+       my $delayed_mp_param = {};
+       PVE::LXC::Config->foreach_mountpoint($mp_param, sub {
            my ($ms, $mountpoint) = @_;
 
            my $volid = $mountpoint->{volume};
@@ -279,6 +290,12 @@ __PACKAGE__->register_method({
            if ($mountpoint->{type} ne 'volume') { # bind or device
                die "Only root can pass arbitrary filesystem paths.\n"
                    if $authuser ne 'root@pam';
+               if ($restore) {
+                   die "Restoring to non-volume rootfs is not allowed.\n"
+                       if $ms eq 'rootfs';
+                   $delayed_mp_param->{$ms} = $mp_param->{$ms};
+                   delete $mp_param->{$ms};
+               }
            } else {
                my ($sid, $volname) = PVE::Storage::parse_volume_id($volid);
                &$check_and_activate_storage($sid);
@@ -286,7 +303,7 @@ __PACKAGE__->register_method({
        });
 
        # check/activate default storage
-       &$check_and_activate_storage($storage) if !defined($param->{rootfs});
+       &$check_and_activate_storage($storage) if !defined($mp_param->{rootfs});
 
        PVE::LXC::Config->update_pct_config($vmid, $conf, 0, $no_disk_param);
 
@@ -308,22 +325,25 @@ __PACKAGE__->register_method({
            my $vollist = [];
 
            eval {
-               if (!defined($param->{rootfs})) {
+               if ($storage_only_mode) {
                    if ($restore) {
-                       my (undef, $rootfsinfo) = 
PVE::LXC::Create::recover_config($archive);
-                       die "unable to detect disk size - please specify rootfs 
(size)\n"
-                           if !defined($rootfsinfo->{size});
-                       my $disksize = $rootfsinfo->{size} / (1024 * 1024 * 
1024); # create_disks expects GB as unit size
-                       delete $rootfsinfo->{size};
-                       delete $rootfsinfo->{ro} if defined($rootfsinfo->{ro});
-                       $rootfsinfo->{volume} = "$storage:$disksize";
-                       $param->{rootfs} = 
PVE::LXC::Config->print_ct_mountpoint($rootfsinfo, 1);
+                       (undef, $mp_param, $delayed_mp_param) = 
PVE::LXC::Create::recover_config($archive);
+                       PVE::LXC::Config->foreach_mountpoint($mp_param, sub {
+                           my ($ms, $mountpoint) = @_;
+                           die "unable to detect disk size - please specify 
$ms (size)\n"
+                               if !defined($mountpoint->{size});
+                           my $disksize = $mountpoint->{size} / (1024 * 1024 * 
1024); # create_disks expects GB as unit size 
+                           delete $mountpoint->{size};
+                           $mountpoint->{volume} = "$storage:$disksize";
+                           $mp_param->{$ms} = 
PVE::LXC::Config->print_ct_mountpoint($mountpoint, $ms eq 'rootfs');
+                       });
                    } else {
-                       $param->{rootfs} = "$storage:4"; # defaults to 4GB
+                       $mp_param->{rootfs} = "$storage:4"; # defaults to 4GB
                    }
                }
 
-               $vollist = PVE::LXC::create_disks($storage_cfg, $vmid, $param, 
$conf);
+               $vollist = PVE::LXC::create_disks($storage_cfg, $vmid, 
$mp_param, $conf);
+
 
                PVE::LXC::Create::create_rootfs($storage_cfg, $vmid, $conf,
                                                $archive, $password, $restore,
@@ -332,6 +352,9 @@ __PACKAGE__->register_method({
                $conf->{hostname} ||= "CT$vmid";
                $conf->{memory} ||= 512;
                $conf->{swap} //= 512;
+               foreach my $mp (keys %$delayed_mp_param) {
+                   $conf->{$mp} = $delayed_mp_param->{$mp};
+               }
                PVE::LXC::Config->write_config($vmid, $conf);
            };
            if (my $err = $@) {
diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
index fe47fc1..560d5b6 100644
--- a/src/PVE/LXC/Create.pm
+++ b/src/PVE/LXC/Create.pm
@@ -107,7 +107,8 @@ sub recover_config {
     PVE::Tools::run_command(['tar', '-xpOf', $archive, $conf_file, 
'--occurrence'], outfunc => $out);
 
     my $conf;
-    my $rootfsinfo;
+    my $mp_param = {};
+    my $delayed_mp_param = {};
 
     if ($conf_file =~ m/pct\.conf/) {
 
@@ -115,21 +116,26 @@ sub recover_config {
 
        delete $conf->{snapshots};
        delete $conf->{template}; # restored CT is never a template
-       
-       if (defined($conf->{rootfs})) {
-           $rootfsinfo = PVE::LXC::Config->parse_ct_rootfs($conf->{rootfs});
-       }
+
+       PVE::LXC::Config->foreach_mountpoint($conf, sub {
+           my ($ms, $mountpoint) = @_;
+           if ($mountpoint->{type} eq 'volume') {
+               $mp_param->{$ms} = $conf->{$ms};
+           } else {
+               $delayed_mp_param->{$ms} = $conf->{$ms};
+           }
+       });
        
     } elsif ($conf_file =~ m/vps\.conf/) {
        
-       ($conf, $rootfsinfo) = PVE::VZDump::ConvertOVZ::convert_ovz($raw);
+       ($conf, $mp_param, $delayed_mp_param) = 
PVE::VZDump::ConvertOVZ::convert_ovz($raw);
        
     } else {
 
        die "internal error";
     }
 
-    return wantarray ? ($conf, $rootfsinfo) : $conf;
+    return wantarray ? ($conf, $mp_param, $delayed_mp_param) : $conf;
 }
 
 sub restore_and_configure {
diff --git a/src/PVE/VZDump/ConvertOVZ.pm b/src/PVE/VZDump/ConvertOVZ.pm
index 8942453..616e30d 100644
--- a/src/PVE/VZDump/ConvertOVZ.pm
+++ b/src/PVE/VZDump/ConvertOVZ.pm
@@ -314,7 +314,7 @@ sub convert_ovz {
 
    $conf->{hostname} = $ovz_conf->{hostname}->{value};
 
-   my $rootfsinfo = { size => $disksize, mp => '/' };
+   my $mp_param = { rootfs => "local:convertedovz,size=$disksize" };
 
-   return wantarray ? ($conf, $rootfsinfo) : $conf;
+   return wantarray ? ($conf, $mp_param, {}) : $conf;
 }
-- 
2.1.4


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
http://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to