#!/usr/bin/perl

package lxc_pve_prestart_hook;

use strict;
use warnings;

use POSIX;
use File::Path;
use Fcntl ':mode';

use PVE::Cluster;
use PVE::LXC::Config;
use PVE::LXC::Setup;
use PVE::LXC::Tools;
use PVE::LXC;
use PVE::Storage;
use PVE::Tools;

PVE::LXC::Tools::lxc_hook('pre-start', 'lxc', sub {
    my ($vmid, $vars, undef, undef) = @_;

    my $skiplock_flag_fn = "/run/lxc/skiplock-$vmid";
    my $skiplock = 1 if -e $skiplock_flag_fn;
    unlink $skiplock_flag_fn if $skiplock;

    PVE::Cluster::check_cfs_quorum(); # only start if we have quorum

    return undef if ! -f PVE::LXC::Config->config_file($vmid);

    my $conf = PVE::LXC::Config->load_config($vmid);
    if (!$skiplock && !PVE::LXC::Config->has_lock($conf, 'mounted')) {
	PVE::LXC::Config->check_lock($conf);
    }

    my $storage_cfg = PVE::Storage::config();

    my $vollist = PVE::LXC::Config->get_vm_volumes($conf);
    my $loopdevlist = PVE::LXC::Config->get_vm_volumes($conf, 'rootfs');

    PVE::Storage::activate_volumes($storage_cfg, $vollist);

    my $rootdir = $vars->{ROOTFS_PATH};

    # Delete any leftover reboot-trigger file
    unlink("/var/lib/lxc/$vmid/reboot");

    my $devlist_file = "/var/lib/lxc/$vmid/devices";
    unlink $devlist_file;
    my $devices = [];

    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 {});
    };

    PVE::LXC::Config->foreach_mountpoint($conf, $setup_mountpoint);

    my $lxc_setup = PVE::LXC::Setup->new($conf, $rootdir);
    $lxc_setup->pre_start_hook();

    if (@$devices) {
	my $devlist = '';
	foreach my $dev (@$devices) {
	    my ($mode, $rdev) = (stat($dev))[2,6];
	    next if !$mode || !S_ISBLK($mode) || !$rdev;
	    my $major = PVE::Tools::dev_t_major($rdev);
	    my $minor = PVE::Tools::dev_t_minor($rdev);
	    $devlist .= "b:$major:$minor:$dev\n";
	}
	PVE::Tools::file_set_contents($devlist_file, $devlist);
    }
});
