#!/usr/bin/perl # Copyright (C) 2012 Red Hat Inc. # # 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 2 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, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # Test adding maximum number of disks to the guest. use strict; use warnings; use Sys::Guestfs; my $errors = 0; my $g = Sys::Guestfs->new (); my $max_disks = $g->max_disks (); printf "max_disks is %d\n", $max_disks; # Create large number of disks. my ($name, $i, $j); for ($i = 0; $i < $max_disks; ++$i) { $name = sprintf "test%d.img", $i; #print "adding $name => /dev/sd", drive_name($i), "\n"; unlink $name; open FILE, ">$name" or die "$name: $!"; truncate FILE, 1024*1024 or die "$name: truncate: $!"; close FILE or die "$name: $!"; $g->add_drive_opts ($name, format => "raw"); } $g->launch (); # Check the disks were added. my @devices = $g->list_devices (); if (@devices != $max_disks) { print STDERR "$0: incorrect number of devices returned by \$g->list_devices:\n"; print STDERR "$0: \@devices = ", join (" ", @devices), "\n"; $errors++; } for ($i = 0; $i < $max_disks; ++$i) { my $expected = drive_name ($i); unless ($devices[$i] =~ m{/dev/.d$expected$}) { print STDERR "$0: incorrect device name at index $i: ", "expected /dev/sd$expected, but got $devices[$i]\n"; $errors++; } } # Check device_index. for ($i = 0; $i < $max_disks; ++$i) { if ($i != $g->device_index ($devices[$i])) { print STDERR "$0: incorrect device index for $devices[$i]\n"; $errors++; } } # Put some data on each disk to check they are mountable, writable etc. for ($i = 0; $i < $max_disks; ++$i) { my $dev = $devices[$i]; $g->mkmountpoint ("/mp$i"); # To save time in the test, add 15 partitions to the first disk # and last disks only, and 1 partition to every other disk. Note # that 15 partitions is the max allowed by virtio-blk. my $part; if ($i == 0 || $i == $max_disks-1) { $g->part_init ($dev, "gpt"); for ($j = 1; $j <= 14; ++$j) { $g->part_add ($dev, "p", 64*$j, 64*$j+63); } $g->part_add ($dev, "p", 64*15, -64); $part = $dev . "15"; } else { $g->part_disk ($dev, "mbr"); $part = $dev . "1"; } $g->mkfs ("ext2", "$part"); $g->mount ("$part", "/mp$i"); $g->write ("/mp$i/disk$i", "This is disk #$i.\n"); } for ($i = 0; $i < $max_disks; ++$i) { if ($g->cat ("/mp$i/disk$i") ne "This is disk #$i.\n") { print STDERR "$0: unexpected content in file /mp$i/disk$i\n"; $errors++; } } # Enumerate and check partition names. my @partitions = $g->list_partitions (); if (@partitions != $max_disks + 14*2) { print STDERR "$0: incorrect number of partitions returned by \$g->list_partitions:\n"; print STDERR "$0: \@partitions = ", join (" ", @partitions), "\n"; $errors++; } for ($i = 0, $j = 0; $i < $max_disks; ++$i) { my $expected = drive_name ($i); if ($i == 0 || $i == $max_disks-1) { unless ($partitions[$j++] =~ m{/dev/.d${expected}1$} && $partitions[$j++] =~ m{/dev/.d${expected}2$} && $partitions[$j++] =~ m{/dev/.d${expected}3$} && $partitions[$j++] =~ m{/dev/.d${expected}4$} && $partitions[$j++] =~ m{/dev/.d${expected}5$} && $partitions[$j++] =~ m{/dev/.d${expected}6$} && $partitions[$j++] =~ m{/dev/.d${expected}7$} && $partitions[$j++] =~ m{/dev/.d${expected}8$} && $partitions[$j++] =~ m{/dev/.d${expected}9$} && $partitions[$j++] =~ m{/dev/.d${expected}10$} && $partitions[$j++] =~ m{/dev/.d${expected}11$} && $partitions[$j++] =~ m{/dev/.d${expected}12$} && $partitions[$j++] =~ m{/dev/.d${expected}13$} && $partitions[$j++] =~ m{/dev/.d${expected}14$} && $partitions[$j++] =~ m{/dev/.d${expected}15$}) { print STDERR "$0: incorrect partition name at index $i\n"; $errors++; } } else { unless ($partitions[$j++] =~ m{/dev/.d${expected}1$}) { print STDERR "$0: incorrect partition name at index $i\n"; $errors++; } } } $g->umount_all (); $g->close (); for ($i = 0; $i < $max_disks; ++$i) { $name = sprintf "test%d.img", $i; unlink $name; } exit ($errors == 0 ? 0 : 1); sub drive_name { my $index = shift; my $prefix = ""; if ($index >= 26) { $prefix = drive_name ($index/26 - 1); } $index %= 26; return $prefix . chr (97 + $index); }