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