]> git.proxmox.com Git - pve-container.git/blame - src/lxc-pve-autodev-hook
followup: code cleanup
[pve-container.git] / src / lxc-pve-autodev-hook
CommitLineData
50df544c
WB
1#!/usr/bin/perl
2
50df544c
WB
3use strict;
4use warnings;
5
6exit 0 if $ENV{LXC_NAME} && $ENV{LXC_NAME} !~ /^\d+$/;
7
55d14e39
WB
8use File::Path;
9use File::Basename;
10
50df544c
WB
11use PVE::Tools;
12
13my $vmid = $ENV{LXC_NAME};
14my $root = $ENV{LXC_ROOTFS_MOUNT};
15
16if (@ARGV != 3 || $ARGV[1] ne 'lxc' || $ARGV[2] ne 'autodev') {
17 die "invalid usage, this is an LXC autodev hook\n";
18}
19
20if ($vmid ne $ARGV[0]) {
21 die "got wrong name: $ARGV[0] while LXC_NAME=$vmid\n";
22}
23
24my $devlist_file = "/var/lib/lxc/$vmid/devices";
74e20aeb 25my $fd;
50df544c 26
74e20aeb 27if (! open $fd, '<', $devlist_file) {
50df544c
WB
28 exit 0 if $!{ENOENT}; # If the list is empty the file might not exist.
29 die "failed to open device list: $!\n";
30}
31
7b31bd8c
WB
32sub cgroup_do_write($$) {
33 my ($path, $value) = @_;
34 my $fd;
35 if (!open($fd, '>', $path)) {
36 warn "failed to open cgroup file $path: $!\n";
37 return 0;
38 }
39 if (!defined syswrite($fd, $value)) {
40 warn "failed to write value $value to cgroup file $path: $!\n";
41 return 0;
42 }
43 close($fd);
44 return 1;
45}
46
50df544c
WB
47while (defined(my $line = <$fd>)) {
48 if ($line !~ m@^(b):(\d+):(\d+):/dev/(\S+)\s*$@) {
49 warn "invalid .pve-devices entry: $line\n";
50 }
51 my ($type, $major, $minor, $dev) = ($1, $2, $3, $4);
52
53 # Don't break out of $root/dev/
54 if ($dev =~ /\.\./) {
55 warn "skipping illegal device node entry: $dev\n";
56 next;
57 }
58
59 # Never expose /dev/loop-control
60 if ($major == 10 && $minor == 237) {
61 warn "skipping illegal device entry (loop-control) for: $dev\n";
62 next;
63 }
64
55d14e39
WB
65 my $rel_devpath = "/dev/$dev";
66 my $rel_dir = dirname($rel_devpath);
67 File::Path::mkpath("$root/$rel_dir");
68
50df544c
WB
69 PVE::Tools::run_command(['mknod', '-m', '666', "$root/dev/$dev",
70 $type, $major, $minor]);
ada088e6
WB
71
72 if ($dev =~ /^dm-\d+$/) {
73 File::Path::mkpath("$root/dev/mapper");
74 my $mapped_name = PVE::Tools::file_get_contents("/sys/block/$dev/dm/name");
75 chomp $mapped_name;
76 symlink("/dev/$dev", "$root/dev/mapper/$mapped_name");
77 }
7b31bd8c
WB
78
79 my $cgbase = "/sys/fs/cgroup/devices/lxc/$vmid";
80 my $limitpath = "$cgbase/devices.allow";
81 my $nspath = "$cgbase/ns/devices.allow";
82 if (!cgroup_do_write($limitpath, "$type $major:$minor rwm")) {
83 warn "failed to allow access to device $dev ($major:$minor)\n";
84 }
85 if (!cgroup_do_write($nspath, "$type $major:$minor rwm")) {
86 warn "failed to allow access to device $dev ($major:$minor) inside the namespace\n";
87 }
50df544c
WB
88}
89close $fd;
f067e7ba
WB
90
91exit 0;