#!/usr/bin/perl use strict; use warnings; use Fcntl qw(S_IFREG); use File::Basename; use File::Path; use PVE::LXC::Tools; use PVE::Tools qw(MS_BIND); PVE::LXC::Tools::lxc_hook('autodev', 'lxc', sub { my ($vmid, $vars, undef, undef) = @_; my $root = $vars->{ROOTFS_MOUNT}; PVE::LXC::Tools::for_current_passthrough_devices($vmid, sub { my ($type, $major, $minor, $dev) = @_; my $rel_devpath = "/dev/$dev"; my $rel_dir = dirname($rel_devpath); File::Path::mkpath("$root/$rel_dir"); PVE::Tools::mknod("$root/dev/$dev", S_IFREG, 0) or die("Could not mknod $root/dev/$dev: $!\n"); PVE::Tools::mount("/var/lib/lxc/$vmid/passthrough/dev/$dev", "$root/dev/$dev", 0, MS_BIND, 0) or die("Bind mount of device $dev into container failed: $!\n"); }); PVE::LXC::Tools::for_current_passthrough_mounts($vmid, sub { my ($type, $major, $minor, $dev) = @_; my $rel_devpath = "/dev/$dev"; my $rel_dir = dirname($rel_devpath); File::Path::mkpath("$root/$rel_dir"); PVE::Tools::run_command(['mknod', '-m', '666', "$root/dev/$dev", $type, $major, $minor]); if ($dev =~ /^dm-\d+$/) { File::Path::mkpath("$root/dev/mapper"); my $mapped_name = PVE::Tools::file_get_contents("/sys/block/$dev/dm/name"); chomp $mapped_name; symlink("/dev/$dev", "$root/dev/mapper/$mapped_name"); } my $cgbase = "/sys/fs/cgroup/devices/lxc/$vmid"; my $limitpath = "$cgbase/devices.allow"; my $nspath = "$cgbase/ns/devices.allow"; if (!PVE::LXC::Tools::cgroup_do_write($limitpath, "$type $major:$minor rwm")) { warn "failed to allow access to device $dev ($major:$minor)\n"; } if (!PVE::LXC::Tools::cgroup_do_write($nspath, "$type $major:$minor rwm")) { warn "failed to allow access to device $dev ($major:$minor) inside the namespace\n"; } }); });