3 # Copyright (C) 2009 Red Hat Inc.
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 2 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 use Locale::TextDomain 'virt-tools';
31 virt-uname, virt-ps, virt-ping - virtual machine information and statistics
35 virt-uname [--options] [domname]
37 virt-ps [--options] [domname]
39 virt-ping [--options] [domname]
41 virt-ifconfig [--options] [domname]
45 All the tools take either a single C<domname> parameter, which is the
46 name of the virtual machine as known to libvirt (C<virsh list>), or no
47 parameter in which case they operate on all currently running guests.
49 I<Note:> You must install the C<virt-tools-guest> package in each
50 Linux guest, otherwise these programs will not work.
52 There are some common options which can be supplied to any tool:
70 Display version number and exit.
76 =item B<--connect URI> | B<-c URI>
78 If using libvirt, connect to the given I<URI>. If omitted, then we
79 connect to the default libvirt hypervisor.
87 Write out the results in CSV format (comma-separated values). This
88 format can be imported easily into databases and spreadsheets, but
89 read L</NOTE ABOUT CSV FORMAT> below.
95 =item B<--verbose> | B<-v>
97 Enable verbose messages, useful for debugging.
103 GetOptions ("help|?" => \$help,
104 "version" => \$version,
105 "connect|c=s" => \$uri,
107 "verbose|v" => \$verbose,
109 pod2usage (1) if $help;
111 print "@PACKAGE_STRING@\n";
116 "virt-uname" => [ \&do_uname, \&title_uname ],
117 "virt-ps" => [ \&do_ps, \&title_ps ],
118 "virt-ping" => [ \&do_ping, \&title_ping ],
122 my ($do_it, $title_it);
123 foreach (keys %subcommands) {
125 print STDERR "subcommand = $_\n" if $verbose;
126 $do_it = $subcommands{$_}->[0];
127 $title_it = $subcommands{$_}->[1];
131 die "$0: cannot determine which sub-command to run\n" unless $do_it;
133 # If we are being run from a local directory, add that directory to
134 # the path, so we can be run from the source directory without being
136 if (substr ($0, 0, 1) ne "/") {
139 $ENV{PATH} = "$_:$ENV{PATH}"; # XXX Windows?
140 print STDERR "PATH set to $ENV{PATH}\n" if $verbose;
145 # Do we have named guests?
150 $conn = Sys::Virt->new (readonly => 1, address => $uri);
152 $conn = Sys::Virt->new (readonly => 1);
155 # Ignore inactive domains.
156 my @doms = $conn->list_domains ();
158 my @domnames = map { $_->get_name () } @doms;
162 foreach (@domnames) {
175 # Turn any errors into warnings.
177 my ($key, $transport);
179 $transport = get_transport ($_);
180 &$do_it ($_, $key, $transport);
188 print STDERR "errors = $errors\n" if $verbose;
190 exit ($errors == 0 ? 0 : 1);
194 C<virt-uname> displays the system information (kernel version etc) of
201 print_row (__"Guest");
208 my $transport = shift;
216 C<virt-ps> displays the process list of the guest.
222 print_row (__"Guest");
229 my $transport = shift;
237 C<virt-ping> pings the guest by making an empty virt-tools request,
238 and checking that it replies. This can be used as a simple test that
239 virt-tools is available and working inside the guest.
245 print_row (__"Guest");
252 my $transport = shift;
258 # virt-ifconfig is implemented separately.
262 C<virt-ifconfig> displays the IP address of the guest.
280 # XXX Use Text::CSV here.
284 } elsif ($_ =~ /,/ || $_ =~ /\n/) {
296 Virt-tools are a set of tools that you can install in your virtual
297 machines (host and guests) to get enhanced information about the
300 Unlike VMWare Tools, virt-tools is hypervisor agnostic. Also
301 virt-tools is just about collecting statistics and does not include
302 any performance or functionality enhancements for guests (see virtio
305 There are two parts to any virt-tools installation: some client
306 programs like C<virt-uname> and C<virt-ps> that you run on the host,
307 to query guest information. On the guest, you have to install and run
308 a virt-tools service. Between the host and guest is a transport which
311 The L</GUEST ARCHITECTURE> section describes how virt-tools appears
314 The L</HOST ARCHITECTURE> section describes the architecture of
315 virt-tools on the host side.
317 =head1 GUEST ARCHITECTURE
319 In most cases, you can just install the C<virt-tools-guest> package in
320 your Linux guests, or the Windows virt-tools guest package in your
321 Windows guests, and everything should just work. In this section we
322 describe more about how it works (or is supposed to work) from the
325 =head2 COMMUNICATIONS DIRECTORY
327 The guest writes various static, mostly unchanging, information into
328 its own directory. On Linux the directory is
329 C<@localstatedir@/lib/virt-tools/> and under Windows it is
330 C<%systemroot%\virttool\>. In the discussion below, this
331 communications directory is referred to as C<$GUESTCOMMSDIR>.
333 The host is able to read files out of this directory using
334 L<libguestfs(3)> (without any cooperation needed by the guest).
338 The host can't easily see the guest's IP address. The host provides
339 the guest with a network interface connected to a bridge, but the
340 guest can use any IP address it likes (although well-behaved guests
341 will usually have some static IPs or are allocated one by DHCP).
343 So when the guest starts up, or its IP address changes (usually these
344 are rare events) the guest writes a file
345 C<$GUESTCOMMSDIR/ip-E<lt>ifaceE<gt>> which contains details of the IP
346 address of the interface E<lt>ifaceE<gt> (eg. the file might be called
347 C<ip-eth0> under Linux).
349 C<virt-ifconfig> reads this file directly using L<libguestfs(3)>.
353 When the guest is first installed (or more precisely, when the
354 virt-tools-guest package is first installed in the guest), a random
355 secret key is generated. This is used to encrypt communications with
356 the guest, and it is described in more detail below.
358 The key is written to C<$GUESTCOMMSDIR/key>.
362 For process listings, and just about every other piece of data except
363 for IP address, guests run a completely standard SNMP (Simple Network
364 Management Protocol) server. The host client tools access this server
365 in order to query information about the guest. They query this using
368 The protocol used is SNMPv3 (RFC 2571) which addresses security
369 concerns in earlier versions of the protocol. In order to ensure that
370 only the host can access the SNMP server and see the results, all
371 communications are encrypted and authenticated using the guest's key.
375 There is not necessarily a network connection between the host and the
376 guest. There are many configurations of virtualization in which the
377 host has no network access to the guest: for example, if the host
378 firewalls itself off from the guest (or vice versa), or if the guest
379 has a physically separate network card from the host.
381 Therefore the guest to host SNMP transport is not necessarily over an
382 IP network. Other transports are possible, including "vmchannel"
383 (where "vmchannel" is the generic name for a collection of specialized
384 host-guest communication channels implemented in different ways by
385 different hypervisors).
387 =head1 HOST ARCHITECTURE
389 On the host side, the host uses L<libguestfs(3)> to read the guest's
390 IP address and key, and uses some heuristics to determine the
393 Once the key and the transport to the guest are worked out, programs
394 like C<virt-ps>, C<virt-uname> and so on are just making
395 straightforward SNMP calls:
397 +-----------------+ +-----------------+
399 | virt-ps --- request ---> snmpd |
400 | <---- reply ----- |
401 +-----------------+ +-----------------+
403 The difficulty is in determining the key and the transport to use,
404 which is what this section covers. You can also use this knowledge to
405 diagnose problems or to create non-standard configurations.
409 All the host tools use an external helper program called
410 C<virt-tools-get-key> to get the key of the guest. (See
411 L<virt-tools-get-key(8)> for the precise usage of this program).
413 The key is generated by the guest once -- when the virt-tools-guest
414 package is installed in the guest. The key is written to a file
415 C<$GUESTCOMMSDIR/key> (in the guest) which is readable only by root.
417 Using L<libguestfs(3)> the host can read any file in the guest, so it
418 can read this key out directly. This is what the
419 C<virt-tools-get-key> program does, and you can run it by hand to
420 verify its operation:
422 # virt-tools-get-key -v domname
427 C<virt-tools-get-key> caches the keys of guests that it has seen
428 before so it doesn't have to read them each time. The cache is in
429 C<@localstatedir@/lib/virt-tools/keys/> (in the host).
431 You can just delete the files in this directory at any time, I<or> you
432 can drop a file in here which contains the key of a guest.
434 To do this, create a file
435 C<@localstatedir@/lib/virt-tools/keys/E<lt>UUIDE<gt>> where
436 E<lt>UUIDE<gt> is the guest's UUID as displayed by this command:
440 The contents of the file should be the key.
442 You can test this works by running C<virt-tools-get-key> by hand.
444 This cache never expires, unless you remove the files by hand.
452 my $cmd = "virt-tools-get-key";
453 $cmd .= " -v" if $verbose;
455 $cmd .= " -c '$uri'" if $uri;
456 $cmd .= " '$domname'";
458 print STDERR "$cmd\n" if $verbose;
460 open PIPE, "$cmd |" or die "$cmd: $!";
462 die "no response from virt-tools-get-key\n" unless $line;
469 =head2 DETERMINE TRANSPORT
471 All the host tools use a second helper program called
472 C<virt-tools-get-transport> to get the transport and address to use
473 for a guest. (See L<virt-tools-get-transport(8)> for the precise
474 usage of this program).
476 This program tries a series of methods to determine how to access a
477 guest, be it through a direct network connection or over some
478 hypervisor-specific vmchannel.
480 # virt-tools-get-transport -v domname
483 You can diagnose problems with the transport by trying to run this
486 =head3 TRANSPORT CACHE
488 C<virt-tools-get-transport> caches the transports of guests that it
489 has seen before so it doesn't have to determine them each time. The
490 cache is in C<@localstatedir@/lib/virt-tools/transports/> (in the
493 As for the L</KEY CACHE>, this directory is just some files that are
494 named after the UUID of the guest, containing the transport.
496 Unlike the key cache, C<virt-tools-get-transport> will check that a
497 transport is still valid, and will expire (ie. delete) the
498 corresponding entry in the transport cache if it is not valid.
506 my $cmd = "virt-tools-get-transport";
507 $cmd .= " -v" if $verbose;
509 $cmd .= " -c '$uri'" if $uri;
510 $cmd .= " '$domname'";
512 print STDERR "$cmd\n" if $verbose;
514 open PIPE, "$cmd |" or die "$cmd: $!";
516 die "no response from virt-tools-get-transport\n" unless $line;
525 Standard SNMP queries are used between the host and guest.
527 SNMP already supports many of the features we are trying to query
528 (eg. the UCD SNMP MIB provides a way to query the process list of a
529 machine in a form which is a de facto standard).
531 To determine what precise queries are sent, run the tools in verbose
532 mode or examine the source.
534 =head2 RUNNING YOUR OWN SNMP SERVER IN A GUEST
538 =head1 NOTE ABOUT CSV FORMAT
540 Comma-separated values (CSV) is a deceptive format. It I<seems> like
541 it should be easy to parse, but it is definitely not easy to parse.
543 Myth: Just split fields at commas. Reality: This does I<not> work
544 reliably. This example has two columns:
548 Myth: Read the file one line at a time. Reality: This does I<not>
549 work reliably. This example has one row:
554 For shell scripts, use C<csvtool> (L<http://merjis.com/developers/csv>
555 also packaged in major Linux distributions).
557 For other languages, use a CSV processing library (eg. C<Text::CSV>
558 for Perl or Python's built-in csv library).
560 Most spreadsheets and databases can import CSV directly.
568 L<Sys::Guestfs::Lib(3)>,
570 L<http://libguestfs.org/>.
578 Richard W.M. Jones (C<rjones at redhat dot com>)
582 Matthew Booth (C<mbooth at redhat dot com>)
588 Copyright (C) 2009 Red Hat Inc.
590 This program is free software; you can redistribute it and/or modify
591 it under the terms of the GNU General Public License as published by
592 the Free Software Foundation; either version 2 of the License, or
593 (at your option) any later version.
595 This program is distributed in the hope that it will be useful,
596 but WITHOUT ANY WARRANTY; without even the implied warranty of
597 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
598 GNU General Public License for more details.
600 You should have received a copy of the GNU General Public License
601 along with this program; if not, write to the Free Software
602 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.