Generate a dummy 'Fedora' fedora.img in images directory for use by tests.
[libguestfs.git] / tools / virt-list-partitions
1 #!/usr/bin/perl -w
2 # virt-list-partitions
3 # Copyright (C) 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 Sys::Guestfs;
23 use Sys::Guestfs::Lib qw(open_guest);
24 use Pod::Usage;
25 use Getopt::Long;
26 use Locale::TextDomain 'libguestfs';
27
28 =encoding utf8
29
30 =head1 NAME
31
32 virt-list-partitions - List partitions in a virtual machine or disk image
33
34 =head1 SYNOPSIS
35
36  virt-list-partitions [--options] domname
37
38  virt-list-partitions [--options] disk.img [disk.img ...]
39
40 =head1 DESCRIPTION
41
42 C<virt-list-partitions> is a command line tool to list
43 the partitions that are contained in a virtual machine or
44 disk image.  It is mainly useful as a first step to using
45 L<virt-resize(1)>.
46
47 C<virt-list-partitions> is just a simple wrapper around
48 L<libguestfs(3)> functionality.  For more complex cases you should
49 look at the L<guestfish(1)> tool.
50
51 =head1 OPTIONS
52
53 =over 4
54
55 =cut
56
57 my $help;
58
59 =item B<--help>
60
61 Display brief help.
62
63 =cut
64
65 my $version;
66
67 =item B<--version>
68
69 Display version number and exit.
70
71 =cut
72
73 my $uri;
74
75 =item B<--connect URI> | B<-c URI>
76
77 If using libvirt, connect to the given I<URI>.  If omitted, then we
78 connect to the default libvirt hypervisor.
79
80 If you specify guest block devices directly, then libvirt is not used
81 at all.
82
83 =cut
84
85 my $format;
86
87 =item B<--format> raw
88
89 Specify the format of disk images given on the command line.  If this
90 is omitted then the format is autodetected from the content of the
91 disk image.
92
93 If disk images are requested from libvirt, then this program asks
94 libvirt for this information.  In this case, the value of the format
95 parameter is ignored.
96
97 If working with untrusted raw-format guest disk images, you should
98 ensure the format is always specified.
99
100 =cut
101
102 my $human;
103
104 =item B<-h> | B<--human-readable>
105
106 Show sizes in human-readable form (eg. "1G").
107
108 =cut
109
110 my $long;
111
112 =item B<-l> | B<--long>
113
114 With this option, C<virt-list-partitions> displays the type
115 and size of each partition too (where "type" means C<ext3>, C<pv> etc.)
116
117 =cut
118
119 my $total;
120
121 =item B<-t> | B<--total>
122
123 Display the total size of each block device (as a separate row or
124 rows).
125
126 =back
127
128 =cut
129
130 # Configure bundling, otherwise '-lh' is unrecognized.
131 Getopt::Long::Configure ("bundling");
132
133 GetOptions ("help|?" => \$help,
134             "version" => \$version,
135             "connect|c=s" => \$uri,
136             "format=s" => \$format,
137             "human-readable|h" => \$human,
138             "long|l" => \$long,
139             "total|t" => \$total,
140     ) or pod2usage (2);
141 pod2usage (1) if $help;
142 if ($version) {
143     my $g = Sys::Guestfs->new ();
144     my %h = $g->version ();
145     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
146     exit
147 }
148
149 pod2usage (__"virt-list-partitions: no image or VM name given")
150     if @ARGV <= 0;
151
152 my $g;
153 if ($uri) {
154     $g = open_guest (\@ARGV, address => $uri, format => $format);
155 } else {
156     $g = open_guest (\@ARGV, format => $format);
157 }
158
159 $g->launch ();
160
161 # List of partitions and sizes.
162 my @partitions = $g->list_partitions ();
163 foreach my $name (@partitions) {
164     $name = canonicalize ($name);
165
166     print $name;
167
168     if ($long) {
169         my $type;
170         eval {
171             $type = $g->vfs_type ($name);
172         };
173         $type ||= "unknown";
174         $type = "pv" if $type eq "LVM2_member";
175         print " $type ";
176
177         my $size;
178         eval {
179             $size = $g->blockdev_getsize64 ($name);
180         };
181         $size ||= "unknown";
182
183         if ($human) {
184             print (human_size($size));
185         } else {
186             print $size;
187         }
188     }
189     print "\n";
190 }
191
192 if ($total) {
193     # List of devices and sizes.
194     my @devices = $g->list_devices ();
195     foreach my $name (@devices) {
196         $name = canonicalize ($name);
197
198         print $name;
199
200         if ($long) {
201             print " device ";
202
203             my $size;
204             eval {
205                 $size = $g->blockdev_getsize64 ($name);
206             };
207             $size ||= "unknown";
208
209             if ($human) {
210                 print (human_size($size));
211             } else {
212                 print $size;
213             }
214         }
215         print "\n";
216     }
217 }
218
219 # The reverse of device name translation, see
220 # BLOCK DEVICE NAMING in guestfs(3).
221 sub canonicalize
222 {
223     local $_ = shift;
224
225     if (m{^/dev/[hv]d([a-z]+\d*)$}) {
226         return "/dev/sd$1";
227     }
228     $_;
229 }
230
231 # Convert a number of bytes to a human-readable number.
232 sub human_size
233 {
234     local $_ = shift;
235
236     $_ /= 1024;                 # blocks
237
238     if ($_ < 1024) {
239         sprintf "%dK", $_;
240     } elsif ($_ < 1024 * 1024) {
241         sprintf "%.1fM", ($_ / 1024);
242     } else {
243         sprintf "%.1fG", ($_ / 1024 / 1024);
244     }
245 }
246
247 =head1 SHELL QUOTING
248
249 Libvirt guest names can contain arbitrary characters, some of which
250 have meaning to the shell such as C<#> and space.  You may need to
251 quote or escape these characters on the command line.  See the shell
252 manual page L<sh(1)> for details.
253
254 =head1 SEE ALSO
255
256 L<guestfs(3)>,
257 L<guestfish(1)>,
258 L<virt-list-filesystems(1)>,
259 L<virt-resize(1)>,
260 L<Sys::Guestfs(3)>,
261 L<Sys::Guestfs::Lib(3)>,
262 L<Sys::Virt(3)>,
263 L<http://libguestfs.org/>.
264
265 =head1 AUTHOR
266
267 Richard W.M. Jones L<http://people.redhat.com/~rjones/>
268
269 =head1 COPYRIGHT
270
271 Copyright (C) 2009-2010 Red Hat Inc.
272
273 This program is free software; you can redistribute it and/or modify
274 it under the terms of the GNU General Public License as published by
275 the Free Software Foundation; either version 2 of the License, or
276 (at your option) any later version.
277
278 This program is distributed in the hope that it will be useful,
279 but WITHOUT ANY WARRANTY; without even the implied warranty of
280 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
281 GNU General Public License for more details.
282
283 You should have received a copy of the GNU General Public License
284 along with this program; if not, write to the Free Software
285 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.