Skip to content

Commit

Permalink
wip: fail when out of space before copy
Browse files Browse the repository at this point in the history
  • Loading branch information
frankiejol committed Nov 2, 2023
1 parent bcce71d commit 26c44a1
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 4 deletions.
15 changes: 14 additions & 1 deletion lib/Ravada/Domain/Void.pm
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,20 @@ sub _create_volume($self, $file, $format, $data=undef) {
confess "Undefined format" if !defined $format;
if ($format =~ /iso|raw|void/) {
$data->{format} = $format;
$self->_vm->write_file($file, Dump($data)),
if ( $format eq 'raw' && $data->{capacity} && $self->is_local) {
my $capacity = Ravada::Utils::number_to_size($data->{capacity});
my ($count,$unit) = $capacity =~ /^(\d+)(\w)$/;
die "Error, I can't find count and unit from $capacity"
if !$count || !$unit;

my @cmd = ("dd","if=/dev/zero","of=$file","count=$count","bs=1$unit"
,"status=none");
my ($in, $out, $err);
run3(\@cmd, \$in, \$out, \$err);
warn "@cmd $err" if $err;
} else {
$self->_vm->write_file($file, Dump($data)),
}
} elsif ($format eq 'qcow2') {
my @cmd = ('qemu-img','create','-f','qcow2', $file, $data->{capacity});
my ($out, $err) = $self->_vm->run_command(@cmd);
Expand Down
8 changes: 8 additions & 0 deletions lib/Ravada/VM/KVM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2917,6 +2917,14 @@ sub copy_file_storage($self, $file, $storage) {
my ($name) = $vol->get_name();
my $xml = $vol->get_xml_description();
my $doc = XML::LibXML->load_xml(string => $xml);
my $vol_capacity = $vol->get_info()->{capacity};
my $pool_capacity = $sp->get_info()->{capacity};
die "Error: '$file' too big to fit in $storage ".Ravada::Utils::number_to_size($vol_capacity)." > ".Ravada::Utils::number_to_size($pool_capacity)."\n"
if $vol_capacity>$pool_capacity;
my ($format) = $doc->findnodes("/volume/target/format");
if ($format ne 'qcow2') {
die "Error: I can't copy $format on remote nodes"
Expand Down
81 changes: 81 additions & 0 deletions t/lib/Test/Ravada.pm
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ create_domain
connector
init_ldap_config
create_ram_fs
create_storage_pool
local_ips
Expand Down Expand Up @@ -1538,6 +1539,7 @@ sub clean($ldap=undef) {
_remove_old_groups_ldap();
remove_old_user_ldap();
remove_old_storage_pools();
remove_old_ram_fs();

if ($file_remote_config) {
my $config;
Expand Down Expand Up @@ -2921,4 +2923,83 @@ sub ping_backend() {
return rvd_front->ping_backend();
}

sub _dir_findmnt($dir) {
my @cmd = ("findmnt");
my ($in, $out, $err);
run3(\@cmd, \$in, \$out, \$err);

for my $line ( split /\n/,$out) {
next if $line !~ /var.tmp/;
return 1 if $line =~ /$dir/;
}
}

sub _dir_mounted($dir) {
open my $in,"<","/proc/mounts" or die $!;
while (my $line = <$in>) {
chomp $line;
my ($type,$dir_m) = split /\s+/,$line;
return 1 if $dir eq $dir_m;
}
close $in;
return _dir_findmnt($dir);
}

sub _umount_old_ram_fs() {
my $base_pool = base_pool_name();
open my $in,"<","/proc/mounts" or die $!;
while (my $line = <$in>) {
my ($dev,$dir) = split /\s+/,$line;
if ($dir =~ m{/$base_pool}) {
`umount $dir`;
}
}
}

sub _remove_old_ram_fs_dev() {
my $base_pool = base_pool_name();

opendir my $ls,"/dev" or die $!;
while (my $file = readdir $ls) {
unlink "/dev/$file" or die "$! /dev/$file"
if $file =~ /^$base_pool/;
}
closedir $ls;
}

sub remove_old_ram_fs() {
_umount_old_ram_fs();
_remove_old_ram_fs_dev();
}

sub create_ram_fs($dir=undef,$size=1024*1024) {
if (!$dir ) {
$dir = "/var/tmp/$</";
mkdir $dir if ! -e $dir;

$dir .= new_pool_name();
}
mkdir $dir if ! -e $dir;

if (_dir_mounted($dir)) {
my @cmd =("umount",$dir);
my ($in, $out, $err);
run3(\@cmd, \$in, \$out, \$err);
die $err if $err;
}

my ($name) = $dir =~ m{.*/(.*)};
my $dev = "/dev/$name";
my @cmd = ("mkfs","-q", $dev, $size);
my ($in, $out, $err);
run3(\@cmd, \$in, \$out, \$err);
die $err if $err;

@cmd = ("mount",$dev,$dir);
run3(\@cmd, \$in, \$out, \$err);
die $err if $err;

return ($dir,$size, $dev);
}

1;
83 changes: 80 additions & 3 deletions t/storage_move.t
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use strict;

use Carp qw(confess);
use Data::Dumper;
use IPC::Run3 qw(run3);
use Test::More;

use lib 't/lib';
Expand All @@ -16,9 +17,15 @@ mkdir $DIR_TMP if ! -e $DIR_TMP;

########################################################################

sub _create_storage_pool($vm) {
my $name = new_pool_name();
my $dir = "$DIR_TMP/$name";
sub _create_storage_pool($vm, $dir=undef) {

my $name;
if (!defined $dir) {
$name = new_pool_name();
$dir = "$DIR_TMP/$name";
} else {
($name) = $dir =~ m{.*/(.*)};
}
mkdir $dir if ! -e $dir;

my ($old) = grep {$_ eq $name } $vm->list_storage_pools();
Expand Down Expand Up @@ -73,6 +80,75 @@ sub test_do_not_overwrite($vm) {
rmdir($dir) or die "$! $dir";
}

sub _search_free_space($dir) {
diag($dir);
open my $mounts,"<","/proc/mounts" or die $!;
my $found;
while (my $line = <$mounts>) {
my ($type,$partition) = split /\s+/, $line;
if ($partition eq $dir) {
$found = $partition;
last;
}
}
close $mounts;
if ( $found ) {
my @cmd = ("stat","-f","-c",'%a',$found);
my ($in, $out, $err);
run3(\@cmd,\$in,\$out,\$err);
die $err if $err;
chomp $out;
my $blocks = $out;
@cmd=("stat","-f","-c",'%S',$found);
run3(\@cmd,\$in,\$out,\$err);
die $err if $err;
chomp $out;
my $size = $out;
return $size * $blocks / (1024*1024*1024);

}

my ($dir2) = $dir =~ m{(/.*)/.*};
return if !$dir2;

return _find_mount($dir2);
}

sub test_fail($vm) {
return if $< || $vm->type eq 'Void';

my ($dir,$size, $dev) = create_ram_fs();

$dir .= "/".new_pool_name();

my ($sp) = _create_storage_pool($vm, $dir);

my $domain = create_domain_v2(vm => $vm, data => 1, swap => 1 );

my $vol = $domain->add_volume( name => new_domain_name()
,size => $size
,allocation => $size*1024
,format => 'raw'
);

my $req = Ravada::Request->move_volume(
uid => user_admin->id
,id_domain => $domain->id
,volume => $vol
,storage => $sp
);

wait_request( check_error => 0, debug => 0);
like($req->error,qr/./,"Expecting $vol failed to copy to $sp")
or exit;

$domain->remove(user_admin);
`umount $dir`;
rmdir $dir or die "$! $dir";
unlink $dev or die "$! $dev";

}

sub test_move_volume($vm) {
my $domain = create_domain_v2(vm => $vm, data => 1, swap => 1 );
$domain->add_volume( name => new_domain_name().".raw"
Expand Down Expand Up @@ -154,6 +230,7 @@ for my $vm_name ( vm_names() ) {
skip $msg,10 if !$vm;

diag("test $vm_name");
test_fail($vm);
test_move_volume($vm);
test_do_not_overwrite($vm);
}
Expand Down

0 comments on commit 26c44a1

Please sign in to comment.