[go: up one dir, main page]

Menu

[r33]: / trunk / ostransfer  Maximize  Restore  History

Download this file

191 lines (143 with data), 4.0 kB

#! /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;
}