On March 11, 2020 11:44 am, Mira Limbeck wrote: > The reuse of the tunnel, which we're opening to communicate with the target > node and to forward the unix socket for the state migration, for the NBD unix > socket requires adding support for an array of sockets to forward, not just a > single one. We also have to change the $sock_addr variable to an array > for the cleanup of the socket file as SSH does not remove the file. > > To communicate to the target node the support of unix sockets for NBD > storage migration, we're specifying an nbd_protocol_version which is set > to 1. This version is then passed to the target node via STDIN. For this > we always have to pass either the spice ticket followed by a newline, or > just a newline if no spice ticket is defined. Otherwise the target side > would assume the 'nbd_protocol_version: 1' line to be the spice ticket. > > When the NBD server on the target node is started with a unix socket, we > get a different line containing all the information required to start > the drive-mirror. This contains the unix socket path used on the target node > which we require for forwarding and cleanup. > > Signed-off-by: Mira Limbeck <m.limb...@proxmox.com> > --- > PVE/QemuMigrate.pm | 32 +++++++++++++++++++++++++++----- > 1 file changed, 27 insertions(+), 5 deletions(-) > > diff --git a/PVE/QemuMigrate.pm b/PVE/QemuMigrate.pm > index e569a2c..a52746c 100644 > --- a/PVE/QemuMigrate.pm > +++ b/PVE/QemuMigrate.pm > @@ -142,7 +142,10 @@ sub write_tunnel { > sub fork_tunnel { > my ($self, $tunnel_addr) = @_; > > - my @localtunnelinfo = defined($tunnel_addr) ? ('-L' , $tunnel_addr ) : > (); > + my @localtunnelinfo = (); > + foreach my $addr (@$tunnel_addr) { > + push @localtunnelinfo, '-L', $addr; > + } > > my $cmd = [@{$self->{rem_ssh}}, '-o ExitOnForwardFailure=yes', > @localtunnelinfo, '/usr/sbin/qm', 'mtunnel' ]; > > @@ -184,7 +187,7 @@ sub finish_tunnel { > > if ($tunnel->{sock_addr}) { > # ssh does not clean up on local host > - my $cmd = ['rm', '-f', $tunnel->{sock_addr}]; # > + my $cmd = ['rm', '-f', @{$tunnel->{sock_addr}}]; # > PVE::Tools::run_command($cmd); > > # .. and just to be sure check on remote side > @@ -594,10 +597,16 @@ sub phase2 { > } > > my $spice_port; > + my $tunnel_addr = []; > + my $sock_addr = []; > + # version > 0 for unix socket support > + my $nbd_protocol_version = 1; > + my $input = $spice_ticket ? "$spice_ticket\n" : "\n"; > + $input .= "nbd_protocol_version: $nbd_protocol_version\n"; > > # Note: We try to keep $spice_ticket secret (do not pass via command > line parameter) > # instead we pipe it through STDIN > - my $exitcode = PVE::Tools::run_command($cmd, input => $spice_ticket, > outfunc => sub { > + my $exitcode = PVE::Tools::run_command($cmd, input => $input, outfunc => > sub { > my $line = shift; > > if ($line =~ m/^migration listens on > tcp:(localhost|[\d\.]+|\[[\d\.:a-fA-F]+\]):(\d+)$/) { > @@ -626,7 +635,18 @@ sub phase2 { > > $self->{target_drive}->{$targetdrive}->{drivestr} = $drivestr; > $self->{target_drive}->{$targetdrive}->{nbd_uri} = $nbd_uri; > + } elsif ($line =~ m!^storage migration listens on > nbd:unix:(/run/qemu-server/(\d+)_nbd\.migrate):exportname=(\S+) > volume:(\S+)$!) { > + my $drivestr = $4; > + die "Destination UNIX socket's VMID does not match source VMID" if > $vmid ne $2; > + my $nbd_unix_addr = $1; > + my $nbd_uri = "nbd:unix:$nbd_unix_addr:exportname=$3"; > + my $targetdrive = $3; > + $targetdrive =~ s/drive-//g; > > + $self->{target_drive}->{$targetdrive}->{drivestr} = $drivestr; > + $self->{target_drive}->{$targetdrive}->{nbd_uri} = $nbd_uri; > + push @$tunnel_addr, "$nbd_unix_addr:$nbd_unix_addr"; > + push @$sock_addr, $nbd_unix_addr; > } elsif ($line =~ m/^QEMU: (.*)$/) { > $self->log('info', "[$self->{node}] $1\n"); > } > @@ -645,8 +665,9 @@ sub phase2 { > > if ($ruri =~ /^unix:/) { > unlink $raddr; > - $self->{tunnel} = $self->fork_tunnel("$raddr:$raddr"); > - $self->{tunnel}->{sock_addr} = $raddr; > + push @$tunnel_addr, "$raddr:$raddr"; > + $self->{tunnel} = $self->fork_tunnel($tunnel_addr); > + push @$sock_addr, $raddr; > > my $unix_socket_try = 0; # wait for the socket to become ready > while (! -S $raddr) {
are we sure we don't need to wait for all (UNIX) sockets to become ready here? > @@ -678,6 +699,7 @@ sub phase2 { > #fork tunnel for insecure migration, to send faster commands like resume > $self->{tunnel} = $self->fork_tunnel(); > } > + $self->{tunnel}->{sock_addr} = $sock_addr if (@$sock_addr); > > my $start = time(); > > -- > 2.20.1 > > > _______________________________________________ > pve-devel mailing list > pve-devel@pve.proxmox.com > https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > _______________________________________________ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel