Skip to content

Instantly share code, notes, and snippets.

@lae
Created May 3, 2022 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lae/9ef4c3af24c372110273bc6cf10831f5 to your computer and use it in GitHub Desktop.
Save lae/9ef4c3af24c372110273bc6cf10831f5 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
use strict;
use warnings;
my %associations = (
100 => ['/microcosm/audio', '/microcosm/books', '/microcosm/games', '/microcosm/scramble', '/microcosm/work'],
101 => ['/microcosm/audio', '/microcosm/games']
);
use PVE::QemuServer;
use Template;
my $tt = Template->new;
print "GUEST HOOK: " . join(' ', @ARGV) . "\n";
my $vmid = shift;
my $conf = PVE::QemuConfig->load_config($vmid);
my $vfs_args_file = "/run/$vmid.virtfs";
my $phase = shift;
my $unit_tpl = "[Unit]
Description=virtiofsd filesystem share at [% share %] for VM %i
StopWhenUnneeded=true
[Service]
Type=simple
PIDFile=/run/virtiofsd/.run.virtiofsd.%i-[% share_id %].sock.pid
ExecStart=/usr/lib/kvm/virtiofsd -f --socket-path=/run/virtiofsd/%i-[% share_id %].sock -o source=[% share %] -o cache=always
[Install]
RequiredBy=%i.scope\n";
if ($phase eq 'pre-start') {
print "$vmid is starting, doing preparations.\n";
my $vfs_args = "-object memory-backend-memfd,id=mem,size=$conf->{memory}M,share=on -numa node,memdev=mem";
my $char_id = 0;
# TODO: Have removal logic. Probably need to glob the systemd directory for matching files.
for (@{$associations{$vmid}}) {
my $share_id = $_ =~ s/^\///r =~ s/\//_/gr;
my $unit_name = 'virtiofsd-' . $share_id;
my $unit_file = '/etc/systemd/system/' . $unit_name . '@.service';
print "attempting to install unit $unit_name...\n";
if (not -e $unit_file) {
$tt->process(\$unit_tpl, { share => $_, share_id => $share_id }, $unit_file)
|| die $tt->error(), "\n";
system("/usr/bin/systemctl daemon-reload");
system("/usr/bin/systemctl enable $unit_name\@$vmid.service");
}
system("/usr/bin/systemctl start $unit_name\@$vmid.service");
$vfs_args .= " -chardev socket,id=char$char_id,path=/run/virtiofsd/$vmid-$share_id.sock";
$vfs_args .= " -device vhost-user-fs-pci,chardev=char$char_id,tag=$share_id";
$char_id += 1;
}
open(FH, '>', $vfs_args_file) or die $!;
print FH $vfs_args;
close(FH);
print $vfs_args . "\n";
if (defined($conf->{args}) && not $conf->{args} =~ /$vfs_args/) {
print "Appending virtiofs arguments to VM args.\n";
$conf->{args} .= " $vfs_args";
} else {
print "Setting VM args to generated virtiofs arguments.\n";
$conf->{args} = " $vfs_args";
}
PVE::QemuConfig->write_config($vmid, $conf);
}
elsif($phase eq 'post-start') {
print "$vmid started successfully.\n";
my $vfs_args = do {
local $/ = undef;
open my $fh, "<", $vfs_args_file or die $!;
<$fh>;
};
if ($conf->{args} =~ /$vfs_args/) {
print "Removing virtiofs arguments from VM args.\n";
$conf->{args} =~ s/\ *$vfs_args//g;
print $conf->{args};
$conf->{args} = undef if $conf->{args} =~ /^$/;
PVE::QemuConfig->write_config($vmid, $conf);
}
}
elsif($phase eq 'pre-stop') {
#print "$vmid will be stopped.\n";
}
elsif($phase eq 'post-stop') {
#print "$vmid stopped. Doing cleanup.\n";
} else {
die "got unknown phase '$phase'\n";
}
exit(0);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment