all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Daniel Kral <d.kral@proxmox.com>
To: Proxmox VE development discussion <pve-devel@lists.proxmox.com>,
	Markus Frank <m.frank@proxmox.com>
Subject: Re: [pve-devel] [PATCH qemu-server v15 5/7] fix #1027: virtio-fs support
Date: Fri, 4 Apr 2025 14:19:48 +0200	[thread overview]
Message-ID: <1ff32e70-b85b-429f-95f8-33ce469a7a22@proxmox.com> (raw)
In-Reply-To: <20250403103442.136958-6-m.frank@proxmox.com>

Some comments inline about undefined values.

Also two small notes about testing the assertions, which both works as 
expected (die for Windows + POSIX ACLs and memory hotplug + virtiofs).

On 4/3/25 12:34, Markus Frank wrote:
> add support for sharing directories with a guest vm.
> 
> virtio-fs needs virtiofsd to be started.
> In order to start virtiofsd as a process (despite being a daemon it is
> does not run in the background), a double-fork is used.
> 
> virtiofsd should close itself together with QEMU.
> 
> There are the parameters dirid and the optional parameters direct-io,
> cache and writeback. Additionally the expose-xattr & expose-acl
> parameter can be set to expose xattr & acl settings from the shared
> filesystem to the guest system.
> 
> The dirid gets mapped to the path on the current node and is also used
> as a mount tag (name used to mount the device on the guest).
> 
> example config:
> ```
> virtiofs0: foo,direct-io=1,cache=always,expose-acl=1
> virtiofs1: dirid=bar,cache=never,expose-xattr=1,writeback=1
> ```
> 
> For information on the optional parameters see the coherent doc patch
> and the official gitlab README:
> https://gitlab.com/virtio-fs/virtiofsd/-/blob/main/README.md
> 
> Also add a permission check for virtiofs directory access.
> 
> Signed-off-by: Markus Frank <m.frank@proxmox.com>
> ---
> v15:
> * removed announce-submounts option altogether and always set it for
>   virtiofsd
> * added die if both memory hotplug and virtiofs are enabled
> * changed parameter order of PVE::QemuServer::Memory::config so that
>   $cmd and $machine_flags are last.
>   * die instead of warn in assert_virtiofs_config when acl is enabled for
>   a windows VM
> 
>   PVE/API2/Qemu.pm           |  41 +++++++-
>   PVE/QemuServer.pm          |  29 ++++-
>   PVE/QemuServer/Makefile    |   3 +-
>   PVE/QemuServer/Memory.pm   |  25 +++--
>   PVE/QemuServer/Virtiofs.pm | 209 +++++++++++++++++++++++++++++++++++++
>   5 files changed, 296 insertions(+), 11 deletions(-)
>   create mode 100644 PVE/QemuServer/Virtiofs.pm
> 
> diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
> index 156b1c7b..5a695306 100644
> --- a/PVE/API2/Qemu.pm
> +++ b/PVE/API2/Qemu.pm
> @@ -39,6 +39,7 @@ use PVE::QemuServer::MetaInfo;
>   use PVE::QemuServer::PCI;
>   use PVE::QemuServer::QMPHelpers;
>   use PVE::QemuServer::USB;
> +use PVE::QemuServer::Virtiofs qw(max_virtiofs);
>   use PVE::QemuMigrate;
>   use PVE::RPCEnvironment;
>   use PVE::AccessControl;
> @@ -803,6 +804,33 @@ my sub check_vm_create_hostpci_perm {
>       return 1;
>   };
>   
> +my sub check_dir_perm {
> +    my ($rpcenv, $authuser, $vmid, $pool, $opt, $value) = @_;
> +
> +    return 1 if $authuser eq 'root@pam';
> +
> +    $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Disk']);
> +
> +    my $virtiofs = PVE::JSONSchema::parse_property_string('pve-qm-virtiofs', $value);
> +    $rpcenv->check_full($authuser, "/mapping/dir/$virtiofs->{dirid}", ['Mapping.Use']);
> +
> +    return 1;
> +};
> +
> +my sub check_vm_create_dir_perm {
> +    my ($rpcenv, $authuser, $vmid, $pool, $param) = @_;
> +
> +    return 1 if $authuser eq 'root@pam';
> +
> +    for (my $i = 0; $i < max_virtiofs(); $i++) {
> +	my $opt = "virtiofs$i";
> +	next if !$param->{$opt};
> +	check_dir_perm($rpcenv, $authuser, $vmid, $pool, $opt, $param->{$opt});
> +    }
> +
> +    return 1;
> +};
> +
>   my $check_vm_modify_config_perm = sub {
>       my ($rpcenv, $authuser, $vmid, $pool, $key_list) = @_;
>   
> @@ -813,7 +841,7 @@ my $check_vm_modify_config_perm = sub {
>   	# else, as there the permission can be value dependent
>   	next if PVE::QemuServer::is_valid_drivename($opt);
>   	next if $opt eq 'cdrom';
> -	next if $opt =~ m/^(?:unused|serial|usb|hostpci)\d+$/;
> +	next if $opt =~ m/^(?:unused|serial|usb|hostpci|virtiofs)\d+$/;
>   	next if $opt eq 'tags';
>   
>   
> @@ -1116,6 +1144,7 @@ __PACKAGE__->register_method({
>   	    &$check_vm_create_serial_perm($rpcenv, $authuser, $vmid, $pool, $param);
>   	    check_vm_create_usb_perm($rpcenv, $authuser, $vmid, $pool, $param);
>   	    check_vm_create_hostpci_perm($rpcenv, $authuser, $vmid, $pool, $param);
> +	    check_vm_create_dir_perm($rpcenv, $authuser, $vmid, $pool, $param);
>   
>   	    PVE::QemuServer::check_bridge_access($rpcenv, $authuser, $param);
>   	    &$check_cpu_model_access($rpcenv, $authuser, $param);
> @@ -2007,6 +2036,10 @@ my $update_vm_api  = sub {
>   		    check_hostpci_perm($rpcenv, $authuser, $vmid, undef, $opt, $val);
>   		    PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
>   		    PVE::QemuConfig->write_config($vmid, $conf);
> +		} elsif ($opt =~ m/^virtiofs\d$/) {
> +		    check_dir_perm($rpcenv, $authuser, $vmid, undef, $opt, $val);
> +		    PVE::QemuConfig->add_to_pending_delete($conf, $opt, $force);
> +		    PVE::QemuConfig->write_config($vmid, $conf);
>   		} elsif ($opt eq 'tags') {
>   		    assert_tag_permissions($vmid, $val, '', $rpcenv, $authuser);
>   		    delete $conf->{$opt};
> @@ -2097,6 +2130,12 @@ my $update_vm_api  = sub {
>   		    }
>   		    check_hostpci_perm($rpcenv, $authuser, $vmid, undef, $opt, $param->{$opt});
>   		    $conf->{pending}->{$opt} = $param->{$opt};
> +		} elsif ($opt =~ m/^virtiofs\d$/) {
> +		    if (my $oldvalue = $conf->{$opt}) {
> +			check_dir_perm($rpcenv, $authuser, $vmid, undef, $opt, $oldvalue);
> +		    }
> +		    check_dir_perm($rpcenv, $authuser, $vmid, undef, $opt, $param->{$opt});
> +		    $conf->{pending}->{$opt} = $param->{$opt};
>   		} elsif ($opt eq 'tags') {
>   		    assert_tag_permissions($vmid, $conf->{$opt}, $param->{$opt}, $rpcenv, $authuser);
>   		    $conf->{pending}->{$opt} = PVE::GuestHelpers::get_unique_tags($param->{$opt});
> diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
> index ffd5d56b..558b924d 100644
> --- a/PVE/QemuServer.pm
> +++ b/PVE/QemuServer.pm
> @@ -33,6 +33,7 @@ use PVE::Exception qw(raise raise_param_exc);
>   use PVE::Format qw(render_duration render_bytes);
>   use PVE::GuestHelpers qw(safe_string_ne safe_num_ne safe_boolean_ne);
>   use PVE::HA::Config;
> +use PVE::Mapping::Dir;
>   use PVE::Mapping::PCI;
>   use PVE::Mapping::USB;
>   use PVE::INotify;
> @@ -62,6 +63,7 @@ use PVE::QemuServer::Monitor qw(mon_cmd);
>   use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr print_pcie_root_port parse_hostpci);
>   use PVE::QemuServer::QMPHelpers qw(qemu_deviceadd qemu_devicedel qemu_objectadd qemu_objectdel);
>   use PVE::QemuServer::USB;
> +use PVE::QemuServer::Virtiofs qw(max_virtiofs start_all_virtiofsd);
>   
>   my $have_sdn;
>   eval {
> @@ -948,6 +950,10 @@ my $netdesc = {
>   
>   PVE::JSONSchema::register_standard_option("pve-qm-net", $netdesc);
>   
> +for (my $i = 0; $i < max_virtiofs(); $i++)  {
> +    $confdesc->{"virtiofs$i"} = get_standard_option('pve-qm-virtiofs');
> +}
> +
>   my $ipconfig_fmt = {
>       ip => {
>   	type => 'string',
> @@ -3707,8 +3713,18 @@ sub config_to_command {
>   	push @$cmd, get_cpu_options($conf, $arch, $kvm, $kvm_off, $machine_version, $winversion, $gpu_passthrough);
>       }
>   
> +    my $virtiofs_enabled = PVE::QemuServer::Virtiofs::virtiofs_enabled($conf);
> +
>       PVE::QemuServer::Memory::config(
> -	$conf, $vmid, $sockets, $cores, $hotplug_features->{memory}, $cmd);
> +	$conf,
> +	$vmid,
> +	$sockets,
> +	$cores,
> +	$hotplug_features->{memory},
> +	$virtiofs_enabled,
> +	$cmd,
> +	$machineFlags,
> +    );
>   
>       push @$cmd, '-S' if $conf->{freeze};
>   
> @@ -3998,6 +4014,8 @@ sub config_to_command {
>   	push @$machineFlags, 'confidential-guest-support=sev0';
>       }
>   
> +    PVE::QemuServer::Virtiofs::config($conf, $vmid, $devices);
> +

If a VM has a virtiofs in its config, which does only define a dir 
mapping for other nodes than the current one the VM should start on, 
then this will fail with a rather weird error message on start:

Use of uninitialized value $path in pattern match (m//) at 
/usr/share/perl5/PVE/Mapping/Dir.pm line 51.
TASK ERROR: directory mapping invalid: Value does not look like a valid 
absolute path. These symbols are currently not allowed in path: ;,=()

This is because in config() it calls assert_virtiofs_config(), but the 
find_on_current_node() will return undef and therefore results in 
assert_valid() having an undef value to check against the regex.

Since it does make sense to allow VMs to have virtiofs configured with 
only specific nodes having a dir mapping, it would be great to improve 
this when the VM is started on a node, where there is no dir mapping on 
the current node, that it either drops the virtiofs config or errors out 
entirely.

>       push @$cmd, @$devices;
>       push @$cmd, '-rtc', join(',', @$rtcFlags) if scalar(@$rtcFlags);
>       push @$cmd, '-machine', join(',', @$machineFlags) if scalar(@$machineFlags);
> @@ -5806,6 +5824,8 @@ sub vm_start_nolock {
>   	PVE::Tools::run_fork sub {
>   	    PVE::Systemd::enter_systemd_scope($vmid, "Proxmox VE VM $vmid", %systemd_properties);
>   
> +	    my $virtiofs_sockets = start_all_virtiofsd($conf, $vmid);
> +
>   	    my $tpmpid;
>   	    if ((my $tpm = $conf->{tpmstate0}) && !PVE::QemuConfig->is_template($conf)) {
>   		# start the TPM emulator so QEMU can connect on start
> @@ -5813,6 +5833,8 @@ sub vm_start_nolock {
>   	    }
>   
>   	    my $exitcode = run_command($cmd, %run_params);
> +	    eval { PVE::QemuServer::Virtiofs::close_sockets(@$virtiofs_sockets); };
> +	    log_warn("closing virtiofs sockets failed - $@") if $@;
>   	    if ($exitcode) {
>   		if ($tpmpid) {
>   		    warn "stopping swtpm instance (pid $tpmpid) due to QEMU startup error\n";
> @@ -6485,7 +6507,10 @@ sub check_mapping_access {
>   	    } else {
>   		die "either 'host' or 'mapping' must be set.\n";
>   	    }
> -       }
> +	} elsif ($opt =~ m/^virtiofs\d$/) {
> +	    my $virtiofs = PVE::JSONSchema::parse_property_string('pve-qm-virtiofs', $conf->{$opt});
> +	    $rpcenv->check_full($user, "/mapping/dir/$virtiofs->{dirid}", ['Mapping.Use']);
> +	}
>      }
>   };
>   
> diff --git a/PVE/QemuServer/Makefile b/PVE/QemuServer/Makefile
> index 18fd13ea..3588e0e1 100644
> --- a/PVE/QemuServer/Makefile
> +++ b/PVE/QemuServer/Makefile
> @@ -11,7 +11,8 @@ SOURCES=PCI.pm		\
>   	CPUConfig.pm	\
>   	CGroup.pm	\
>   	Drive.pm	\
> -	QMPHelpers.pm
> +	QMPHelpers.pm	\
> +	Virtiofs.pm
>   
>   .PHONY: install
>   install: ${SOURCES}
> diff --git a/PVE/QemuServer/Memory.pm b/PVE/QemuServer/Memory.pm
> index e5024cd2..1111410a 100644
> --- a/PVE/QemuServer/Memory.pm
> +++ b/PVE/QemuServer/Memory.pm
> @@ -336,7 +336,7 @@ sub qemu_memdevices_list {
>   }
>   
>   sub config {
> -    my ($conf, $vmid, $sockets, $cores, $hotplug, $cmd) = @_;
> +    my ($conf, $vmid, $sockets, $cores, $hotplug, $virtiofs_enabled, $cmd, $machine_flags) = @_;
>   
>       my $memory = get_current_memory($conf->{memory});
>       my $static_memory = 0;
> @@ -367,6 +367,9 @@ sub config {
>   
>       die "numa needs to be enabled to use hugepages" if $conf->{hugepages} && !$conf->{numa};
>   
> +    die "Memory hotplug does not work in combination with virtio-fs.\n"
> +	if $hotplug && $virtiofs_enabled;

note: Ran into this accidentally as one of my VMs had this enabled 
before, works as expected.

> +
>       if ($conf->{numa}) {
>   
>   	my $numa_totalmemory = undef;
> @@ -379,7 +382,8 @@ sub config {
>   	    my $numa_memory = $numa->{memory};
>   	    $numa_totalmemory += $numa_memory;
>   
> -	    my $mem_object = print_mem_object($conf, "ram-node$i", $numa_memory);
> +	    my $memdev = $virtiofs_enabled ? "virtiofs-mem$i" : "ram-node$i";
> +	    my $mem_object = print_mem_object($conf, $memdev, $numa_memory);
>   
>   	    # cpus
>   	    my $cpulists = $numa->{cpus};
> @@ -404,7 +408,7 @@ sub config {
>   	    }
>   
>   	    push @$cmd, '-object', $mem_object;
> -	    push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
> +	    push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=$memdev";
>   	}
>   
>   	die "total memory for NUMA nodes must be equal to vm static memory\n"
> @@ -418,15 +422,20 @@ sub config {
>   		die "host NUMA node$i doesn't exist\n"
>   		    if !host_numanode_exists($i) && $conf->{hugepages};
>   
> -		my $mem_object = print_mem_object($conf, "ram-node$i", $numa_memory);
> -		push @$cmd, '-object', $mem_object;
> -
>   		my $cpus = ($cores * $i);
>   		$cpus .= "-" . ($cpus + $cores - 1) if $cores > 1;
>   
> -		push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=ram-node$i";
> +		my $memdev = $virtiofs_enabled ? "virtiofs-mem$i" : "ram-node$i";
> +		my $mem_object = print_mem_object($conf, $memdev, $numa_memory);
> +		push @$cmd, '-object', $mem_object;
> +		push @$cmd, '-numa', "node,nodeid=$i,cpus=$cpus,memdev=$memdev";
>   	    }
>   	}
> +    } elsif ($virtiofs_enabled) {
> +	# kvm: '-machine memory-backend' and '-numa memdev' properties are mutually exclusive
> +	push @$cmd, '-object', 'memory-backend-memfd,id=virtiofs-mem'
> +	    .",size=$conf->{memory}M,share=on";
> +	push @$machine_flags, 'memory-backend=virtiofs-mem';
>       }
>   
>       if ($hotplug) {
> @@ -453,6 +462,8 @@ sub print_mem_object {
>   	my $path = hugepages_mount_path($hugepages_size);
>   
>   	return "memory-backend-file,id=$id,size=${size}M,mem-path=$path,share=on,prealloc=yes";
> +    } elsif ($id =~ m/^virtiofs-mem/) {
> +	return "memory-backend-memfd,id=$id,size=${size}M,share=on";
>       } else {
>   	return "memory-backend-ram,id=$id,size=${size}M";
>       }
> diff --git a/PVE/QemuServer/Virtiofs.pm b/PVE/QemuServer/Virtiofs.pm
> new file mode 100644
> index 00000000..5b948d57
> --- /dev/null
> +++ b/PVE/QemuServer/Virtiofs.pm
> @@ -0,0 +1,209 @@
> +package PVE::QemuServer::Virtiofs;
> +
> +use strict;
> +use warnings;
> +
> +use Fcntl qw(F_GETFD F_SETFD FD_CLOEXEC);
> +use IO::Socket::UNIX;
> +use POSIX;
> +use Socket qw(SOCK_STREAM);
> +
> +use PVE::JSONSchema qw(parse_property_string);
> +use PVE::Mapping::Dir;
> +use PVE::QemuServer::Helpers;
> +use PVE::RESTEnvironment qw(log_warn);
> +
> +use base qw(Exporter);
> +
> +our @EXPORT_OK = qw(
> +max_virtiofs
> +start_all_virtiofsd
> +);
> +
> +my $MAX_VIRTIOFS = 10;
> +my $socket_path_root = "/run/qemu-server/virtiofsd";
> +
> +my $virtiofs_fmt = {
> +    'dirid' => {
> +	type => 'string',
> +	default_key => 1,
> +	description => "Mapping identifier of the directory mapping to be shared with the guest."
> +	    ." Also used as a mount tag inside the VM.",
> +	format_description => 'mapping-id',
> +	format => 'pve-configid',
> +    },
> +    'cache' => {
> +	type => 'string',
> +	description => "The caching policy the file system should use (auto, always, metadata, never).",
> +	enum => [qw(auto always metadata never)],
> +	default => "auto",
> +	optional => 1,
> +    },
> +    'direct-io' => {
> +	type => 'boolean',
> +	description => "Honor the O_DIRECT flag passed down by guest applications.",
> +	default => 0,
> +	optional => 1,
> +    },
> +    writeback => {
> +	type => 'boolean',
> +	description => "Enable writeback cache. If enabled, writes may be cached in the guest until"
> +	    ." the file is closed or an fsync is performed.",
> +	default => 0,
> +	optional => 1,
> +    },
> +    'expose-xattr' => {
> +	type => 'boolean',
> +	description => "Enable support for extended attributes for this mount.",
> +	default => 0,
> +	optional => 1,
> +    },
> +    'expose-acl' => {
> +	type => 'boolean',
> +	description => "Enable support for POSIX ACLs (enabled ACL implies xattr) for this mount.",
> +	default => 0,
> +	optional => 1,
> +    },
> +};
> +PVE::JSONSchema::register_format('pve-qm-virtiofs', $virtiofs_fmt);
> +
> +my $virtiofsdesc = {
> +    optional => 1,
> +    type => 'string', format => $virtiofs_fmt,
> +    description => "Configuration for sharing a directory between host and guest using Virtio-fs.",
> +};
> +PVE::JSONSchema::register_standard_option("pve-qm-virtiofs", $virtiofsdesc);
> +
> +sub max_virtiofs {
> +    return $MAX_VIRTIOFS;
> +}
> +
> +sub assert_virtiofs_config {
> +    my ($ostype, $virtiofs) = @_;
> +
> +    my $dir_cfg = PVE::Mapping::Dir::find_on_current_node($virtiofs->{dirid});

This is affected by $dir_cfg being undef if there is no dir mapping on 
the current node, as described in another reply.

> +
> +    my $acl = $virtiofs->{'expose-acl'};
> +    if ($acl && PVE::QemuServer::Helpers::windows_version($ostype)) {
> +	die "Please disable ACLs for virtiofs on Windows VMs, otherwise"
> +	    ." the virtiofs shared directory cannot be mounted.\n";

note: Tested this, works as expected now.

> +    }
> +
> +    eval { PVE::Mapping::Dir::assert_valid($dir_cfg) };
> +    die "directory mapping invalid: $@\n" if $@;
> +}
> +
> +sub config {
> +    my ($conf, $vmid, $devices) = @_;
> +
> +    for (my $i = 0; $i < max_virtiofs(); $i++) {
> +	my $opt = "virtiofs$i";
> +
> +	next if !$conf->{$opt};
> +	my $virtiofs = parse_property_string('pve-qm-virtiofs', $conf->{$opt});
> +
> +	assert_virtiofs_config($conf->{ostype}, $virtiofs);
> +
> +	push @$devices, '-chardev', "socket,id=virtiofs$i,path=$socket_path_root/vm$vmid-fs$i";
> +
> +	# queue-size is set 1024 because of bug with Windows guests:
> +	# https://bugzilla.redhat.com/show_bug.cgi?id=1873088
> +	# 1024 is also always used in the virtiofs documentations:
> +	# https://gitlab.com/virtio-fs/virtiofsd#examples
> +	push @$devices, '-device', 'vhost-user-fs-pci,queue-size=1024'
> +	    .",chardev=virtiofs$i,tag=$virtiofs->{dirid}";
> +    }
> +}
> +
> +sub virtiofs_enabled {
> +    my ($conf) = @_;
> +
> +    my $virtiofs_enabled = 0;
> +    for (my $i = 0; $i < max_virtiofs(); $i++) {
> +	my $opt = "virtiofs$i";
> +	next if !$conf->{$opt};
> +	parse_property_string('pve-qm-virtiofs', $conf->{$opt});
> +	$virtiofs_enabled = 1;
> +    }
> +    return $virtiofs_enabled;
> +}
> +
> +sub start_all_virtiofsd {
> +    my ($conf, $vmid) = @_;
> +    my $virtiofs_sockets = [];
> +    for (my $i = 0; $i < max_virtiofs(); $i++) {
> +	my $opt = "virtiofs$i";
> +
> +	next if !$conf->{$opt};
> +	my $virtiofs = parse_property_string('pve-qm-virtiofs', $conf->{$opt});
> +
> +	my $virtiofs_socket = start_virtiofsd($vmid, $i, $virtiofs);
> +	push @$virtiofs_sockets, $virtiofs_socket;
> +    }
> +    return $virtiofs_sockets;
> +}
> +
> +sub start_virtiofsd {
> +    my ($vmid, $fsid, $virtiofs) = @_;
> +
> +    mkdir $socket_path_root;
> +    my $socket_path = "$socket_path_root/vm$vmid-fs$fsid";
> +    unlink($socket_path);
> +    my $socket = IO::Socket::UNIX->new(
> +	Type => SOCK_STREAM,
> +	Local => $socket_path,
> +	Listen => 1,
> +    ) or die "cannot create socket - $!\n";
> +
> +    my $flags = fcntl($socket, F_GETFD, 0)
> +	or die "failed to get file descriptor flags: $!\n";
> +    fcntl($socket, F_SETFD, $flags & ~FD_CLOEXEC)
> +	or die "failed to remove FD_CLOEXEC from file descriptor\n";
> +
> +    my $dir_cfg = PVE::Mapping::Dir::find_on_current_node($virtiofs->{dirid});

This would also be affected by $dir_cfg being undef if there is no dir 
mapping on the current node.

> +
> +    my $virtiofsd_bin = '/usr/libexec/virtiofsd';
> +    my $fd = $socket->fileno();
> +    my $path = $dir_cfg->{path};
> +
> +    my $could_not_fork_err = "could not fork to start virtiofsd\n";
> +    my $pid = fork();
> +    if ($pid == 0) {
> +	POSIX::setsid();
> +	$0 = "task pve-vm$vmid-virtiofs$fsid";
> +	my $pid2 = fork();
> +	if ($pid2 == 0) {
> +	    my $cmd = [$virtiofsd_bin, "--fd=$fd", "--shared-dir=$path"];
> +	    push @$cmd, '--xattr' if $virtiofs->{'expose-xattr'};
> +	    push @$cmd, '--posix-acl' if $virtiofs->{'expose-acl'};
> +	    push @$cmd, '--announce-submounts';

note: AFAICS --announce-submounts is the default for virtiofsd, but it's 
better safe to explicitly set it here anyway.

> +	    push @$cmd, '--allow-direct-io' if $virtiofs->{'direct-io'};
> +	    push @$cmd, '--cache='.$virtiofs->{cache} if $virtiofs->{cache};
> +	    push @$cmd, '--writeback' if $virtiofs->{'writeback'};
> +	    push @$cmd, '--syslog';
> +	    exec(@$cmd);
> +	} elsif (!defined($pid2)) {
> +	    die $could_not_fork_err;
> +	} else {
> +	    POSIX::_exit(0);
> +	}
> +    } elsif (!defined($pid)) {
> +	die $could_not_fork_err;
> +    } else {
> +	waitpid($pid, 0);
> +    }
> +
> +    # return socket to keep it alive,
> +    # so that QEMU will wait for virtiofsd to start
> +    return $socket;
> +}
> +
> +sub close_sockets {
> +    my @sockets = @_;
> +    for my $socket (@sockets) {
> +	shutdown($socket, 2);
> +	close($socket);
> +    }
> +}
> +
> +1;



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


  reply	other threads:[~2025-04-04 12:20 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-03 10:34 [pve-devel] [PATCH cluster/guest-common/docs/qemu-server/manager v15 0/12] virtiofs Markus Frank
2025-04-03 10:34 ` [pve-devel] [PATCH cluster v15 1/12] add mapping/dir.cfg for resource mapping Markus Frank
2025-04-04 13:46   ` Fiona Ebner
2025-04-03 10:34 ` [pve-devel] [PATCH guest-common v15 2/12] add dir mapping section config Markus Frank
2025-04-04 12:17   ` Daniel Kral
2025-04-03 10:34 ` [pve-devel] [PATCH docs v15 3/12] add doc section for the shared filesystem virtio-fs Markus Frank
2025-04-04 12:20   ` Daniel Kral
2025-04-03 10:34 ` [pve-devel] [PATCH qemu-server v15 4/12] control: add virtiofsd as runtime dependency for qemu-server Markus Frank
2025-04-03 10:34 ` [pve-devel] [PATCH qemu-server v15 5/7] fix #1027: virtio-fs support Markus Frank
2025-04-04 12:19   ` Daniel Kral [this message]
2025-04-03 10:34 ` [pve-devel] [PATCH qemu-server v15 6/12] migration: check_local_resources for virtiofs Markus Frank
2025-04-04 12:18   ` Daniel Kral
2025-04-03 10:34 ` [pve-devel] [PATCH qemu-server v15 7/12] disable snapshot (with RAM) and hibernate with virtio-fs devices Markus Frank
2025-04-03 10:34 ` [pve-devel] [PATCH manager v15 08/12] api: add resource map api endpoints for directories Markus Frank
2025-04-03 10:34 ` [pve-devel] [PATCH manager v15 09/12] ui: add edit window for dir mappings Markus Frank
2025-04-04 12:21   ` Daniel Kral
2025-04-03 10:34 ` [pve-devel] [PATCH manager v15 10/12] ui: add resource mapping view for directories Markus Frank
2025-04-04 12:21   ` Daniel Kral
2025-04-03 10:34 ` [pve-devel] [PATCH manager v15 11/12] ui: form: add selector for directory mappings Markus Frank
2025-04-03 10:34 ` [pve-devel] [PATCH manager v15 12/12] ui: add options to add virtio-fs to qemu config Markus Frank
2025-04-04 12:21   ` Daniel Kral
2025-04-03 11:18 ` [pve-devel] [PATCH cluster/guest-common/docs/qemu-server/manager v15 0/12] virtiofs Markus Frank
2025-04-03 14:11 ` Lukas Wagner
2025-04-04  8:27 ` Lukas Wagner
2025-04-04 15:08   ` Markus Frank
2025-04-04 12:22 ` Daniel Kral

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1ff32e70-b85b-429f-95f8-33ce469a7a22@proxmox.com \
    --to=d.kral@proxmox.com \
    --cc=m.frank@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal