The command “xm list” displays the number of seconds of CPU time used by each Xen domain. This makes it easy to compare the CPU use of the various domains if they were all started at the same time (usually system boot). But is not very helpful if they were started at different times.
I wrote a little Perl program to display the percentage of one CPU that has been used by each domain, here is a sample of the output:
Domain-0 uses 7.70% of one CPU
demo uses 0.06% of one CPU
lenny32 uses 2.07% of one CPU
unstable uses 0.30% of one CPU
Now the command “xm top” can give you the amount of CPU time used at any moment (which is very useful). But it’s also good to be able to see how much is being used over the course of some days of operation. For example if a domain is using the equivalent of 34% of one CPU over the course of a week (as one domain that I run is doing) then it makes sense to allocate more than one VCPU to it so that things don’t slow down at peak times or when cron jobs are running.
I believe that it’s best to limit the number of CPUs allocated to Xen domains. For example I am running a Xen server with 8 CPU cores. I could grant each domain access to 8 VCPUs, but then any domain could use all that CPU power if it ran wild. While if I give no domain more than 2 VCPUs then one domain could use all the CPU resources allocated to it without the other domains being impacted. I realise that there are scheduling algorithms in the Xen kernel that are designed to deal with such situations, but I believe that simply denying access to excessive resource use is more effective and reliable.
I have not filed a bug report requesting that my script be added to one of the Xen packages as I’m not sure which one it would belong in (and also it’s a bit of a hack). It’s licensed under the GPL so anyone who wants to use it can do what they want. Any distribution package maintainer who wants to include it in a Xen utilities package is welcome to do so. The code is below.
#!/usr/bin/perl
use strict;
open(LIST, "xm list --long|") or die "Can't get list";
my $name = "Dom0";
my $uptime = 0.0;
my $cpu_time = 0.0;
open(UPTIME, "</proc/uptime") or die "Can't open /proc/uptime";
my @arr = split(/ /, <UPTIME>);
$uptime = $arr[0];
close(UPTIME);
while(<LIST>)
{
chomp;
if($_ =~ /^\)/)
{
my $cpu = $cpu_time / $uptime * 100.0;
printf("%s uses %.2f%% of one CPU\n", $name, $cpu);
next;
}
$_ =~ s/\).*$//;
if($_ =~ /up_time /)
{
$_ =~ s/^.*up_time //;
$uptime = $_;
next;
}
if($_ =~ /cpu_time /)
{
$_ =~ s/^.*cpu_time //;
$cpu_time = $_;
next;
}
if($_ =~ /\(name /)
{
$_ =~ s/^.*name //;
$name = $_;
next;
}
}
close(LIST);