This way we operate on defined paths in the monitor namespace (/run/pve/mountpoint/{rootfs,mp0,mp1,...}) while performing the mount, and can use `move_mount()` without passing the MOVE_MOUNT_T_SYMLINKS flag when putting the hierarchy in place.
Signed-off-by: Wolfgang Bumiller <w.bumil...@proxmox.com> --- Changes to v2: use mountpoint_insert_staged. src/lxc-pve-prestart-hook | 78 +++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/src/lxc-pve-prestart-hook b/src/lxc-pve-prestart-hook index c0965ab..229af8e 100755 --- a/src/lxc-pve-prestart-hook +++ b/src/lxc-pve-prestart-hook @@ -5,9 +5,9 @@ package lxc_pve_prestart_hook; use strict; use warnings; -use POSIX; +use Fcntl qw(O_DIRECTORY :mode); use File::Path; -use Fcntl ':mode'; +use POSIX; use PVE::Cluster; use PVE::LXC::Config; @@ -15,7 +15,8 @@ use PVE::LXC::Setup; use PVE::LXC::Tools; use PVE::LXC; use PVE::Storage; -use PVE::Tools; +use PVE::Syscall qw(:fsmount); +use PVE::Tools qw(AT_FDCWD O_PATH); PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub { my ($vmid, $vars, undef, undef) = @_; @@ -51,19 +52,74 @@ PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub { my (undef, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf); - my $setup_mountpoint = sub { - my ($ms, $mountpoint) = @_; - - #return if $ms eq 'rootfs'; - my (undef, undef, $dev) = PVE::LXC::mountpoint_mount($mountpoint, $rootdir, $storage_cfg, undef, $rootuid, $rootgid); - push @$devices, $dev if $dev && $mountpoint->{quota}; - }; - # Unmount first when the user mounted the container with "pct mount". eval { PVE::Tools::run_command(['umount', '--recursive', $rootdir], outfunc => sub {}, errfunc => sub {}); }; + my $setup_mountpoint; + if (!PVE::LXC::Tools::can_use_new_mount_api()) { + # Legacy mode for old kernels: + $setup_mountpoint = sub { + my ($opt, $mountpoint) = @_; + + my (undef, undef, $dev) = PVE::LXC::mountpoint_mount( + $mountpoint, + $rootdir, + $storage_cfg, + undef, + $rootuid, + $rootgid, + ); + push @$devices, $dev if $dev && $mountpoint->{quota}; + }; + } else { + # With newer kernels we stage mount points and then use move_mount(). + my $rootdir_fd = undef; + $setup_mountpoint = sub { + my ($opt, $mountpoint) = @_; + + my $dir = PVE::LXC::get_staging_mount_path($opt); + my (undef, undef, $dev, $mount_fd) = PVE::LXC::mountpoint_stage( + $mountpoint, + $dir, + $storage_cfg, + undef, + $rootuid, + $rootgid, + ); + + my $ddir; + if ($rootdir_fd) { + # Mount relative to the rootdir fd. + $ddir = './' . $mountpoint->{mp}; + } else { + # Assert that 'rootfs' is the first one: + die "foreach_mount() error\n" if $opt ne 'rootfs'; + + # Mount the rootfs absolutely (rootdir_fd=undef uses AT_FDCWD). + # $rootdir is not controlled by the container, so this is fine. + $ddir = $rootdir; + } + + PVE::LXC::mountpoint_insert_staged( + $mount_fd, + $rootdir_fd, + $ddir, + $opt, + $rootuid, + $rootgid, + ); + + # From now on we mount inside our rootfs: + if (!$rootdir_fd) { + $rootdir_fd = $mount_fd; + } + + push @$devices, $dev if $dev && $mountpoint->{quota}; + }; + } + PVE::LXC::Config->foreach_mountpoint($conf, $setup_mountpoint); my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); -- 2.20.1 _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel