daemon: debug segv correct use of dereferencing NULL.
[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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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<-c URI>
79
80 =item B<--connect URI>
81
82 If using libvirt, connect to the given I<URI>.  If omitted, then we
83 connect to the default libvirt hypervisor.
84
85 If you specify guest block devices directly, then libvirt is not used
86 at all.
87
88 =cut
89
90 my $format;
91
92 =item B<--format> raw
93
94 Specify the format of disk images given on the command line.  If this
95 is omitted then the format is autodetected from the content of the
96 disk image.
97
98 If disk images are requested from libvirt, then this program asks
99 libvirt for this information.  In this case, the value of the format
100 parameter is ignored.
101
102 If working with untrusted raw-format guest disk images, you should
103 ensure the format is always specified.
104
105 =cut
106
107 my $human;
108
109 =item B<-h>
110
111 =item B<--human-readable>
112
113 Show sizes in human-readable form (eg. "1G").
114
115 =cut
116
117 my $long;
118
119 =item B<-l>
120
121 =item B<--long>
122
123 With this option, C<virt-list-partitions> displays the type
124 and size of each partition too (where "type" means C<ext3>, C<pv> etc.)
125
126 =cut
127
128 my $total;
129
130 =item B<-t>
131
132 =item B<--total>
133
134 Display the total size of each block device (as a separate row or
135 rows).
136
137 =back
138
139 =cut
140
141 # Configure bundling, otherwise '-lh' is unrecognized.
142 Getopt::Long::Configure ("bundling");
143
144 GetOptions ("help|?" => \$help,
145             "version" => \$version,
146             "connect|c=s" => \$uri,
147             "format=s" => \$format,
148             "human-readable|h" => \$human,
149             "long|l" => \$long,
150             "total|t" => \$total,
151     ) or pod2usage (2);
152 pod2usage (1) if $help;
153 if ($version) {
154     my $g = Sys::Guestfs->new ();
155     my %h = $g->version ();
156     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
157     exit
158 }
159
160 pod2usage (__"virt-list-partitions: no image or VM name given")
161     if @ARGV <= 0;
162
163 my $g;
164 if ($uri) {
165     $g = open_guest (\@ARGV, address => $uri, format => $format);
166 } else {
167     $g = open_guest (\@ARGV, format => $format);
168 }
169
170 $g->launch ();
171
172 # List of partitions and sizes.
173 my @partitions = $g->list_partitions ();
174 foreach my $name (@partitions) {
175     $name = canonicalize ($name);
176
177     print $name;
178
179     if ($long) {
180         my $type;
181         eval {
182             $type = $g->vfs_type ($name);
183         };
184         $type ||= "unknown";
185         $type = "pv" if $type eq "LVM2_member";
186         print " $type ";
187
188         my $size;
189         eval {
190             $size = $g->blockdev_getsize64 ($name);
191         };
192         $size ||= "unknown";
193
194         if ($human) {
195             print (human_size($size));
196         } else {
197             print $size;
198         }
199     }
200     print "\n";
201 }
202
203 if ($total) {
204     # List of devices and sizes.
205     my @devices = $g->list_devices ();
206     foreach my $name (@devices) {
207         $name = canonicalize ($name);
208
209         print $name;
210
211         if ($long) {
212             print " device ";
213
214             my $size;
215             eval {
216                 $size = $g->blockdev_getsize64 ($name);
217             };
218             $size ||= "unknown";
219
220             if ($human) {
221                 print (human_size($size));
222             } else {
223                 print $size;
224             }
225         }
226         print "\n";
227     }
228 }
229
230 # The reverse of device name translation, see
231 # BLOCK DEVICE NAMING in guestfs(3).
232 sub canonicalize
233 {
234     local $_ = shift;
235
236     if (m{^/dev/[hv]d([a-z]+\d*)$}) {
237         return "/dev/sd$1";
238     }
239     $_;
240 }
241
242 # Convert a number of bytes to a human-readable number.
243 sub human_size
244 {
245     local $_ = shift;
246
247     $_ /= 1024;                 # blocks
248
249     if ($_ < 1024) {
250         sprintf "%dK", $_;
251     } elsif ($_ < 1024 * 1024) {
252         sprintf "%.1fM", ($_ / 1024);
253     } else {
254         sprintf "%.1fG", ($_ / 1024 / 1024);
255     }
256 }
257
258 =head1 SHELL QUOTING
259
260 Libvirt guest names can contain arbitrary characters, some of which
261 have meaning to the shell such as C<#> and space.  You may need to
262 quote or escape these characters on the command line.  See the shell
263 manual page L<sh(1)> for details.
264
265 =head1 SEE ALSO
266
267 L<guestfs(3)>,
268 L<guestfish(1)>,
269 L<virt-filesystems(1)>,
270 L<virt-list-filesystems(1)>,
271 L<virt-resize(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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.