From: Dietmar Maurer Date: Mon, 31 Aug 2015 13:59:55 +0000 (+0200) Subject: implement mount_all/umount_all X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;ds=sidebyside;h=9622e8484672154e60f27221a094af61dcff8563;p=pve-container.git implement mount_all/umount_all --- diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm index 718fcbf..45cc369 100644 --- a/src/PVE/LXC.pm +++ b/src/PVE/LXC.pm @@ -1764,21 +1764,42 @@ sub is_template { return 1 if defined $conf->{template} && $conf->{template} == 1; } -sub foreach_mountpoint { - my ($conf, $func) = @_; +sub mountpoint_names { + my ($reverse) = @_; - my $mountpoint = parse_ct_mountpoint($conf->{rootfs}); - $mountpoint->{mp} = '/'; # just to be sure - &$func('rootfs', $mountpoint); + my @names = ('rootfs'); for (my $i = 0; $i < $MAX_MOUNT_POINTS; $i++) { - my $key = "mp$i"; - next if !defined($conf->{$key}); - $mountpoint = parse_ct_mountpoint($conf->{$key}); + push @names, "mp$i"; + } + + return $reverse ? reverse @names : @names; +} + +sub foreach_mountpoint_full { + my ($conf, $reverse, $func) = @_; + + foreach my $key (mountpoint_names($reverse)) { + my $value = $conf->{$key}; + next if !defined($value); + my $mountpoint = parse_ct_mountpoint($value); + $mountpoint->{mp} = '/' if $key eq 'rootfs'; # just to be sure &$func($key, $mountpoint); } } +sub foreach_mountpoint { + my ($conf, $func) = @_; + + foreach_mountpoint_full($conf, 0, $func); +} + +sub foreach_mountpoint_reverse { + my ($conf, $func) = @_; + + foreach_mountpoint_full($conf, 1, $func); +} + sub loopdevices_list { my $loopdev = {}; @@ -1892,6 +1913,84 @@ sub dettach_loops { } } +sub umount_all { + my ($vmid, $storage_cfg, $conf, $noerr) = @_; + + my $loopdevs = loopdevices_list(); + + my $rootdir = "/var/lib/lxc/$vmid/rootfs"; + my $volid_list = get_vm_volumes($conf); + + foreach_mountpoint_reverse($conf, sub { + my ($ms, $mountpoint) = @_; + + my $volid = $mountpoint->{volume}; + my $mount = $mountpoint->{mp}; + + return if !$volid || !$mount; + + $mount_path = "$rootdir/$mount"; + + # fixme: test if mounted? + eval { + PVE::Tools::run_command(['umount', '-d', $mountpoint_path]); + }; + if (my $err = $@) { + if ($noerr) { + warn $err; + } else { + die $err; + } + } + }); + + PVE::LXC::dettach_loops($storage_cfg, $volid_list); +} + +sub mount_all { + my ($vmid, $storage_cfg, $conf, $format_raw_images) = @_; + + my $rootdir = "/var/lib/lxc/$vmid/rootfs"; + + my $volid_list = get_vm_volumes($conf); + PVE::Storage::activate_volumes($storage_cfg, $volid_list); + + eval { + my $loopdevs = attach_loops($storage_cfg, $volid_list); + + foreach_mountpoint($conf, sub { + my ($ms, $mountpoint) = @_; + + my $volid = $mountpoint->{volume}; + my $mount = $mountpoint->{mp}; + + return if !$volid || !$mount; + + my $image_path = PVE::Storage::path($storage_cfg, $volid); + my ($vtype, undef, undef, undef, undef, $isBase, $format) = + PVE::Storage::parse_volname($storage_cfg, $volid); + + die "unable to mount base volume - internal error" if $isBase; + + if ($format_raw_images && $format eq 'raw') { + my $cmd = ['mkfs.ext4', $image_path]; + PVE::Tools::run_command($cmd); + } + + mountpoint_mount($mountpoint, $rootdir, $storage_cfg, $loopdevs); + }); + }; + if (my $err = $@) { + warn "mounting container failed - $err"; + umount_all($vmid, $storage_cfg, $conf, 1); + } else { + umount_all($vmid, $storage_cfg, $conf, 0); + } + + return $rootdir; +} + + sub mountpoint_mount_path { my ($mountpoint, $storage_cfg, $loopdevs, $snapname) = @_; diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm index ebd81cc..04fd767 100644 --- a/src/PVE/LXC/Create.pm +++ b/src/PVE/LXC/Create.pm @@ -205,39 +205,18 @@ sub create_rootfs { PVE::LXC::create_config($vmid, $conf); } - my $mountpoint = PVE::LXC::parse_ct_mountpoint($conf->{rootfs}); - $mountpoint->{mp} = '/'; - - my $volid = $mountpoint->{volume}; - - my $image_path = PVE::Storage::path($storage_cfg, $volid); - my $mountpoint_path = "/var/lib/lxc/$vmid/rootfs"; - eval { - PVE::Storage::activate_volumes($storage_cfg, [$volid]); - my $loopdevs = PVE::LXC::attach_loops($storage_cfg, [$volid]); - if (!-d $image_path) { - my $cmd = ['mkfs.ext4', $image_path]; - PVE::Tools::run_command($cmd); - } - - PVE::LXC::mountpoint_mount($mountpoint, $mountpoint_path, $storage_cfg, $loopdevs); - - restore_and_configure($vmid, $archive, $mountpoint_path, $conf, $password, $restore); + my $rootdir = PVE::LXC::mount_all($vmid, $storage_cfg, $conf, 1); + restore_and_configure($vmid, $archive, $rootdir, $conf, $password, $restore); }; if (my $err = $@) { - eval { - PVE::LXC::dettach_loops($storage_cfg, [$volid]); - PVE::Storage::deactivate_volumes($storage_cfg, [$volid]); - }; - warn $@ if $@; - die $err; + warn $err; + PVE::LXC::umount_all($vmid, $storage_cfg, $conf, 1); + } else { + PVE::LXC::umount_all($vmid, $storage_cfg, $conf, 0); } - PVE::Tools::run_command(['umount', '-l', '-d', $mountpoint_path]); - PVE::LXC::dettach_loops($storage_cfg, [$volid]); PVE::Storage::deactivate_volumes($storage_cfg, [$volid]); - } 1;