Rewrite virt-cat in C.
[libguestfs.git] / tools / virt-rescue
1 #!/usr/bin/perl -w
2 # virt-rescue
3 # Copyright (C) 2009-2010 Red Hat Inc.
4 #
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.
9 #
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.
14 #
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.
18
19 use warnings;
20 use strict;
21
22 use Errno;
23 use Sys::Guestfs;
24 use Sys::Guestfs::Lib qw(open_guest);
25 use Pod::Usage;
26 use Getopt::Long;
27 use Locale::TextDomain 'libguestfs';
28
29 =encoding utf8
30
31 =head1 NAME
32
33 virt-rescue - Run a rescue shell on a virtual machine
34
35 =head1 SYNOPSIS
36
37  virt-rescue [--options] domname
38
39  virt-rescue [--options] disk.img [disk.img ...]
40
41 =head1 WARNING
42
43 You must I<not> use C<virt-rescue> on live virtual machines.  Doing so
44 will probably result in disk corruption in the VM.  C<virt-rescue>
45 tries to stop you from doing this, but doesn't catch all cases.
46
47 However if you use the I<--ro> (read only) option, then you can attach
48 a shell to a live virtual machine.  The results might be strange or
49 inconsistent at times but you won't get disk corruption.
50
51 =head1 DESCRIPTION
52
53 virt-rescue is like a Rescue CD, but for virtual machines, and without
54 the need for a CD.  virt-rescue gives you a rescue shell and some
55 simple recovery tools which you can use to examine or rescue a virtual
56 machine or disk image.
57
58 You can run virt-rescue on any virtual machine known to libvirt, or
59 directly on disk image(s):
60
61  virt-rescue GuestName
62
63  virt-rescue --ro /path/to/disk.img
64
65  virt-rescue /dev/sdc
66
67 For live VMs you I<must> use the --ro option.
68
69 When you run virt-rescue on a virtual machine or disk image, you are
70 placed in an interactive bash shell where you can use many ordinary
71 Linux commands.  What you see in C</> (C</bin>, C</lib> etc) is the
72 rescue appliance.  You must mount the virtual machine's filesystems by
73 hand.  There is an empty directory called C</sysroot> where you can
74 mount filesystems.
75
76 In the example below, we list logical volumes, then choose one to
77 mount under C</sysroot>:
78
79  ><rescue> lvs
80  LV      VG        Attr   LSize   Origin Snap%  Move Log Copy%  Convert
81  lv_root vg_f11x64 -wi-a-   8.83G
82  lv_swap vg_f11x64 -wi-a- 992.00M
83  ><rescue> mount /dev/vg_f11x64/lv_root /sysroot
84  ><rescue> ls /sysroot
85
86 If you don't know what filesystems are available on the virtual
87 machine then you can use commands such as L<parted(8)> and L<lvs(8)>
88 to find out.
89
90 =head2 NOTES
91
92 Virt-rescue can be used on I<any> disk image file or device, not just
93 a virtual machine.  For example you can use it on a blank file if you
94 want to partition that file (although we would recommend using
95 L<guestfish(1)> instead as it is more suitable for this purpose).  You
96 can even use virt-rescue on things like SD cards.
97
98 This tool is just designed for quick interactive hacking on a virtual
99 machine.  For more structured access to a virtual machine disk image,
100 you should use L<guestfs(3)>.  To get a structured shell that you can
101 use to make scripted changes to guests, use L<guestfish(1)>.
102
103 =head1 OPTIONS
104
105 =over 4
106
107 =cut
108
109 my $help;
110
111 =item B<--help>
112
113 Display brief help.
114
115 =cut
116
117 my $version;
118
119 =item B<--version>
120
121 Display version number and exit.
122
123 =cut
124
125 my $append;
126
127 =item B<--append kernelopts>
128
129 Pass additional options to the rescue kernel.
130
131 =cut
132
133 my $uri;
134
135 =item B<--connect URI> | B<-c URI>
136
137 If using libvirt, connect to the given I<URI>.  If omitted, then we
138 connect to the default libvirt hypervisor.
139
140 If you specify guest block devices directly, then libvirt is not used
141 at all.
142
143 =cut
144
145 my $format;
146
147 =item B<--format> raw
148
149 Specify the format of disk images given on the command line.  If this
150 is omitted then the format is autodetected from the content of the
151 disk image.
152
153 If disk images are requested from libvirt, then this program asks
154 libvirt for this information.  In this case, the value of the format
155 parameter is ignored.
156
157 If working with untrusted raw-format guest disk images, you should
158 ensure the format is always specified.
159
160 =cut
161
162 my $memsize;
163
164 =item B<--memsize MB> | B<-m MB>
165
166 Change the amount of memory allocated to the rescue system.  The
167 default is set by libguestfs and is small but adequate for running
168 system tools.  The occasional program might need more memory.  The
169 parameter is specified in megabytes.
170
171 =cut
172
173 my $network;
174
175 =item B<--network MB>
176
177 Enable QEMU user networking in the guest.
178
179 =cut
180
181 my $readonly;
182
183 =item B<--ro> | B<-r>
184
185 Open the image read-only.
186
187 The option must always be used if the disk image or virtual machine
188 might be running, and is generally recommended in cases where you
189 don't need write access to the disk.
190
191 =cut
192
193 my $selinux;
194
195 =item B<--selinux>
196
197 Enable SELinux in the rescue appliance.  You should read
198 L<guestfs(3)/SELINUX> before using this option.
199
200 =back
201
202 =cut
203
204 GetOptions ("help|?" => \$help,
205             "version" => \$version,
206             "append=s" => \$append,
207             "connect|c=s" => \$uri,
208             "format=s" => \$format,
209             "memsize|m=i" => \$memsize,
210             "network" => \$network,
211             "ro|r" => \$readonly,
212             "selinux" => \$selinux,
213     ) or pod2usage (2);
214 pod2usage (1) if $help;
215 if ($version) {
216     my $g = Sys::Guestfs->new ();
217     my %h = $g->version ();
218     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
219     exit
220 }
221
222 pod2usage (__"virt-rescue: no image or VM names rescue given")
223     if @ARGV == 0;
224
225 my @args = (\@ARGV);
226 push @args, address => $uri if $uri;
227 push @args, rw => 1 unless $readonly;
228 push @args, format => $format if defined $format;
229 my $g = open_guest (@args);
230
231 # Setting "direct mode" is required for the rescue appliance.
232 $g->set_direct (1);
233
234 # Set other features.
235 $g->set_selinux (1) if $selinux;
236 $g->set_memsize ($memsize) if defined $memsize;
237 $g->set_network (1) if $network;
238
239 # Set the kernel command line, which must include guestfs_rescue=1
240 # (see appliance/init).
241 my $str = "guestfs_rescue=1";
242 $str .= " $append" if defined $append;
243 $g->set_append ($str);
244
245 # Run the appliance.  This won't return until the user quits the
246 # appliance.
247 eval { $g->launch (); };
248
249 # launch() expects guestfsd to start. However, virt-rescue doesn't run guestfsd,
250 # so this will always fail with ECHILD when the appliance exits unexpectedly.
251 die $@ unless $!{ECHILD};
252
253 exit 0;
254
255 =head1 ENVIRONMENT VARIABLES
256
257 Several environment variables affect virt-rescue.  See
258 L<guestfs(3)/ENVIRONMENT VARIABLES> for the complete list.
259
260 =head1 SHELL QUOTING
261
262 Libvirt guest names can contain arbitrary characters, some of which
263 have meaning to the shell such as C<#> and space.  You may need to
264 quote or escape these characters on the command line.  See the shell
265 manual page L<sh(1)> for details.
266
267 =head1 SEE ALSO
268
269 L<guestfs(3)>,
270 L<guestfish(1)>,
271 L<virt-cat(1)>,
272 L<Sys::Guestfs(3)>,
273 L<Sys::Guestfs::Lib(3)>,
274 L<Sys::Virt(3)>,
275 L<http://libguestfs.org/>.
276
277 =head1 AUTHOR
278
279 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
280
281 =head1 COPYRIGHT
282
283 Copyright (C) 2009-2010 Red Hat Inc.
284
285 This program is free software; you can redistribute it and/or modify
286 it under the terms of the GNU General Public License as published by
287 the Free Software Foundation; either version 2 of the License, or
288 (at your option) any later version.
289
290 This program is distributed in the hope that it will be useful,
291 but WITHOUT ANY WARRANTY; without even the implied warranty of
292 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
293 GNU General Public License for more details.
294
295 You should have received a copy of the GNU General Public License
296 along with this program; if not, write to the Free Software
297 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.