#!/usr/bin/perl -w
# virt-rescue
-# Copyright (C) 2009 Red Hat Inc.
+# Copyright (C) 2009-2010 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
use warnings;
use strict;
+use Errno;
use Sys::Guestfs;
use Sys::Guestfs::Lib qw(open_guest);
use Pod::Usage;
=cut
+my $append;
+
+=item B<--append kernelopts>
+
+Pass additional options to the rescue kernel.
+
+=cut
+
my $uri;
=item B<--connect URI> | B<-c URI>
=cut
+my $format;
+
+=item B<--format> raw
+
+Specify the format of disk images given on the command line. If this
+is omitted then the format is autodetected from the content of the
+disk image.
+
+If disk images are requested from libvirt, then this program asks
+libvirt for this information. In this case, the value of the format
+parameter is ignored.
+
+If working with untrusted raw-format guest disk images, you should
+ensure the format is always specified.
+
+=cut
+
+my $memsize;
+
+=item B<--memsize MB> | B<-m MB>
+
+Change the amount of memory allocated to the rescue system. The
+default is set by libguestfs and is small but adequate for running
+system tools. The occasional program might need more memory. The
+parameter is specified in megabytes.
+
+=cut
+
+my $network;
+
+=item B<--network>
+
+Enable QEMU user networking in the guest.
+
+=cut
+
my $readonly;
=item B<--ro> | B<-r>
might be running, and is generally recommended in cases where you
don't need write access to the disk.
+=cut
+
+my $selinux;
+
+=item B<--selinux>
+
+Enable SELinux in the rescue appliance. You should read
+L<guestfs(3)/SELINUX> before using this option.
+
=back
=cut
GetOptions ("help|?" => \$help,
"version" => \$version,
+ "append=s" => \$append,
"connect|c=s" => \$uri,
+ "format=s" => \$format,
+ "memsize|m=i" => \$memsize,
+ "network" => \$network,
"ro|r" => \$readonly,
+ "selinux" => \$selinux,
) or pod2usage (2);
pod2usage (1) if $help;
if ($version) {
my @args = (\@ARGV);
push @args, address => $uri if $uri;
push @args, rw => 1 unless $readonly;
+push @args, format => $format if defined $format;
my $g = open_guest (@args);
+# Setting "direct mode" is required for the rescue appliance.
$g->set_direct (1);
-$g->set_append ("guestfs_rescue=1");
-$g->launch ();
+# Set other features.
+$g->set_selinux (1) if $selinux;
+$g->set_memsize ($memsize) if defined $memsize;
+$g->set_network (1) if $network;
+
+# Set the kernel command line, which must include guestfs_rescue=1
+# (see appliance/init).
+my $str = "guestfs_rescue=1";
+$str .= " $append" if defined $append;
+$g->set_append ($str);
+
+# Run the appliance. This won't return until the user quits the
+# appliance.
+eval { $g->launch (); };
+
+# launch() expects guestfsd to start. However, virt-rescue doesn't run guestfsd,
+# so this will always fail with ECHILD when the appliance exits unexpectedly.
+die $@ unless $!{ECHILD};
exit 0;
Several environment variables affect virt-rescue. See
L<guestfs(3)/ENVIRONMENT VARIABLES> for the complete list.
+=head1 SHELL QUOTING
+
+Libvirt guest names can contain arbitrary characters, some of which
+have meaning to the shell such as C<#> and space. You may need to
+quote or escape these characters on the command line. See the shell
+manual page L<sh(1)> for details.
+
=head1 SEE ALSO
L<guestfs(3)>,