From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 37F6A60E5B for ; Thu, 3 Feb 2022 13:42:45 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A799626D47 for ; Thu, 3 Feb 2022 13:42:44 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id AF2D226D3D for ; Thu, 3 Feb 2022 13:42:43 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 86D4944BD4 for ; Thu, 3 Feb 2022 13:42:43 +0100 (CET) From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= To: pve-devel@lists.proxmox.com Date: Thu, 3 Feb 2022 13:41:42 +0100 Message-Id: <20220203124143.1931377-22-f.gruenbichler@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220203124143.1931377-1-f.gruenbichler@proxmox.com> References: <20220203124143.1931377-1-f.gruenbichler@proxmox.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.207 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% 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 T_SCC_BODY_TEXT_LINE -0.01 - URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [storage.pm] Subject: [pve-devel] [PATCH v4 storage 3/4] storage_migrate: pull out import/export_prepare X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Feb 2022 12:42:45 -0000 for re-use with remote migration, where import and export happen on different clusters connected via a websocket instead of SSH tunnel. Signed-off-by: Fabian Grünbichler --- Notes: v4: - unify array refs - small fixups new in v3 PVE/Storage.pm | 113 ++++++++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 43 deletions(-) diff --git a/PVE/Storage.pm b/PVE/Storage.pm index 93ae3ac..837df1b 100755 --- a/PVE/Storage.pm +++ b/PVE/Storage.pm @@ -651,16 +651,70 @@ sub storage_migrate_snapshot { return $scfg->{type} eq 'zfspool' || $scfg->{type} eq 'btrfs'; } -sub storage_migrate { - my ($cfg, $volid, $target_sshinfo, $target_storeid, $opts, $logfunc) = @_; +my $volume_import_prepare = sub { + my ($volid, $format, $path, $apiver, $opts) = @_; my $base_snapshot = $opts->{base_snapshot}; my $snapshot = $opts->{snapshot}; - my $ratelimit_bps = $opts->{ratelimit_bps}; - my $insecure = $opts->{insecure}; my $with_snapshots = $opts->{with_snapshots} ? 1 : 0; + my $migration_snapshot = $opts->{migration_snapshot} ? 1 : 0; my $allow_rename = $opts->{allow_rename} ? 1 : 0; + my $recv = ['pvesm', 'import', $volid, $format, $path, '-with-snapshots', $with_snapshots]; + if (defined($snapshot)) { + push @$recv, '-snapshot', $snapshot; + } + if ($migration_snapshot) { + push @$recv, '-delete-snapshot', $snapshot; + } + push @$recv, '-allow-rename', $allow_rename if $apiver >= 5; + + if (defined($base_snapshot)) { + # Check if the snapshot exists on the remote side: + push @$recv, '-base', $base_snapshot if $apiver >= 9; + } + + return $recv; +}; + +my $volume_export_prepare = sub { + my ($cfg, $volid, $format, $logfunc, $opts) = @_; + my $base_snapshot = $opts->{base_snapshot}; + my $snapshot = $opts->{snapshot}; + my $with_snapshots = $opts->{with_snapshots} ? 1 : 0; + my $migration_snapshot = $opts->{migration_snapshot} ? 1 : 0; + my $ratelimit_bps = $opts->{ratelimit_bps}; + + my $send = ['pvesm', 'export', $volid, $format, '-', '-with-snapshots', $with_snapshots]; + if (defined($snapshot)) { + push @$send, '-snapshot', $snapshot; + } + if (defined($base_snapshot)) { + push @$send, '-base', $base_snapshot; + } + + my $cstream; + if (defined($ratelimit_bps)) { + $cstream = [ '/usr/bin/cstream', '-t', $ratelimit_bps ]; + $logfunc->("using a bandwidth limit of $ratelimit_bps bps for transferring '$volid'") if $logfunc; + } + + volume_snapshot($cfg, $volid, $snapshot) if $migration_snapshot; + + if (defined($snapshot)) { + activate_volumes($cfg, [$volid], $snapshot); + } else { + activate_volumes($cfg, [$volid]); + } + + return $cstream ? [ $send, $cstream ] : [ $send ]; +}; + +sub storage_migrate { + my ($cfg, $volid, $target_sshinfo, $target_storeid, $opts, $logfunc) = @_; + + my $insecure = $opts->{insecure}; + my ($storeid, $volname) = parse_volume_id($volid); my $scfg = storage_config($cfg, $storeid); @@ -688,19 +742,12 @@ sub storage_migrate { my $ssh_base = PVE::SSHInfo::ssh_info_to_command_base($target_sshinfo); local $ENV{RSYNC_RSH} = PVE::Tools::cmd2string($ssh_base); - my @cstream; - if (defined($ratelimit_bps)) { - @cstream = ([ '/usr/bin/cstream', '-t', $ratelimit_bps ]); - $logfunc->("using a bandwidth limit of $ratelimit_bps bps for transferring '$volid'") if $logfunc; + if (!defined($opts->{snapshot})) { + $opts->{migration_snapshot} = storage_migrate_snapshot($cfg, $storeid); + $opts->{snapshot} = '__migration__' if $opts->{migration_snapshot}; } - my $migration_snapshot; - if (!defined($snapshot)) { - $migration_snapshot = storage_migrate_snapshot($cfg, $storeid); - $snapshot = '__migration__' if $migration_snapshot; - } - - my @formats = volume_transfer_formats($cfg, $volid, $target_volid, $snapshot, $base_snapshot, $with_snapshots); + my @formats = volume_transfer_formats($cfg, $volid, $target_volid, $opts->{snapshot}, $opts->{base_snapshot}, $opts->{with_snapshots}); die "cannot migrate from storage type '$scfg->{type}' to '$tcfg->{type}'\n" if !@formats; my $format = $formats[0]; @@ -715,22 +762,7 @@ sub storage_migrate { my $match_api_version = sub { $target_apiver = $1 if $_[0] =~ m!^APIVER (\d+)$!; }; eval { run_command($get_api_version, logfunc => $match_api_version); }; - my $send = ['pvesm', 'export', $volid, $format, '-', '-with-snapshots', $with_snapshots]; - my $recv = [@$ssh, '--', 'pvesm', 'import', $target_volid, $format, $import_fn, '-with-snapshots', $with_snapshots]; - if (defined($snapshot)) { - push @$send, '-snapshot', $snapshot; - push @$recv, '-snapshot', $snapshot; - } - if ($migration_snapshot) { - push @$recv, '-delete-snapshot', $snapshot; - } - push @$recv, '-allow-rename', $allow_rename if $target_apiver >= 5; - - if (defined($base_snapshot)) { - # Check if the snapshot exists on the remote side: - push @$send, '-base', $base_snapshot; - push @$recv, '-base', $base_snapshot if $target_apiver >= 9; - } + my $recv = [ @$ssh, '--', $volume_import_prepare->($target_volid, $format, $import_fn, $target_apiver, $opts)->@* ]; my $new_volid; my $pattern = volume_imported_message(undef, 1); @@ -745,19 +777,13 @@ sub storage_migrate { } }; - volume_snapshot($cfg, $volid, $snapshot) if $migration_snapshot; - - if (defined($snapshot)) { - activate_volumes($cfg, [$volid], $snapshot); - } else { - activate_volumes($cfg, [$volid]); - } + my $cmds = $volume_export_prepare->($cfg, $volid, $format, $logfunc, $opts); eval { if ($insecure) { my $input = IO::File->new(); my $info = IO::File->new(); - open3($input, $info, $info, @{$recv}) + open3($input, $info, $info, @$recv) or die "receive command failed: $!\n"; close($input); @@ -774,7 +800,7 @@ sub storage_migrate { # we won't be reading from the socket shutdown($socket, 0); - eval { run_command([$send, @cstream], output => '>&'.fileno($socket), errfunc => $logfunc); }; + eval { run_command($cmds, output => '>&'.fileno($socket), errfunc => $logfunc); }; my $send_error = $@; # don't close the connection entirely otherwise the receiving end @@ -795,7 +821,8 @@ sub storage_migrate { die $send_error if $send_error; } else { - run_command([$send, @cstream, $recv], logfunc => $match_volid_and_log); + push @$cmds, $recv; + run_command($cmds, logfunc => $match_volid_and_log); } die "unable to get ID of the migrated volume\n" @@ -803,8 +830,8 @@ sub storage_migrate { }; my $err = $@; warn "send/receive failed, cleaning up snapshot(s)..\n" if $err; - if ($migration_snapshot) { - eval { volume_snapshot_delete($cfg, $volid, $snapshot, 0) }; + if ($opts->{migration_snapshot}) { + eval { volume_snapshot_delete($cfg, $volid, $opts->{snapshot}, 0) }; warn "could not remove source snapshot: $@\n" if $@; } die $err if $err; -- 2.30.2