New tool: virt-make-fs for creating filesystems on devices.
[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 $long;
86
87 =item B<-l> | B<--long>
88
89 With this option, C<virt-list-partitions> displays the type
90 and size of each partition too (where "type" means C<ext3>, C<pv> etc.)
91
92 =cut
93
94 my $human;
95
96 =item B<-h> | B<--human-readable>
97
98 Show sizes in human-readable form (eg. "1G").
99
100 =back
101
102 =cut
103
104 # Configure bundling, otherwise '-lh' is unrecognized.
105 Getopt::Long::Configure ("bundling");
106
107 GetOptions ("help|?" => \$help,
108             "version" => \$version,
109             "connect|c=s" => \$uri,
110             "long|l" => \$long,
111             "human-readable|h" => \$human,
112     ) or pod2usage (2);
113 pod2usage (1) if $help;
114 if ($version) {
115     my $g = Sys::Guestfs->new ();
116     my %h = $g->version ();
117     print "$h{major}.$h{minor}.$h{release}$h{extra}\n";
118     exit
119 }
120
121 pod2usage (__"virt-list-partitions: no image or VM name given")
122     if @ARGV <= 0;
123
124 my $g;
125 if ($uri) {
126     $g = open_guest (\@ARGV, address => $uri);
127 } else {
128     $g = open_guest (\@ARGV);
129 }
130
131 $g->launch ();
132
133 # List of partitions and sizes.
134 my @partitions;
135 my @devices = $g->list_devices ();
136 foreach my $dev (@devices) {
137     my @p = $g->part_list ($dev);
138     foreach (@p) {
139         $_->{name} = canonicalize ("$dev" . $_->{part_num});
140         push @partitions, $_;
141     }
142 }
143
144 # Print them.
145 foreach my $part (@partitions) {
146     print $part->{name};
147
148     if ($long) {
149         my $type;
150         eval {
151             $type = $g->vfs_type ($part->{name});
152         };
153         $type ||= "unknown";
154         $type = "pv" if $type eq "LVM2_member";
155         print " $type ";
156         if ($human) {
157             print (human_size($part->{part_size}));
158         } else {
159             print $part->{part_size};
160         }
161     }
162     print "\n";
163 }
164
165 # The reverse of device name translation, see
166 # BLOCK DEVICE NAMING in guestfs(3).
167 sub canonicalize
168 {
169     local $_ = shift;
170
171     if (m{^/dev/[hv]d([a-z]\d)$}) {
172         return "/dev/sd$1";
173     }
174     $_;
175 }
176
177 # Convert a number of bytes to a human-readable number.
178 sub human_size
179 {
180     local $_ = shift;
181
182     $_ /= 1024;                 # blocks
183
184     if ($_ < 1024) {
185         sprintf "%dK", $_;
186     } elsif ($_ < 1024 * 1024) {
187         sprintf "%.1fM", ($_ / 1024);
188     } else {
189         sprintf "%.1fG", ($_ / 1024 / 1024);
190     }
191 }
192
193 =head1 SEE ALSO
194
195 L<guestfs(3)>,
196 L<guestfish(1)>,
197 L<virt-list-filesystems(1)>,
198 L<virt-resize(1)>,
199 L<Sys::Guestfs(3)>,
200 L<Sys::Guestfs::Lib(3)>,
201 L<Sys::Virt(3)>,
202 L<http://libguestfs.org/>.
203
204 =head1 AUTHOR
205
206 Richard W.M. Jones L<http://et.redhat.com/~rjones/>
207
208 =head1 COPYRIGHT
209
210 Copyright (C) 2009 Red Hat Inc.
211
212 This program is free software; you can redistribute it and/or modify
213 it under the terms of the GNU General Public License as published by
214 the Free Software Foundation; either version 2 of the License, or
215 (at your option) any later version.
216
217 This program is distributed in the hope that it will be useful,
218 but WITHOUT ANY WARRANTY; without even the implied warranty of
219 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
220 GNU General Public License for more details.
221
222 You should have received a copy of the GNU General Public License
223 along with this program; if not, write to the Free Software
224 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.