X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qmextract;h=1466a586d9163ec31c3f7976a07a6046f3f64f7e;hb=de5af2d3b2a9e13442b61536a99061e5340e86c5;hp=b5d3db2940337ecbdf787e96dbef99bae4ee0e98;hpb=3e16d5fc605b1a5475c1e82630a7e37211626e65;p=qemu-server.git diff --git a/qmextract b/qmextract index b5d3db29..1466a586 100755 --- a/qmextract +++ b/qmextract @@ -1,18 +1,26 @@ -#!/usr/bin/perl -w +#!/usr/bin/perl use strict; +use warnings; use Getopt::Long; use File::Path; use IO::File; +use PVE::INotify; use PVE::JSONSchema; use PVE::Tools; -use PVE::Cluster qw(cfs_read_file); +use PVE::Cluster; +use PVE::RPCEnvironment; +use PVE::Storage; use PVE::QemuServer; -my @std_opts = ('storage=s', 'info', 'prealloc'); +$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; + +die "please run as root\n" if $> != 0; + +my @std_opts = ('storage=s', 'pool=s', 'info', 'prealloc'); sub print_usage { - print STDERR "usage: $0 [--storage=] [--info] [--prealloc] \n\n"; + print STDERR "usage: $0 [--storage=] [--pool=] [--info] [--prealloc] \n\n"; } my $opts = {}; @@ -21,6 +29,14 @@ if (!GetOptions ($opts, @std_opts)) { exit (-1); } +PVE::INotify::inotify_init(); + +my $rpcenv = PVE::RPCEnvironment->init('cli'); + +$rpcenv->init_request(); +$rpcenv->set_language($ENV{LANG}); +$rpcenv->set_user('root@pam'); + sub extract_archive { # NOTE: this is run as tar subprocess (--to-command) @@ -43,6 +59,9 @@ sub extract_archive { my $vmid = $ENV{VZDUMP_VMID}; PVE::JSONSchema::pve_verify_vmid($vmid); + my $user = $ENV{VZDUMP_USER}; + $rpcenv->check_user_enabled($user); + if ($opts->{info}) { print STDERR "reading archive member '$filename'\n"; } else { @@ -96,7 +115,7 @@ sub extract_archive { print STDERR "restoring old style vzdump archive - " . "no device map inside archive\n"; die "can't restore old style archive to storage '$opts->{storage}'\n" - if $opts->{storage} && $opts->{storage} ne 'local'; + if defined($opts->{storage}) && $opts->{storage} ne 'local'; my $dir = "/var/lib/vz/images/$vmid"; mkpath $dir; @@ -120,17 +139,32 @@ sub extract_archive { "($filesize != $info->{size})\n"; } + # check permission for all used storages + my $pool = $opts->{pool}; + if ($user ne 'root@pam') { + if (defined($opts->{storage})) { + my $sid = $opts->{storage} || 'local'; + $rpcenv->check($user, "/storage/$sid", ['Datastore.AllocateSpace']); + } else { + foreach my $fn (keys %$map) { + my $fi = $map->{$fn}; + my $sid = $fi->{storeid} || 'local'; + $rpcenv->check($user, "/storage/$sid", ['Datastore.AllocateSpace']); + } + } + } + my $storeid; - if ($opts->{storage}) { - $storeid = $opts->{storage}; + if (defined($opts->{storage})) { + $storeid = $opts->{storage} || 'local'; } else { $storeid = $info->{storeid} || 'local'; } - my $cfg = cfs_read_file('storage.cfg'); + my $cfg = PVE::Storage::config(); my $scfg = PVE::Storage::storage_config($cfg, $storeid); - my $alloc_size = ($filesize + 1024 - 1)/1024; + my $alloc_size = int(($filesize + 1024 - 1)/1024); if ($scfg->{type} eq 'dir' || $scfg->{type} eq 'nfs') { # hack: we just alloc a small file (32K) - we overwrite it anyways $alloc_size = 32; @@ -157,8 +191,8 @@ sub extract_archive { exec 'dd', 'ibs=256K', 'obs=256K', "of=$path"; die "couldn't exec dd: $!\n"; } else { - exec '/usr/lib/qemu-server/sparsecp', $path; - die "couldn't exec sparsecp: $!\n"; + exec '/bin/cp', '--sparse=always', '/dev/stdin', $path; + die "couldn't exec cp: $!\n"; } } @@ -172,7 +206,7 @@ if (scalar(@ARGV) == 2) { PVE::Cluster::check_cfs_quorum(); - PVE::QemuServer::restore_archive($archive, $vmid, $opts); + PVE::QemuServer::restore_archive($archive, $vmid, 'root@pam', $opts); } elsif (scalar(@ARGV) == 0 && $ENV{TAR_FILENAME}) { extract_archive();