Commit dbd8ac56 authored by Francesc Guasch's avatar Francesc Guasch Committed by frankiejol
Browse files

fix(nodes): shared storage detection

parent 7e2234ad
......@@ -814,6 +814,7 @@ sub prepare_base($self, $with_cd) {
confess "Undefined info->target ".Dumper($volume)
if !$volume->info->{target};
next if !defined $volume->file || !length($volume->file);
my $base = $volume->prepare_base();
push @base_img,([$base, $volume->info->{target}]);
}
......
......@@ -1467,26 +1467,6 @@ sub _read_file_local( $self, $file ) {
return join('',<$in>);
}
=head2 file_exists
Returns true if the file exists in this virtual manager storage
=cut
sub file_exists( $self, $file ) {
return -e $file if $self->is_local;
my $ssh = $self->_ssh;
confess "Error: no ssh connection to ".$self->name if ! $ssh;
confess "Error: dangerous filename '$file'"
if $file =~ /[`|"(\\\[]/;
my ($out, $err) = $self->run_command("/bin/ls -1 $file");
return 1 if !$err;
return 0;
}
=head2 remove_file
Removes a file from the storage of the virtual manager
......@@ -1752,26 +1732,51 @@ sub shutdown_domains($self) {
}
sub _shared_storage_cache($self, $node, $dir, $value=undef) {
if (!defined $value) {
my $sth = $$CONNECTOR->dbh->prepare(
"SELECT is_shared FROM storage_nodes "
." WHERE dir= ? "
." AND ((id_node1 = ? AND id_node2 = ? ) "
." OR (id_node2 = ? AND id_node1 = ? )) "
);
$sth->execute($dir, $self->id, $node->id, $node->id, $self->id);
my ($is_shared) = $sth->fetchrow;
return $is_shared;
}
my ($id_node1, $id_node2) = ($self->id, $node->id);
($id_node1, $id_node2) = reverse ($self->id, $node->id) if $self->id < $node->id;
my $cached_storage = $self->_get_shared_storage_cache($id_node1, $id_node2, $dir);
return $cached_storage if !defined $value;
return $value if defined $cached_storage && $cached_storage == $value;
confess "Error: conflicting storage, cached=$cached_storage , new=$value"
if defined $cached_storage && $cached_storage != $value;
my $sth = $$CONNECTOR->dbh->prepare(
"INSERT INTO storage_nodes (id_node1, id_node2, dir, is_shared) "
." VALUES (?,?,?,?)"
);
eval { $sth->execute($self->id, $node->id, $dir, $value) };
eval { $sth->execute($id_node1, $id_node2, $dir, $value) };
confess $@ if $@ && $@ !~ /Duplicate entry/i;
return $value;
}
sub _get_shared_storage_cache($self, $id_node1, $id_node2, $dir) {
my $sth = $$CONNECTOR->dbh->prepare(
"SELECT * FROM storage_nodes "
." WHERE dir= ? "
." AND ((id_node1 = ? AND id_node2 = ? ) "
." OR (id_node2 = ? AND id_node1 = ? )) "
);
$sth->execute($dir, $id_node1, $id_node2, $id_node2, $id_node1);
my @is_shared;
my $is_shared;
my $conflict_is_shared;
while ( my $row = $sth->fetchrow_hashref ) {
if (defined $is_shared && defined $row->{shared} && $is_shared != $row->{is_shared}) {
$conflict_is_shared=1;
}
push @is_shared,($row);
$is_shared = $row->{is_shared}
unless $is_shared && !$row->{is_shared};
}
if (scalar(@is_shared)>1 && $conflict_is_shared) {
warn "Warning: error in storage_nodes , conflicting duplicated entries "
.Dumper(\@is_shared)
}
return $is_shared;
}
=head2 shared_storage
Returns true if there is shared storage among to nodes
......@@ -1807,9 +1812,8 @@ sub shared_storage($self, $node, $dir) {
last;
}
$self->write_file($file,''.localtime(time));
confess if !$self->file_exists($file);
my $shared;
for (1 .. 5 ) {
for (1 .. 10 ) {
$shared = $node->file_exists($file);
last if $shared;
sleep 1;
......
......@@ -447,6 +447,22 @@ sub search_volume_path_re($self, $pattern) {
}
=head2 file_exists
Returns true if the file exists in this virtual manager storage
=cut
sub file_exists($self, $file) {
for my $pool ($self->vm->list_all_storage_pools ) {
$pool->refresh();
for my $vol ( $pool->list_all_volumes ) {
return 1 if $vol->get_path eq $file;
}
}
return 0;
}
=head2 dir_img
Returns the directory where disk images are stored in this Virtual Manager
......
......@@ -401,6 +401,27 @@ sub free_disk($self, $storage_pool = undef) {
}
die "Not found";
}
=head2 file_exists
Returns true if the file exists in this virtual manager storage
=cut
sub file_exists( $self, $file ) {
return -e $file if $self->is_local;
my $ssh = $self->_ssh;
confess "Error: no ssh connection to ".$self->name if ! $ssh;
confess "Error: dangerous filename '$file'"
if $file =~ /[`|"(\\\[]/;
my ($out, $err) = $self->run_command("/bin/ls -1 $file");
return 1 if !$err;
return 0;
}
#########################################################################3
1;
......@@ -306,7 +306,6 @@ sub _different_hash($h1,$h2) {
for my $key (keys %$h1) {
next if exists $h1->{$key} && exists $h2->{$key}
&& !defined $h1->{$key} && !defined $h2->{$key};
if (!exists $h2->{$key}
|| !defined $h1->{$key} && defined $h2->{$key}
|| defined $h1->{$key} && !defined $h2->{$key}
......
......@@ -65,6 +65,23 @@ sub test_fail_different_storage_pools($node) {
$base->remove(user_admin);
}
sub test_shared_conflict($vm, $node) {
$vm->_shared_storage_cache($node,"/var/tmp/",1);
is($vm->_shared_storage_cache($node,"/var/tmp/"),1);
is($node->_shared_storage_cache($vm,"/var/tmp/"),1);
is($vm->shared_storage($node,"/var/tmp"),1);
is($node->shared_storage($vm,"/var/tmp"),1);
eval { $vm->_shared_storage_cache($node,"/var/tmp/",0) };
like($@,qr"conflict");
is($vm->_shared_storage_cache($node,"/var/tmp/"),1);
is($node->_shared_storage_cache($vm,"/var/tmp/"),1);
is($vm->shared_storage($node,"/var/tmp"),1);
is($node->shared_storage($vm,"/var/tmp"),1);
}
##################################################################################
if ($>) {
my $msg = "SKIPPED: Test must run as root";
......@@ -108,6 +125,8 @@ for my $vm_name ( 'KVM' ) {
test_fail_different_storage_pools($node);
test_shared_conflict($vm, $node);
clean_remote_node($node);
remove_node($node);
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment