1
0
mirror of synced 2026-01-13 15:17:30 +00:00
xen-tools.xen-tools/examples/update-modules
2013-01-17 17:51:16 +01:00

234 lines
4.0 KiB
Perl
Executable File

#!/usr/bin/perl
#
# This code is intended to update the modules installed within each
# Xen guest domain to the named version.
#
# It should be fairly safe, but I make no promises - hence why this
# is an example.
#
# Steve
# --
#
use strict;
use warnings;
use File::Path qw/ rmtree /;
use File::Temp qw/ tempdir /;
my $modules = shift;
if ( ! defined( $modules ) )
{
print <<EOF;
Usage: $0 <modules>
eg: $0 2.6.18.xx|/usr/lib/modules/nn.nn.nn-xen
EOF
exit;
}
#
# Make sure the path is fully qualified.
#
if ( $modules !~ /^[\/\\]/ )
{
$modules = "/lib/modules/" . $modules;
}
#
# Make sure the module directory exists.
#
if ( ! -d $modules )
{
print "The modules directory $modules doesn't exist.\n";
exit;
}
#
# OK now we have the modules so we need to:
#
# 0. Read our configuration file.
# 1. Find each xen guest.
# 2. Ensure it isn't running (TODO)
# 3. Mount the disk image.
# 4. Remove existing modules, and copy in the specified ones.
#
#
my %CONFIG;
readConfigurationFile( "/etc/xen-tools/xen-tools.conf" );
foreach my $guest ( findGuests() )
{
print "Attempting to update guest: $guest\n";
#
# Create a temporary directory to mount the disk upon.
#
my $tmp = tempdir( CLEANUP => 1 );
#
# Mount the disk.
#
if ( $CONFIG{'dir'} )
{
# The loopback image.
my $img = $CONFIG{'dir'} . "/domains/" . $guest . "/disk.img";
system( "mount -o loop $img $tmp" );
}
elsif ( $CONFIG{'lvm'} )
{
# The LVM volume
my $img = "/dev/" . $CONFIG{'lvm'} . "/$guest-disk";
system( "mount $img $tmp" );
}
else
{
print "Unhandled disk format - can't mount\n";
next;
}
#
# We've got it mounted.
#
print "\tMounted disk image.\n";
# make sure we have a directory
if ( ! -d $tmp . "/lib/modules" )
{
print "\tMissing modules. Skipping\n";
next;
}
#
# Remove the existing module directories.
#
`rm -rf $tmp/lib/modules`;
mkdir $tmp . "/lib/modules";
print "\tRemoved existing modules\n";
#
# Copy existing directory.
#
if ( -d $tmp . "/lib/modules" )
{
`cp -R $modules $tmp/lib/modules/`;
print "\tCopied over $modules\n";
}
else
{
print "No module directory .. weirdness\n";
}
#
# Unmount
#
system( "umount $tmp" );
print "\tUnmounted disk image.\n\n";
}
=begin doc
Find each xen guest upon the system.
=end doc
=cut
sub findGuests
{
my @results;
#
# Assume xen-tools.
#
foreach my $file ( glob( "/etc/xen/*.cfg" ) )
{
#
# Find the name.
#
open( INPUT, "<" , $file );
foreach my $line ( <INPUT> )
{
chomp( $line );
if ( $line =~ /name\s*=\s*['"]([^'"]+)["']/ )
{
push @results, $1;
}
}
close( INPUT );
}
return( sort( @results ) );
}
=begin doc
Read the configuration file specified.
=end doc
=cut
sub readConfigurationFile
{
my ($file) = ( @_ );
open( FILE, "<", $file ) or die "Cannot read file '$file' - $!";
my $line = "";
while (defined($line = <FILE>) )
{
chomp $line;
if ($line =~ s/\\$//)
{
$line .= <FILE>;
redo unless eof(FILE);
}
# Skip lines beginning with comments
next if ( $line =~ /^([ \t]*)\#/ );
# Skip blank lines
next if ( length( $line ) < 1 );
# Strip trailing comments.
if ( $line =~ /(.*)\#(.*)/ )
{
$line = $1;
}
# Find variable settings
if ( $line =~ /([^=]+)=([^\n]+)/ )
{
my $key = $1;
my $val = $2;
# Strip leading and trailing whitespace.
$key =~ s/^\s+//;
$key =~ s/\s+$//;
$val =~ s/^\s+//;
$val =~ s/\s+$//;
# Store value.
$CONFIG{ $key } = $val;
}
}
close( FILE );
}