mirror of
https://git.proxmox.com/git/qemu-server
synced 2025-08-07 11:10:24 +00:00
add socat and unix socket for storage migration
This is a workaround for nbd infinite timeout connect Signed-off-by: Alexandre Derumier <aderumier@odiso.com>
This commit is contained in:
parent
b74cad8ae3
commit
35e4ab0498
@ -5913,13 +5913,36 @@ sub qemu_drive_mirror {
|
|||||||
|
|
||||||
my $qemu_target;
|
my $qemu_target;
|
||||||
my $format;
|
my $format;
|
||||||
|
$jobs->{"drive-$drive"} = {};
|
||||||
|
|
||||||
if($dst_volid =~ /^nbd:(localhost|[\d\.]+|\[[\d\.:a-fA-F]+\]):(\d+)/) {
|
if($dst_volid =~ /^nbd:(localhost|[\d\.]+|\[[\d\.:a-fA-F]+\]):(\d+):exportname=(\S+)/) {
|
||||||
$qemu_target = $dst_volid;
|
|
||||||
my $server = $1;
|
my $server = $1;
|
||||||
my $port = $2;
|
my $port = $2;
|
||||||
|
my $exportname = $3;
|
||||||
|
|
||||||
$format = "nbd";
|
$format = "nbd";
|
||||||
die "can't connect remote nbd server $server:$port" if !PVE::Network::tcp_ping($server, $port, 2);
|
my $unixsocket = "/run/qemu-server/$vmid.mirror-drive-$drive";
|
||||||
|
$qemu_target = "nbd+unix:///$exportname?socket=$unixsocket";
|
||||||
|
my $cmd = ['socat', "UNIX-LISTEN:$unixsocket,fork", "TCP:$server:$2,connect-timeout=1"];
|
||||||
|
|
||||||
|
my $pid = fork();
|
||||||
|
if (!defined($pid)) {
|
||||||
|
die "forking socat tunnel failed";
|
||||||
|
} elsif ($pid == 0) {
|
||||||
|
exec(@$cmd);
|
||||||
|
exit(-1);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
$jobs->{"drive-$drive"}->{pid} = $pid;
|
||||||
|
|
||||||
|
my $timeout = 0;
|
||||||
|
while (1) {
|
||||||
|
last if -S $unixsocket;
|
||||||
|
die if $timeout > 5;
|
||||||
|
$timeout++;
|
||||||
|
sleep 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
my $storecfg = PVE::Storage::config();
|
my $storecfg = PVE::Storage::config();
|
||||||
@ -5940,12 +5963,12 @@ sub qemu_drive_mirror {
|
|||||||
print "drive mirror is starting for drive-$drive\n";
|
print "drive mirror is starting for drive-$drive\n";
|
||||||
|
|
||||||
eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); }; #if a job already run for this device,it's throw an error
|
eval { vm_mon_cmd($vmid, "drive-mirror", %$opts); }; #if a job already run for this device,it's throw an error
|
||||||
|
|
||||||
if (my $err = $@) {
|
if (my $err = $@) {
|
||||||
eval { PVE::QemuServer::qemu_blockjobs_cancel($vmid, $jobs) };
|
eval { PVE::QemuServer::qemu_blockjobs_cancel($vmid, $jobs) };
|
||||||
die "mirroring error: $err";
|
die "mirroring error: $err";
|
||||||
}
|
}
|
||||||
|
|
||||||
$jobs->{"drive-$drive"} = {};
|
|
||||||
|
|
||||||
qemu_drive_mirror_monitor ($vmid, $vmiddst, $jobs, $skipcomplete);
|
qemu_drive_mirror_monitor ($vmid, $vmiddst, $jobs, $skipcomplete);
|
||||||
}
|
}
|
||||||
@ -6016,6 +6039,7 @@ sub qemu_drive_mirror_monitor {
|
|||||||
}else {
|
}else {
|
||||||
print "$job : complete ok : flushing pending writes\n";
|
print "$job : complete ok : flushing pending writes\n";
|
||||||
$jobs->{$job}->{complete} = 1;
|
$jobs->{$job}->{complete} = 1;
|
||||||
|
eval { qemu_blockjobs_finish_tunnel($vmid, $job, $jobs->{$job}->{pid}) } ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6053,6 +6077,7 @@ sub qemu_blockjobs_cancel {
|
|||||||
|
|
||||||
if(defined($jobs->{$job}->{cancel}) && !defined($running_jobs->{$job})) {
|
if(defined($jobs->{$job}->{cancel}) && !defined($running_jobs->{$job})) {
|
||||||
print "$job : finished\n";
|
print "$job : finished\n";
|
||||||
|
eval { qemu_blockjobs_finish_tunnel($vmid, $job, $jobs->{$job}->{pid}) } ;
|
||||||
delete $jobs->{$job};
|
delete $jobs->{$job};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6063,6 +6088,25 @@ sub qemu_blockjobs_cancel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub qemu_blockjobs_finish_tunnel {
|
||||||
|
my ($vmid, $job, $cpid) = @_;
|
||||||
|
|
||||||
|
return if !$cpid;
|
||||||
|
|
||||||
|
for (my $i = 1; $i < 20; $i++) {
|
||||||
|
my $waitpid = waitpid($cpid, WNOHANG);
|
||||||
|
last if (defined($waitpid) && ($waitpid == $cpid));
|
||||||
|
|
||||||
|
if ($i == 10) {
|
||||||
|
kill(15, $cpid);
|
||||||
|
} elsif ($i >= 15) {
|
||||||
|
kill(9, $cpid);
|
||||||
|
}
|
||||||
|
sleep (1);
|
||||||
|
}
|
||||||
|
unlink "/run/qemu-server/$vmid.mirror-$job";
|
||||||
|
}
|
||||||
|
|
||||||
sub clone_disk {
|
sub clone_disk {
|
||||||
my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
|
my ($storecfg, $vmid, $running, $drivename, $drive, $snapname,
|
||||||
$newvmid, $storage, $format, $full, $newvollist, $jobs, $skipcomplete) = @_;
|
$newvmid, $storage, $format, $full, $newvollist, $jobs, $skipcomplete) = @_;
|
||||||
|
Loading…
Reference in New Issue
Block a user