diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 2d3bf580..dacb8d1c 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -256,6 +256,21 @@ my $vga_fmt = { }, }; +my $ivshmem_fmt = { + size => { + type => 'integer', + minimum => 1, + description => "The size of the file in MB.", + }, + name => { + type => 'string', + pattern => '[a-zA-Z0-9\-]+', + optional => 1, + format_description => 'string', + description => "The name of the file. Will be prefixed with 'pve-shm-'. Default is the VMID. Will be deleted when the VM is stopped.", + }, +}; + my $confdesc = { onboot => { optional => 1, @@ -621,6 +636,12 @@ EODESCR optional => 1, description => "Script that will be executed during various steps in the vms lifetime.", }, + ivshmem => { + type => 'string', + format => $ivshmem_fmt, + description => "Inter-VM shared memory. Useful for direct communication between VMs, or to the host.", + optional => 1, + } }; my $confdesc_cloudinit = { @@ -2808,6 +2829,8 @@ sub check_local_resources { $loc_res = 1 if $conf->{hostusb}; # old syntax $loc_res = 1 if $conf->{hostpci}; # old syntax + $loc_res = 1 if $conf->{ivshmem}; + foreach my $k (keys %$conf) { next if $k =~ m/^usb/ && ($conf->{$k} eq 'spice'); # sockets are safe: they will recreated be on the target side post-migrate @@ -3908,6 +3931,24 @@ sub config_to_command { push @$devices, '-device', $netdevicefull; } + if ($conf->{ivshmem}) { + my $ivshmem = PVE::JSONSchema::parse_property_string($ivshmem_fmt, $conf->{ivshmem}); + my $bus; + if ($q35) { + $bus = print_pcie_addr("ivshmem"); + } else { + $bus = print_pci_addr("ivshmem", $bridges, $arch, $machine_type); + } + my $path = '/dev/shm/pve-shm-'; + if ($ivshmem->{name}) { + $path .= $ivshmem->{name}; + } else { + $path .= $vmid; + } + push @$devices, '-device', "ivshmem-plain,memdev=ivshmem$bus,"; + push @$devices, '-object', "memory-backend-file,id=ivshmem,share=on,mem-path=$path,size=$ivshmem->{size}M"; + } + if (!$q35) { # add pci bridges if (qemu_machine_feature_enabled ($machine_type, $kvmver, 2, 3)) { @@ -5464,6 +5505,11 @@ sub vm_stop_cleanup { unlink "/var/run/qemu-server/${vmid}.$ext"; } + if ($conf->{ivshmem}) { + my $ivshmem = PVE::JSONSchema::parse_property_string($ivshmem_fmt, $conf->{ivshmem}); + unlink '/dev/shm/pve-shm-' . ($ivshmem->{name} // $vmid); + } + foreach my $key (keys %$conf) { next if $key !~ m/^hostpci(\d+)$/; my $hostpciindex = $1; diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm index f22f5adb..d8471460 100644 --- a/PVE/QemuServer/PCI.pm +++ b/PVE/QemuServer/PCI.pm @@ -78,6 +78,7 @@ my $devices = { 'virtio13' => { bus => 2, addr => 8 }, 'virtio14' => { bus => 2, addr => 9 }, 'virtio15' => { bus => 2, addr => 10 }, + 'ivshmem' => { bus => 2, addr => 11 }, 'virtioscsi0' => { bus => 3, addr => 1 }, 'virtioscsi1' => { bus => 3, addr => 2 }, 'virtioscsi2' => { bus => 3, addr => 3 }, @@ -150,6 +151,7 @@ sub print_pcie_addr { hostpci1bus0 => { bus => "pcie.0", addr => 17 }, hostpci2bus0 => { bus => "pcie.0", addr => 18 }, hostpci3bus0 => { bus => "pcie.0", addr => 19 }, + ivshmem => { bus => 'pcie.0', addr => 20 }, }; if (defined($devices->{$id}->{bus}) && defined($devices->{$id}->{addr})) {