From: Shannon Sterz <s.sterz@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH manager 11/21] api: host backup: add warnings in case zfs snapdir is disabled
Date: Fri, 28 Aug 2026 15:30:20 +0200 [thread overview]
Message-ID: <20260828133030.351140-12-s.sterz@proxmox.com> (raw)
In-Reply-To: <20260828133030.351140-1-s.sterz@proxmox.com>
queries the zfs property `snapdir` and adds a warning to the logs that
backup consistency can be improved if users enable it. note that this
is mostly an additional measure, the default is 'hidden' which means
that the snapshot directory is enabled but hidden.
Signed-off-by: Shannon Sterz <s.sterz@proxmox.com>
---
PVE/API2/HostBackup.pm | 24 ++++++++++++++++++++----
PVE/HostBackupTools.pm | 13 ++++++++++++-
2 files changed, 32 insertions(+), 5 deletions(-)
diff --git a/PVE/API2/HostBackup.pm b/PVE/API2/HostBackup.pm
index 8e8a87e10..60b07773b 100644
--- a/PVE/API2/HostBackup.pm
+++ b/PVE/API2/HostBackup.pm
@@ -47,12 +47,27 @@ my sub prepare_backup($backup_name) {
if (my $mntinfo = PVE::VZDump::get_mount_info("/")) {
if ($mntinfo->{fstype} eq "zfs") {
- $snap_cmd = ['zfs', 'snapshot', $mntinfo->{device} . '@' . $backup_name];
-
# snapshots are mounted under `/.zfs/snapshots` unless snapdir is set to "disabled".
# the default is "hidden".
# https://openzfs.github.io/openzfs-docs/man/v2.4/7/zfsprops.7.html#snapdir
- $base_path = "/.zfs/snapshot/$backup_name/";
+ my $output = PVE::HostBackupTools::get_json_from_command([
+ "zfs", "get", "snapdir", "rpool/ROOT/pve-1", "-j",
+ ]);
+
+ my $snapdir_opt =
+ $output->{datasets}->{"rpool/ROOT/pve-1"}->{properties}->{snapdir}->{value};
+
+ warn "could not determine if zfs supports mounted root fs snapshots, continuing on a"
+ . " best effort basis.\n"
+ if !defined($snapdir_opt);
+
+ if ($snapdir_opt eq "disabled") {
+ warn "zfs property 'snapdir' is disabled. please enable it or set it to 'hidden'"
+ . " to allow for more consistent host backups!\n";
+ } elsif (-d "/.zfs/snapshot/") {
+ $snap_cmd = ['zfs', 'snapshot', $mntinfo->{device} . '@' . $backup_name];
+ $base_path = "/.zfs/snapshot/$backup_name/";
+ }
} elsif ($mntinfo->{fstype} eq "btrfs") {
# check if snapshots directory exists, if not create one
mkdir "/.snapshots"
@@ -171,7 +186,8 @@ my sub cleanup_backup($backup_name, $backup_target) {
if (my $mntinfo = PVE::VZDump::get_mount_info("/")) {
if ($mntinfo->{fstype} eq "zfs") {
- $snap_cmd = ['zfs', 'destroy', $mntinfo->{device} . '@' . $backup_name];
+ $snap_cmd = ['zfs', 'destroy', $mntinfo->{device} . '@' . $backup_name]
+ if -d "/.zfs/snapshot/";
} elsif ($mntinfo->{fstype} eq "btrfs") {
$snap_cmd = [
'btrfs', '-q', 'subvolume', 'delete', '--', '/.snapshots/root@' . $backup_name,
diff --git a/PVE/HostBackupTools.pm b/PVE/HostBackupTools.pm
index c51c78d9b..9ac143f8b 100644
--- a/PVE/HostBackupTools.pm
+++ b/PVE/HostBackupTools.pm
@@ -13,8 +13,19 @@ use PVE::Tools;
use PVE::Cmd qw(run);
use PVE::VZDump;
-my sub get_json_from_command($command) {
+=head3 get_json_from_command($command)
+Executes the provided C<command> using C<PVE::Cmd::run> and assumes that the
+output is valid JSON in its entirety. Output can be split across lines, but may
+not be interrupted by other text or contain more than one valid JSON array
+or object. The caller is required to make sure that the command's output conforms
+to these restrictions.
+
+Returns a parsed hash or array of the JSON output of the command.
+
+=cut
+
+sub get_json_from_command($command) {
my $json = '';
run(
--
2.47.3
next prev parent reply other threads:[~2026-08-28 13:31 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-28 13:30 [RFC cluster/common/container/docs/installer/manager 00/21] add rudimentary host backup mechanism Shannon Sterz
2026-08-28 13:30 ` [PATCH cluster 01/21] pmxcfs: status: fix formatting of parameters in checked_mkdir() Shannon Sterz
2026-08-28 13:30 ` [PATCH cluster 02/21] pmxcfs: correctly log message when directory can't be created Shannon Sterz
2026-08-28 13:30 ` [PATCH cluster 03/21] pmxcfs: add live backup capability Shannon Sterz
2026-08-28 13:30 ` [PATCH cluster 04/21] pmxcfs: add ability to query backup progress Shannon Sterz
2026-08-28 13:30 ` [PATCH common 05/21] systemd: move parse_os_release() helper to PVE::Systemd Shannon Sterz
2026-08-28 13:30 ` [PATCH container 06/21] setup: use parse_os_release from PVE::Systemd Shannon Sterz
2026-08-28 13:30 ` [PATCH manager 07/21] jobs/api: add basic host backup job logic Shannon Sterz
2026-08-28 13:30 ` [PATCH manager 08/21] api: cluster: add endpoints for manage host backup jobs Shannon Sterz
2026-08-28 13:30 ` [PATCH manager 09/21] api: node: add endpoints for listing backups for a node Shannon Sterz
2026-08-28 13:30 ` [PATCH manager 10/21] api: host backup: include global, disk and network options for restore Shannon Sterz
2026-08-28 13:30 ` Shannon Sterz [this message]
2026-08-28 13:30 ` [PATCH manager 12/21] ui: node: add panel to manage backups of a host Shannon Sterz
2026-08-28 13:30 ` [PATCH manager 13/21] ui: dc: add panel for managing host backup jobs Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 14/21] bump proxmox-installer-types to 0.2 Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 15/21] make tidy and clean up whitespace in unconfigured.sh Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 16/21] installer-common: add option to verify TLS connections via callback Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 17/21] low-level-installer: add support for restoring backups Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 18/21] installer-common/tui-installer: implement restore tui Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 19/21] unconfigured: add restore mode to unconfigured.sh Shannon Sterz
2026-08-28 13:30 ` [PATCH installer 20/21] tui-installer: unmount a potentially mounted backup on abort Shannon Sterz
2026-08-28 13:30 ` [PATCH docs 21/21] examples: add example hook script for host backup jobs Shannon Sterz
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=20260828133030.351140-12-s.sterz@proxmox.com \
--to=s.sterz@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox