OpenSANd Code
Brought to you by:
hoefer
#! /usr/bin/perl
# This is opensand, an NBD base SAN system
# Copyright (C) 2008-2014 Stefan Hoefer <stefan@hoefer.ch>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
use strict;
use IPC::Open2;
if (@ARGV != 2 || $ARGV[0] !~ /^\d+$/) {
die "Usage: ostransfer diskid host\n";
}
#print "Getting source...\n";
my $source = get_source($ARGV[0]);
if (defined($source)) {
print "Source disk $ARGV[0]:\n";
print " Active: ".$source->{active}."\n";
print " Size: ".$source->{size}."\n";
print " Encrypted: ".$source->{encrypted}."\n";
print " Protected: ".$source->{protected}."\n";
print " Comment: ".$source->{comment}."\n";
}
else {
die "Could not find disk $ARGV[0]!\n";
}
if ($source->{active}) {
die "The source disk must not be active!\n";
}
print "Opening destination...\n";
my $fd = get_destination($ARGV[1], $source);
if ($fd > 0) {
if (open my $fdin, sprintf("/var/lib/opensand/disks/disk%05d", int($ARGV[0]))) {
print " Transferring data...\n";
my $buffer;
my $bytesread = 1;
my $total = 0;
while ($bytesread > 0) {
$bytesread = read($fdin, $buffer, 1024*1024*4);
if ($bytesread > 0) {
$total += $bytesread;
print $fd $buffer;
}
}
close($fdin);
if ($total == $source->{size}) {
print " Transfer complete ($total bytes).\n";
}
else {
print " Transfer incomplete ($total of ".$source->{size}." bytes)\n";
}
}
close($fd);
print "Disk successfully transferred\n";
}
else {
die "Error opening destination descriptor\n";
}
sub get_destination {
my $host = shift;
my $source = shift;
my $out;
my $in;
my $pid = open2($out, $in, 'ssh', $host, '/bin/bash');
if ($pid > 1) {
print " Destination opened...\n";
print $in "oscontrol create ".($source->{size}/1024/1024)." '".$source->{comment}."'\n";
my $reply = <$out>;
chomp $reply;
my $id = -1;
if ($reply =~ /ok (\d+)/) {
$id = $1;
print " Disk $id created\n";
}
if ($id >= 0) {
if ($source->{protected}) {
print " Setting protection mode...\n";
print $in "oscontrol protect $id 1\n";
<$out>;
}
if ($source->{encrypted}) {
print " Encrypting disk...\n";
print $in "oscontrol encrypt $id 1\n";
<$out>;
}
print " Scrambling disk...\n";
print $in "oscontrol scramble $id 1\n";
<$out>;
print $in sprintf("cat > /var/lib/opensand/disks/disk%05d\n", $id);
return $in;
}
}
return -1;
}
sub get_source {
my $id = shift;
my $result;
if (open my $fd, "oscontrol list |") {
while (my $line = <$fd>) {
chomp $line;
if ($line =~ /^(\d+)/) {
if (int($1) == int($id)) {
$result = {};
my ($id, $uuid, $size, $timestamp, $type, $status, $encrypted, $protected, $backuped, $snapshots, $backups, $comment) = split ":", $line;
$result->{size} = $size;
$result->{encrypted} = $encrypted;
$result->{protected} = $protected;
$result->{comment} = $comment;
}
}
}
close $fd;
}
if (defined($result)) {
if (open my $fd, "oscontrol show $id|") {
while (my $line = <$fd>) {
chomp $line;
if ($line =~ /^ +Active: +(NO|YES)/) {
if ($1 eq "NO") {
$result->{active} = 0;
}
elsif ($1 eq "YES") {
$result->{active} = 1;
}
else {
$result->{active} = -1;
}
}
}
close $fd;
}
system("oscontrol scramble $id 1 \&> /dev/null");
}
return $result;
}