#! /usr/bin/perl -w # getXenMounts.pl # Author: R. W. Rodolico (http://www.dailydata.net) # Date: 20121121 # Description: # Script that uses xenstore to read all attached block devices on all domU's # in running DOM0. Output is a tab delimited file designed for easy parsing # # Field 1: domu name # Field 2: domu number # Field 3: drive number (vbd number) # Field 4: drive name on DOMU # Field 5: drive number on DOM0 # # designed to allow you easily determine what to use for xm block-attach and # xm block-detach, for example if a drive needs to be detached from a DOMU to # resize or replace. # # Simple usage example: # determine which drive is mounted as /home on virtual named book: # 1. Log into book. Issue command 'mount' to see what device name is. umount that drive. # Assume it was xvda3 # 2. Log into DOM0. Issue command getXenMounts.pl | grep book | grep xvda3 # output similar to 'book 26 51715 xvda3 /dev/virtuals/book.dailydata.net-home' # 3. Detach the drive with command 'xm block-detach book 51715' (or, 'xm block-detach 26 51715') # 'book' is the name, 26 is the domain number, and they are interchangable # 4. Perform the work you need to do on /dev/virtuals/book.dailydata.net-home (resize, replace, whatever) # 5. Re-attach to domain with command 'xm block-attach book phy:/dev/virtuals/book.dailydata.net-home xvda3 w' # Again, book and 26 are interchangable as long as you have not changed the domain id in the process # 6. Log back into the server and remount drive. # Deficiencies: # Probably would be nice to accept a couple of parameters denoting domain ID and device on domain, then get a single value returned # Subject to change of xenstore database format. This works on xenstore v4.0.1 # Copyright 2012, R. W. Rodolico # 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 . # Revisions: # 20130813 - fixed bug where domu name was not printing correctly # 20121121 - Initial release # get a list of running virtuals, return as an array sub getRunningVirtuals { my @virtuals = ´xenstore-list /local/domain/0/backend/vbd´; chomp @virtuals; return @virtuals; } # find all drives for a given virtual, then retrieve the device name on the virtual (dev) # and the device name on DOM0 (params) # return a hash reference sub getDrivesForVirtual { my $virnum = shift; my %output; my @drives = ´xenstore-list /local/domain/0/backend/vbd/$virnum´; # get all attached vbd's chomp @drives; foreach my $thisDrive ( @drives ) { # go through the list of drives # find the name on the virtual (sans /dev/, which is assumed) $output{$thisDrive}{'DomU'} = ´xenstore-read /local/domain/0/backend/vbd/$virnum/$thisDrive/dev´; chomp $output{$thisDrive}{'DomU'}; # and, find the name on DOM0 that provides this $output{$thisDrive}{'Dom0'} = ´xenstore-read /local/domain/0/backend/vbd/$virnum/$thisDrive/params´; chomp $output{$thisDrive}{'Dom0'}; } return \%output; } # helper sub that simply determines the "human" name of a given DomU and returns it sub getDOMUName { my $virtnum = shift; my $virtname = ´xenstore-read /local/domain/$virtnum/name´; chomp $virtname; return $virtname; } my %output; # hash for output my @virtuals = &getRunningVirtuals(); # store dom-id (integer) in array for all running DOMU's foreach my $thisVirt ( @virtuals ) { # for each of them # create a hash entry and attach the drive information for it $output{$thisVirt} = &getDrivesForVirtual( $thisVirt ); } # print them out. print "domu\tdomu\tdrive\tdomu\tdom0\n"; print "name\tid\tid\tdevice\tdevice\n"; print "====\t====\t=====\t====\t====\n"; foreach my $virtual ( keys %output ) { my $driveList = $output{$virtual}; foreach my $drive ( keys %$driveList ) { print &getDOMUName($virtual) . "\t$virtual\t$drive\t$$driveList{$drive}{'DomU'}\t$$driveList{$drive}{'Dom0'}\n"; } } 1;