]>
git.proxmox.com Git - qemu-server.git/blob - qmextract
9 use PVE
::Cluster
qw(cfs_read_file);
12 my @std_opts = ('storage=s', 'info', 'prealloc');
15 print STDERR
"usage: $0 [--storage=<storeid>] [--info] [--prealloc] <archive> <vmid>\n\n";
19 if (!GetOptions
($opts, @std_opts)) {
25 # NOTE: this is run as tar subprocess (--to-command)
27 $SIG{INT
} = $SIG{TERM
} = $SIG{QUIT
} = $SIG{HUP
} = $SIG{PIPE
} = sub {
28 die "interrupted by signal\n";
31 my $filename = $ENV{TAR_FILENAME
};
32 die "got strange environment - no TAR_FILENAME\n" if !$filename;
34 my $filesize = $ENV{TAR_SIZE
};
35 die "got strange file size '$filesize'\n" if !$filesize;
37 my $tmpdir = $ENV{VZDUMP_TMPDIR
};
38 die "got strange environment - no VZDUMP_TMPDIR\n" if !$tmpdir;
40 my $filetype = $ENV{TAR_FILETYPE
} || 'none';
41 die "got strange filetype '$filetype'\n" if $filetype ne 'f';
43 my $vmid = $ENV{VZDUMP_VMID
};
44 PVE
::JSONSchema
::pve_verify_vmid
($vmid);
47 print STDERR
"reading archive member '$filename'\n";
49 print STDERR
"extracting '$filename' from archive\n";
52 my $conffile = "$tmpdir/qemu-server.conf";
53 my $statfile = "$tmpdir/qmrestore.stat";
55 if ($filename eq 'qemu-server.conf') {
56 my $outfd = IO
::File-
>new($conffile, "w") ||
57 die "unable to write file '$conffile'\n";
59 while (defined(my $line = <>)) {
61 print STDERR
"CONFIG: $line" if $opts->{info
};
70 exec 'dd', 'bs=256K', "of=/dev/null";
71 die "couldn't exec dd: $!\n";
74 my $conffd = IO
::File-
>new($conffile, "r") ||
75 die "unable to read file '$conffile'\n";
78 while (defined(my $line = <$conffd>)) {
79 if ($line =~ m/^\#vzdump\#map:(\S+):(\S+):(\d+):(\S*):$/) {
80 $map->{$2} = { virtdev
=> $1, size
=> $3, storeid
=> $4 };
85 my $statfd = IO
::File-
>new($statfile, "a") ||
86 die "unable to open file '$statfile'\n";
88 if ($filename !~ m/^.*\.([^\.]+)$/){
89 die "got strange filename '$filename'\n";
96 print STDERR
"restoring old style vzdump archive - " .
97 "no device map inside archive\n";
98 die "can't restore old style archive to storage '$opts->{storage}'\n"
99 if $opts->{storage
} && $opts->{storage
} ne 'local';
101 my $dir = "/var/lib/vz/images/$vmid";
104 $path = "$dir/$filename";
106 print $statfd "vzdump::$path\n";
111 my $info = $map->{$filename};
112 die "no vzdump info for '$filename'\n" if !$info;
114 if ($filename !~ m/^vm-disk-$info->{virtdev}\.([^\.]+)$/){
115 die "got strange filename '$filename'\n";
118 if ($filesize != $info->{size
}) {
119 die "detected size difference for '$filename' " .
120 "($filesize != $info->{size})\n";
124 if ($opts->{storage
}) {
125 $storeid = $opts->{storage
};
127 $storeid = $info->{storeid
} || 'local';
130 my $cfg = cfs_read_file
('storage.cfg');
131 my $scfg = PVE
::Storage
::storage_config
($cfg, $storeid);
133 my $alloc_size = ($filesize + 1024 - 1)/1024;
134 if ($scfg->{type
} eq 'dir' || $scfg->{type
} eq 'nfs') {
135 # hack: we just alloc a small file (32K) - we overwrite it anyways
138 die "unable to restore '$filename' to storage '$storeid'\n" .
139 "storage type '$scfg->{type}' does not support format '$format\n"
143 my $volid = PVE
::Storage
::vdisk_alloc
($cfg, $storeid, $vmid,
144 $format, undef, $alloc_size);
146 print STDERR
"new volume ID is '$volid'\n";
148 print $statfd "vzdump:$info->{virtdev}:$volid\n";
151 $path = PVE
::Storage
::path
($cfg, $volid);
154 print STDERR
"restore data to '$path' ($filesize bytes)\n";
156 if ($opts->{prealloc
} || $format ne 'raw' || (-b
$path)) {
157 exec 'dd', 'ibs=256K', 'obs=256K', "of=$path";
158 die "couldn't exec dd: $!\n";
160 exec '/usr/lib/qemu-server/sparsecp', $path;
161 die "couldn't exec sparsecp: $!\n";
166 if (scalar(@ARGV) == 2) {
170 # fixme: use API call
171 PVE
::JSONSchema
::pve_verify_vmid
($vmid);
173 PVE
::Cluster
::check_cfs_quorum
();
175 PVE
::QemuServer
::restore_archive
($archive, $vmid, $opts);
177 } elsif (scalar(@ARGV) == 0 && $ENV{TAR_FILENAME
}) {