]>
Commit | Line | Data |
---|---|---|
deaf7667 AD |
1 | #!/usr/bin/perl |
2 | ||
b056d074 DM |
3 | package lxc_pve_prestart_hook; |
4 | ||
deaf7667 AD |
5 | use strict; |
6 | use warnings; | |
4ed2b825 | 7 | |
3bd97c10 | 8 | use Fcntl qw(O_DIRECTORY :mode); |
deaf7667 | 9 | use File::Path; |
3bd97c10 | 10 | use POSIX; |
deaf7667 | 11 | |
deaf7667 | 12 | use PVE::Cluster; |
0a49c44e | 13 | use PVE::LXC::Config; |
c9a5774b | 14 | use PVE::LXC::Setup; |
0a49c44e WB |
15 | use PVE::LXC::Tools; |
16 | use PVE::LXC; | |
17 | use PVE::Storage; | |
3bd97c10 WB |
18 | use PVE::Syscall qw(:fsmount); |
19 | use PVE::Tools qw(AT_FDCWD O_PATH); | |
deaf7667 | 20 | |
0a49c44e WB |
21 | PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub { |
22 | my ($vmid, $vars, undef, undef) = @_; | |
c9a5774b | 23 | |
0a49c44e WB |
24 | my $skiplock_flag_fn = "/run/lxc/skiplock-$vmid"; |
25 | my $skiplock = 1 if -e $skiplock_flag_fn; | |
26 | unlink $skiplock_flag_fn if $skiplock; | |
c9a5774b | 27 | |
0a49c44e | 28 | PVE::Cluster::check_cfs_quorum(); # only start if we have quorum |
1e1fad99 | 29 | |
0a49c44e | 30 | return undef if ! -f PVE::LXC::Config->config_file($vmid); |
50df544c | 31 | |
0a49c44e WB |
32 | my $conf = PVE::LXC::Config->load_config($vmid); |
33 | if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) { | |
34 | PVE::LXC::Config->check_lock($conf); | |
35 | } | |
4c98d66c | 36 | |
896823c4 | 37 | my $storage_cfg = PVE::Storage::config(); |
c9a5774b | 38 | |
0a49c44e WB |
39 | my $vollist = PVE::LXC::Config->get_vm_volumes($conf); |
40 | my $loopdevlist = PVE::LXC::Config->get_vm_volumes($conf, 'rootfs'); | |
c9a5774b | 41 | |
0a49c44e | 42 | PVE::Storage::activate_volumes($storage_cfg, $vollist); |
3c99150a | 43 | |
0a49c44e | 44 | my $rootdir = $vars->{ROOTFS_PATH}; |
c9a5774b | 45 | |
0a49c44e WB |
46 | # Delete any leftover reboot-trigger file |
47 | unlink("/var/lib/lxc/$vmid/reboot"); | |
50df544c | 48 | |
0a49c44e WB |
49 | my $devlist_file = "/var/lib/lxc/$vmid/devices"; |
50 | unlink $devlist_file; | |
51 | my $devices = []; | |
deaf7667 | 52 | |
0a49c44e | 53 | my (undef, $rootuid, $rootgid) = PVE::LXC::parse_id_maps($conf); |
deaf7667 | 54 | |
0a49c44e WB |
55 | # Unmount first when the user mounted the container with "pct mount". |
56 | eval { | |
57 | PVE::Tools::run_command(['umount', '--recursive', $rootdir], outfunc => sub {}, errfunc => sub {}); | |
58 | }; | |
deaf7667 | 59 | |
3bd97c10 WB |
60 | my $setup_mountpoint; |
61 | if (!PVE::LXC::Tools::can_use_new_mount_api()) { | |
62 | # Legacy mode for old kernels: | |
63 | $setup_mountpoint = sub { | |
64 | my ($opt, $mountpoint) = @_; | |
65 | ||
66 | my (undef, undef, $dev) = PVE::LXC::mountpoint_mount( | |
67 | $mountpoint, | |
68 | $rootdir, | |
69 | $storage_cfg, | |
70 | undef, | |
71 | $rootuid, | |
72 | $rootgid, | |
73 | ); | |
74 | push @$devices, $dev if $dev && $mountpoint->{quota}; | |
75 | }; | |
76 | } else { | |
77 | # With newer kernels we stage mount points and then use move_mount(). | |
78 | my $rootdir_fd = undef; | |
79 | $setup_mountpoint = sub { | |
80 | my ($opt, $mountpoint) = @_; | |
81 | ||
82 | my $dir = PVE::LXC::get_staging_mount_path($opt); | |
83 | my (undef, undef, $dev, $mount_fd) = PVE::LXC::mountpoint_stage( | |
84 | $mountpoint, | |
85 | $dir, | |
86 | $storage_cfg, | |
87 | undef, | |
88 | $rootuid, | |
89 | $rootgid, | |
90 | ); | |
91 | ||
92 | my $ddir; | |
93 | if ($rootdir_fd) { | |
94 | # Mount relative to the rootdir fd. | |
95 | $ddir = './' . $mountpoint->{mp}; | |
96 | } else { | |
97 | # Assert that 'rootfs' is the first one: | |
98 | die "foreach_mount() error\n" if $opt ne 'rootfs'; | |
99 | ||
100 | # Mount the rootfs absolutely (rootdir_fd=undef uses AT_FDCWD). | |
101 | # $rootdir is not controlled by the container, so this is fine. | |
102 | $ddir = $rootdir; | |
103 | } | |
104 | ||
105 | PVE::LXC::mountpoint_insert_staged( | |
106 | $mount_fd, | |
107 | $rootdir_fd, | |
108 | $ddir, | |
109 | $opt, | |
110 | $rootuid, | |
111 | $rootgid, | |
112 | ); | |
113 | ||
114 | # From now on we mount inside our rootfs: | |
115 | if (!$rootdir_fd) { | |
116 | $rootdir_fd = $mount_fd; | |
117 | } | |
118 | ||
119 | push @$devices, $dev if $dev && $mountpoint->{quota}; | |
120 | }; | |
121 | } | |
122 | ||
0a49c44e | 123 | PVE::LXC::Config->foreach_mountpoint($conf, $setup_mountpoint); |
deaf7667 | 124 | |
0a49c44e WB |
125 | my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir); |
126 | $lxc_setup->pre_start_hook(); | |
deaf7667 | 127 | |
0a49c44e WB |
128 | if (@$devices) { |
129 | my $devlist = ''; | |
130 | foreach my $dev (@$devices) { | |
131 | my ($mode, $rdev) = (stat($dev))[2,6]; | |
132 | next if !$mode || !S_ISBLK($mode) || !$rdev; | |
133 | my $major = PVE::Tools::dev_t_major($rdev); | |
134 | my $minor = PVE::Tools::dev_t_minor($rdev); | |
135 | $devlist .= "b:$major:$minor:$dev\n"; | |
136 | } | |
137 | PVE::Tools::file_set_contents($devlist_file, $devlist); | |
138 | } | |
139 | }); |