all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Fabian Ebner <f.ebner@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [pve-devel] [PATCH v2 qemu-server 7/7] restore: allow preserving drives during restore
Date: Thu, 21 Apr 2022 13:26:55 +0200	[thread overview]
Message-ID: <20220421112659.74011-10-f.ebner@proxmox.com> (raw)
In-Reply-To: <20220421112659.74011-1-f.ebner@proxmox.com>

Preserving a drive means:
  * The disk it references will not be touched by the restore
    operation.
  * The drive will be left as is in the VM configuration.
  * If the drive is present in the backup, that disk will not be
    restored.

A drive that is not present in the backup was/is re-added as unused by
default, but when preserving, it's kept configured instead.

If a drive is not currently configured and passed as part of preserve,
restore is skipped and its entry in the restored config will be
removed.

Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
---

Dependency bump for pve-qemu is needed.

Changes from v1:
  * Allow skipping restore of drive that's not currently configured
    (see below).
  * Adapt to skip=<devname> syntax when passing drive map to VMA.
  * When merging configs, remove key from the final config if value
    is explicitly undef.
  * Add 'preserve-drives' parameter instead of treating passing
    existing disk in a special way. While this makes it less
    flexible, the advantages are:
      * Can be used to skip restoring a disk that's not currently
        configured.
      * Less automagic behavior, it might not be intuitive what
        passing existing disk will do.
      * No conflict with currently existing syntax for containers.
      * No need to specify the disk's options again. The disk will
        be preserved like it's currently in the config.

 PVE/API2/Qemu.pm  | 25 ++++++++++++++++++++++++-
 PVE/QemuServer.pm | 34 +++++++++++++++++++++++++++++++---
 2 files changed, 55 insertions(+), 4 deletions(-)

diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm
index 8df2cc8d..86359cef 100644
--- a/PVE/API2/Qemu.pm
+++ b/PVE/API2/Qemu.pm
@@ -749,6 +749,14 @@ __PACKAGE__->register_method({
 		    description => "Start the VM immediately from the backup and restore in background. PBS only.",
 		    requires => 'archive',
 		},
+		'preserve-drives' => {
+		    optional => 1,
+		    type => 'string',
+		    format => 'pve-configid-list',
+		    description => "List of drives (e.g. scsi0) for which to preserve the current ".
+			"configuration and disk contents.",
+		    requires => 'archive',
+		},
 		pool => {
 		    optional => 1,
 		    type => 'string', format => 'pve-poolid',
@@ -793,6 +801,7 @@ __PACKAGE__->register_method({
 	my $storage = extract_param($param, 'storage');
 	my $unique = extract_param($param, 'unique');
 	my $live_restore = extract_param($param, 'live-restore');
+	my $preserve_drives = extract_param($param, 'preserve-drives');
 
 	if (defined(my $ssh_keys = $param->{sshkeys})) {
 		$ssh_keys = URI::Escape::uri_unescape($ssh_keys);
@@ -825,10 +834,18 @@ __PACKAGE__->register_method({
 	if ($archive) {
 	    for my $opt (sort keys $param->%*) {
 		if (PVE::QemuServer::Drive::is_valid_drivename($opt)) {
-		    raise_param_exc({ $opt => "option conflicts with option 'archive'" });
+		    raise_param_exc({
+			$opt => "option conflicts with option 'archive' (do you mean to use ".
+			    "'preserve-drives'?)",
+		    });
 		}
 	    }
 
+	    for my $opt (PVE::Tools::split_list($preserve_drives)) {
+		raise_param_exc({ 'preserve-drives' => "$opt - not a drive key" })
+		    if !PVE::QemuServer::Drive::is_valid_drivename($opt);
+	    }
+
 	    if ($archive eq '-') {
 		die "pipe requires cli environment\n" if $rpcenv->{type} ne 'cli';
 		$archive = { type => 'pipe' };
@@ -876,6 +893,12 @@ __PACKAGE__->register_method({
 
 	    die "$emsg vm is running\n" if PVE::QemuServer::check_running($vmid);
 
+	    for my $opt (PVE::Tools::split_list($preserve_drives)) {
+		die "internal error - expected drive key\n"
+		    if !PVE::QemuServer::Drive::is_valid_drivename($opt);
+		$param->{$opt} = $conf->{$opt};
+	    }
+
 	    my $realcmd = sub {
 		my $restore_options = {
 		    storage => $storage,
diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index e64a9c7a..affdd0bb 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -6206,6 +6206,15 @@ sub tar_restore_cleanup {
     }
 }
 
+# Possilbe options are
+# $format: archive format
+# $storage: target storage
+# $pool: add VM to this pool
+# $unique: make VM unique (mac addressses, vmgenid)
+# $bwlimit: limit restore speed
+# $live: live restore (PBS only)
+# $override_conf: Settings that will be overwritten. If a key is explicitly set to undef, it will be
+#     deleted from the final config. Drives whose keys appear in this config are not restored.
 sub restore_file_archive {
     my ($archive, $vmid, $user, $opts) = @_;
 
@@ -6309,6 +6318,8 @@ my $parse_backup_hints = sub {
 	    $devinfo->{$devname}->{format} = $format;
 	    $devinfo->{$devname}->{storeid} = $storeid;
 
+	    next if exists($options->{override_conf}->{$virtdev}); # not being restored
+
 	    my $scfg = PVE::Storage::storage_config($storecfg, $storeid);
 	    $check_storage->($storeid, $scfg); # permission and content type check
 
@@ -6481,7 +6492,11 @@ my $restore_merge_config = sub {
 
     my $backup_conf = parse_vm_config($filename, $backup_conf_raw);
     for my $key (keys $override_conf->%*) {
-	$backup_conf->{$key} = $override_conf->{$key};
+	if (defined($override_conf->{$key})) {
+	    $backup_conf->{$key} = $override_conf->{$key};
+	} else {
+	    delete $backup_conf->{$key};
+	}
     }
 
     return $backup_conf;
@@ -6818,6 +6833,12 @@ sub restore_proxmox_backup_archive {
 	# these special drives are already restored before start
 	delete $devinfo->{'drive-efidisk0'};
 	delete $devinfo->{'drive-tpmstate0-backup'};
+
+	for my $key (keys $options->{override_conf}->%*) {
+	    next if !is_valid_drivename($key);
+	    delete $devinfo->{"drive-$key"};
+	}
+
 	pbs_live_restore($vmid, $conf, $storecfg, $devinfo, $repo, $keyfile, $pbs_backup_name);
 
 	PVE::QemuConfig->remove_lock($vmid, "create");
@@ -7010,8 +7031,15 @@ sub restore_vma_archive {
 	my $map = $restore_allocate_devices->($cfg, $virtdev_hash, $vmid);
 
 	# print restore information to $fifofh
-	foreach my $virtdev (sort keys %$virtdev_hash) {
-	    my $d = $virtdev_hash->{$virtdev};
+	for my $devname (sort keys $devinfo->%*) {
+	    my $d = $devinfo->{$devname};
+
+	    if (!$virtdev_hash->{$d->{virtdev}}) { # skipped
+		print $fifofh "skip=$d->{devname}\n";
+		print "not restoring '$d->{devname}', but keeping current disk\n";
+		next;
+	    }
+
 	    next if $d->{is_cloudinit}; # no need to restore cloudinit
 
 	    my $storeid = $d->{storeid};
-- 
2.30.2





  parent reply	other threads:[~2022-04-21 11:27 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-21 11:26 [pve-devel] [PATCH-SERIES v2 qemu/qemu-server/widget-toolkit/manager] more flexible restore Fabian Ebner
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu 1/2] vma: restore: call blk_unref for all opened block devices Fabian Ebner
2022-04-25  6:37   ` Wolfgang Bumiller
2022-04-25 16:10   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu 2/2] vma: allow partial restore Fabian Ebner
2022-04-25  6:40   ` Wolfgang Bumiller
2022-04-25 16:10   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 1/7] restore: cleanup oldconf: also clean up snapshots from kept volumes Fabian Ebner
2022-04-25 16:20   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 2/7] restore destroy volumes: remove check for absolute path Fabian Ebner
2022-04-25 16:20   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 3/7] restore deactivate volumes: never die Fabian Ebner
2022-04-23  9:18   ` Thomas Lamprecht
2022-04-25  6:45     ` Fabian Ebner
2022-04-25 16:21   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 4/7] restore: also deactivate/destroy cloud-init disk upon error Fabian Ebner
2022-04-25 16:21   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 5/7] api: create: refactor parameter check logic Fabian Ebner
2022-04-21 11:26 ` [pve-devel] [PATCH v2 qemu-server 6/7] api: create: allow overriding non-disk options during restore Fabian Ebner
2022-04-21 11:26 ` Fabian Ebner [this message]
2022-04-21 11:26 ` [pve-devel] [PATCH v2 widget-toolkit 1/1] css: add proxmox-good-row class Fabian Ebner
2022-04-23  8:32   ` [pve-devel] applied: " Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 manager 1/3] ui: restore: disallow empty storage selection if it wouldn't work Fabian Ebner
2022-04-23  9:38   ` Thomas Lamprecht
2022-04-25  7:28     ` Fabian Ebner
2022-04-27  7:05       ` Thomas Lamprecht
2022-04-27  8:21         ` Fabian Ebner
2022-04-21 11:26 ` [pve-devel] [PATCH v2 manager 2/3] ui: restore: allow override of some settings Fabian Ebner
2022-04-23 10:07   ` Thomas Lamprecht
2022-04-21 11:26 ` [pve-devel] [PATCH v2 manager 3/3] ui: restore: allow preserving disks Fabian Ebner

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=20220421112659.74011-10-f.ebner@proxmox.com \
    --to=f.ebner@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