[pve-devel] [RFC container] added 'pct df'

Wolfgang Bumiller w.bumiller at proxmox.com
Mon Jul 4 14:07:33 CEST 2016


This works on both online and offline containers. Offline
containers get mounted (with a 'mounted' lock) during the
operation.

The output is similar to 'df -h' and only shows size
information for volumes and device mount points:

Example output:
  MP     Size   Used Use% Path
  rootfs 9.0G 184.9M  0.0 /
  mp0       -      -    - /share
---
Note: needs the pve-common df untaint patch
 src/PVE/CLI/pct.pm | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 90 insertions(+), 1 deletion(-)

diff --git a/src/PVE/CLI/pct.pm b/src/PVE/CLI/pct.pm
index ca87229..b39aef6 100755
--- a/src/PVE/CLI/pct.pm
+++ b/src/PVE/CLI/pct.pm
@@ -283,6 +283,93 @@ __PACKAGE__->register_method({
 	return undef;
     }});
 
+__PACKAGE__->register_method({
+    name => 'df',
+    path => 'df',
+    method => 'GET',
+    description => "Get the container's current disk usage.",
+    parameters => {
+	additionalProperties => 0,
+	properties => {
+	    vmid => get_standard_option('pve-vmid', { completion => \&PVE::LXC::complete_ctid }),
+	},
+    },
+    returns => { type => 'null' },
+    code => sub {
+	my ($param) = @_;
+
+	my $rpcenv = PVE::RPCEnvironment::get();
+
+	# JSONSchema's format_size is exact, this uses floating point numbers
+	my $format = sub {
+	    my ($size) = @_;
+	    return $size if $size < 1024.;
+	    $size /= 1024.;
+	    return sprintf('%.1fK', ${size}) if $size < 1024.;
+	    $size /= 1024.;
+	    return sprintf('%.1fM', ${size}) if $size < 1024.;
+	    $size /= 1024.;
+	    return sprintf('%.1fG', ${size}) if $size < 1024.;
+	    $size /= 1024.;
+	    return sprintf('%.1fT', ${size}) if $size < 1024.;
+	};
+
+	my $vmid = extract_param($param, 'vmid');
+	PVE::LXC::Config->lock_config($vmid, sub {
+	    my $pid = eval { PVE::LXC::find_lxc_pid($vmid) };
+	    my ($conf, $rootdir, $storecfg, $mounted);
+	    if ($@ || !$pid) {
+		$conf = PVE::LXC::Config->set_lock($vmid, 'mounted');
+		$rootdir = "/var/lib/lxc/$vmid/rootfs";
+		$storecfg = PVE::Storage::config();
+		PVE::LXC::mount_all($vmid, $storecfg, $conf);
+		$mounted = 1;
+	    } else {
+		$conf = PVE::LXC::Config->load_config($vmid);
+		$rootdir = "/proc/$pid/root";
+	    }
+
+	    my @list = [qw(MP Size Used Use% Path)];
+	    my @len = (2, 4, 4, 4);
+
+	    eval {
+		PVE::LXC::Config->foreach_mountpoint($conf, sub {
+		    my ($name, $mp) = @_;
+		    my $path = $mp->{mp};
+
+		    my ($total, $used, $pc) = ('-', '-', '-');
+
+		    if ($mp->{type} =~ /^(?:volume|device)$/) {
+			my $df = PVE::Tools::df("$rootdir/$path", 3);
+
+			$total = $format->($df->{total});
+			$used = $format->($df->{used});
+
+			$pc = sprintf('%.1f', $df->{used}/$df->{total});
+		    }
+
+		    my $entry = [ $name, $total, $used, $pc, $path ];
+		    push @list, $entry;
+
+		    foreach my $i (0..3) {
+			$len[$i] = length($entry->[$i])
+			    if $len[$i] < length($entry->[$i]);
+		    }
+		});
+
+		my $format = "%-$len[0]s %$len[1]s %$len[2]s %$len[3]s %s\n";
+		printf($format, @$_) foreach @list;
+	    };
+	    warn $@ if $@;
+
+	    if ($mounted) {
+		PVE::LXC::umount_all($vmid, $storecfg, $conf, 0);
+		PVE::LXC::Config->remove_lock($vmid, 'mounted');
+	    }
+	});
+	return undef;
+    }});
+
 # File creation with specified ownership and permissions.
 # User and group can be names or decimal numbers.
 # Permissions are explicit (not affected by umask) and can be numeric with the
@@ -575,7 +662,9 @@ our $cmddef = {
     unmount => [ __PACKAGE__, 'unmount', ['vmid']],
     push => [ __PACKAGE__, 'push', ['vmid', 'file', 'destination']],
     pull => [ __PACKAGE__, 'pull', ['vmid', 'path', 'destination']],
-    
+
+    df => [ __PACKAGE__, 'df', ['vmid']],
+
     destroy => [ 'PVE::API2::LXC', 'destroy_vm', ['vmid'], 
 		 { node => $nodename }, $upid_exit ],
 
-- 
2.1.4




More information about the pve-devel mailing list