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