147 lines
3.5 KiB
Perl
147 lines
3.5 KiB
Perl
package PVE::Storage::Common;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use PVE::JSONSchema;
|
|
use PVE::Syscall;
|
|
use PVE::Tools qw(run_command);
|
|
|
|
use constant {
|
|
FALLOC_FL_KEEP_SIZE => 0x01, # see linux/falloc.h
|
|
FALLOC_FL_PUNCH_HOLE => 0x02, # see linux/falloc.h
|
|
};
|
|
|
|
=pod
|
|
|
|
=head1 NAME
|
|
|
|
PVE::Storage::Common - Shared functions and utilities for storage plugins and storage operations
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
This module contains common subroutines that are mainly to be used by storage
|
|
plugins. This module's submodules contain subroutines that are tailored towards
|
|
a more specific or related purpose.
|
|
|
|
Functions concerned with storage-related C<PVE::SectionConfig> things, helpers
|
|
for the C<PVE::Storage> API can be found in this module. Functions that can't
|
|
be grouped in a submodule can also be found here.
|
|
|
|
=head1 SUBMODULES
|
|
|
|
=over
|
|
|
|
=back
|
|
|
|
=head1 STANDARD OPTIONS FOR JSON SCHEMA
|
|
|
|
=over
|
|
|
|
=back
|
|
|
|
=head3 pve-storage-image-format
|
|
|
|
Possible formats a guest image can have.
|
|
|
|
=cut
|
|
|
|
# TODO PVE 9 - Note that currently, qemu-server allows more formats for VM images, so third party
|
|
# storage plugins might potentially allow more too, but none of the plugins we are aware of do that.
|
|
# Those formats should either be allowed here or support for them should be phased out (at least in
|
|
# the storage layer). Can still be added again in the future, should any plugin provider request it.
|
|
|
|
PVE::JSONSchema::register_standard_option(
|
|
'pve-storage-image-format',
|
|
{
|
|
type => 'string',
|
|
enum => ['raw', 'qcow2', 'subvol', 'vmdk'],
|
|
description => "Format of the image.",
|
|
},
|
|
);
|
|
|
|
=pod
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=cut
|
|
|
|
=pod
|
|
|
|
=head3 align_size_up
|
|
|
|
$aligned_size = align_size_up($size, $granularity)
|
|
|
|
Returns the next size bigger than or equal to C<$size> that is aligned with a
|
|
granularity of C<$granularity>. Prints a message if the aligned size is not
|
|
equal to the aligned size.
|
|
|
|
=cut
|
|
|
|
sub align_size_up : prototype($$) {
|
|
my ($size, $granularity) = @_;
|
|
|
|
my $padding = ($granularity - $size % $granularity) % $granularity;
|
|
my $aligned_size = $size + $padding;
|
|
print "size $size is not aligned to granularity $granularity, rounding up to $aligned_size\n"
|
|
if $aligned_size != $size;
|
|
return $aligned_size;
|
|
}
|
|
|
|
=pod
|
|
|
|
=head3 deallocate
|
|
|
|
deallocate($file_handle, $offset, $length)
|
|
|
|
Deallocates the range with C<$length> many bytes starting from offset C<$offset>
|
|
for the file associated to the file handle C<$file_handle>. Dies on failure.
|
|
|
|
=cut
|
|
|
|
sub deallocate : prototype($$$) {
|
|
my ($file_handle, $offset, $length) = @_;
|
|
|
|
my $mode = FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE;
|
|
$offset = int($offset);
|
|
$length = int($length);
|
|
|
|
if (syscall(PVE::Syscall::fallocate, fileno($file_handle), $mode, $offset, $length) != 0) {
|
|
die "fallocate: punch hole failed (offset: $offset, length: $length) - $!\n";
|
|
}
|
|
}
|
|
|
|
=pod
|
|
|
|
=head3 run_qemu_img_json
|
|
|
|
run_qemu_img_json($cmd, $timeout)
|
|
|
|
Execute qemu_img command C<$cmd> with a timeout C<$timeout>.
|
|
Parse the output result and return a json.
|
|
|
|
=cut
|
|
|
|
sub run_qemu_img_json {
|
|
my ($cmd, $timeout) = @_;
|
|
my $json = '';
|
|
my $err_output = '';
|
|
eval {
|
|
run_command(
|
|
$cmd,
|
|
timeout => $timeout,
|
|
outfunc => sub { $json .= shift },
|
|
errfunc => sub { $err_output .= shift . "\n" },
|
|
);
|
|
};
|
|
warn $@ if $@;
|
|
if ($err_output) {
|
|
# if qemu did not output anything to stdout we die with stderr as an error
|
|
die $err_output if !$json;
|
|
# otherwise we warn about it and try to parse the json
|
|
warn $err_output;
|
|
}
|
|
return $json;
|
|
}
|
|
1;
|