From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 5B7EF1FF133 for ; Mon, 27 Apr 2026 14:19:56 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id E17B61C6AA; Mon, 27 Apr 2026 14:19:13 +0200 (CEST) From: Markus Frank To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server v3 4/11] virtiofs: add live migration support Date: Mon, 27 Apr 2026 14:16:53 +0200 Message-ID: <20260427121746.270544-5-m.frank@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260427121746.270544-1-m.frank@proxmox.com> References: <20260427121746.270544-1-m.frank@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1777292194771 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.008 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: DHNIATVARBYNTYV6FRMPCGPROF6ENZIW X-Message-ID-Hash: DHNIATVARBYNTYV6FRMPCGPROF6ENZIW X-MailFrom: m.frank@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: There are two migration methods with virtiofsd. Virtiofsd in the 'find-paths' migration mode, tries to find the path inside of the shared directory for every filesystem object that must be transferred to the destination. Add two extra parameters that verify file handles and confirm paths. In the 'file-handles' migration mode every filesystem object is converted to a file handle. This migration mode requires the DAC_READ_SEARCH capability. Add a parameter so that migration does not abort if an error occurs. Aborting on error would result in a stopped VM on the destination node. Signed-off-by: Markus Frank --- v3 changes: * removed the unnecessary 'if' around the $dirid initialisation * changed if to elsif * always start virtiofsd with '--migration-on-error=guest-error' as a safety measure src/PVE/QemuMigrate/Helpers.pm | 14 +++++++++++--- src/PVE/QemuServer/Virtiofs.pm | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/PVE/QemuMigrate/Helpers.pm b/src/PVE/QemuMigrate/Helpers.pm index 466517da..6c6294dd 100644 --- a/src/PVE/QemuMigrate/Helpers.pm +++ b/src/PVE/QemuMigrate/Helpers.pm @@ -21,7 +21,6 @@ sub check_non_migratable_resources { if ($state) { push @blockers, "amd-sev" if $conf->{"amd-sev"}; push @blockers, "intel-tdx" if $conf->{"intel-tdx"}; - push @blockers, "virtiofs" if PVE::QemuServer::Virtiofs::virtiofs_enabled($conf); } if (scalar(@blockers) && !$noerr) { @@ -100,8 +99,17 @@ sub check_local_resources { } if ($k =~ m/^virtiofs/) { my $entry = parse_property_string('pve-qm-virtiofs', $conf->{$k}); - $add_missing_mapping->('dir', $k, $entry->{dirid}); - $mapped_res->{$k} = { name => $entry->{dirid} }; + + my $dirid = $entry->{dirid}; + $add_missing_mapping->('dir', $k, $dirid); + my $mapped_device = { name => $dirid }; + $mapped_res->{$k} = $mapped_device; + + if ($dir_map->{ids}->{$dirid}->{'live-migration-method'}) { + $mapped_device->{'live-migration'} = 1; + # don't add mapped device with live migration as blocker + next; + } } # sockets are safe: they will recreated be on the target side post-migrate next if $k =~ m/^serial/ && ($conf->{$k} eq 'socket'); diff --git a/src/PVE/QemuServer/Virtiofs.pm b/src/PVE/QemuServer/Virtiofs.pm index 8567d2af..f9d7136a 100644 --- a/src/PVE/QemuServer/Virtiofs.pm +++ b/src/PVE/QemuServer/Virtiofs.pm @@ -177,6 +177,9 @@ sub start_virtiofsd { my $dir_cfg = PVE::Mapping::Dir::find_on_current_node($virtiofs->{dirid}); + my $dirid = $virtiofs->{dirid}; + my $dir_properties = PVE::Mapping::Dir::config()->{ids}->{$dirid}; + my $virtiofsd_bin = '/usr/libexec/virtiofsd'; if (!-f $virtiofsd_bin) { die "virtiofsd is not installed. To use virtio-fs, install virtiofsd via apt.\n"; @@ -201,6 +204,21 @@ sub start_virtiofsd { push @$cmd, '--readonly' if $virtiofs->{readonly}; push @$cmd, '--cache=' . $virtiofs->{cache} if $virtiofs->{cache}; push @$cmd, '--inode-file-handles=prefer' if $prefer_inode_fh; + + # migration-on-error=abort would result in a stopped VM on the target node + push @$cmd, '--migration-on-error=guest-error'; + + if (my $method = $dir_properties->{'live-migration-method'}) { + if ($method eq 'find-paths') { + push @$cmd, '--migration-mode=find-paths'; + push @$cmd, '--migration-verify-handles'; + push @$cmd, '--migration-confirm-paths'; + } elsif ($method eq 'file-handles') { + push @$cmd, '--migration-mode=file-handles'; + push @$cmd, '--modcaps=+dac_read_search'; + } + } + push @$cmd, '--syslog'; exec(@$cmd); } elsif (!defined($pid2)) { -- 2.47.3