Commit bf41a4ce authored by Mike Hibler's avatar Mike Hibler

Make sure persistent blockstores are not "sparse" volumes.

Also, use new API call to create zvols.
parent 84eff3a8
#!/usr/bin/perl -wT
#
# Copyright (c) 2013-2015 University of Utah and the Flux Group.
# Copyright (c) 2013-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -300,6 +300,9 @@ sub create($$$;$)
{
my ($pool,$vol,$size,$fstype) = @_;
# XXX create non-sparse (pre-allocated) volumes
my $sparse = 0;
if (defined($pool) && $pool =~ /^([-\w]+)$/) {
$pool = $1;
} else {
......@@ -327,7 +330,7 @@ sub create($$$;$)
return 1;
}
my $rv = freenasVolumeCreate($pool, $vol, $size);
my $rv = freenasVolumeCreate($pool, $vol, $size, $sparse);
if ($rv == 0 && $fstype ne "none") {
$rv = freenasFSCreate($pool, $vol, $fstype);
}
......
......@@ -28,17 +28,7 @@
#
# XXX things the API cannot do yet:
#
# 1. create a zvol volume; no API exists,
#
# Sometime between April and Sept 2016, they finally added an API
# to create zvols:
# storage/volume/<vol>/zvols/ POST w/name and volsize to create
# storage/volume/<vol>/zvols/<zvol> GET for attributes
# storage/volume/<vol>/zvols/<zvol> DELETE to destroy
# Have not converted to use this yet, will have to deal with backward
# compat on servers that don't support it.
#
# 2. create an authorized initiator (POST); always return 302 FOUND
# 1. create an authorized initiator (POST); always return 302 FOUND
#
# API also does not report an error for:
#
......@@ -170,7 +160,7 @@ my $server;
sub freenasPoolList();
sub freenasVolumeList($;$);
sub freenasVolumeCreate($$$);
sub freenasVolumeCreate($$$;$);
sub freenasVolumeDestroy($$);
sub freenasFSCreate($$$);
sub freenasRunCmd($$);
......@@ -432,8 +422,14 @@ sub freenasVolumeList($;$)
}
}
# XXX unbelievable: the API does not return the volsize of a zvol!
# Gotta do it ourselves...
#
# XXX unbelievable: the storage/volume API does not return the volsize
# of a zvol! Gotta do it ourselves...
#
# XXX we could now get this through storage/volume/<pool>/zvols for
# each pool, or storage/volume/<pool>/zvols/<volume> for each zvol.
# But for now, let's just stick with the ZFS command.
#
if (open(ZFS, "$ZFS_CMD get -t volume -o name,value -Hp volsize |")) {
while (my $line = <ZFS>) {
chomp $line;
......@@ -503,17 +499,16 @@ sub freenasPoolList() {
#
# Create a ZFS zvol.
# Unbelievably, the FreeNAS 1.0 API does not support creation of a zvol
# so we have to use the old, hacky interface.
#
sub freenasVolumeCreate($$$)
sub freenasVolumeCreate($$$;$)
{
my ($pool, $volname, $size) = @_;
my ($pool, $volname, $size, $sparse) = @_;
# Untaint arguments since they are passed to a command execution
$pool = untaintHostname($pool);
$volname = untaintHostname($volname);
$size = untaintNumber($size);
$sparse = untaintNumber($sparse);
if (!$pool || !$volname || !$size) {
warn("*** ERROR: freenasVolumeCreate: ".
"Invalid arguments");
......@@ -539,17 +534,37 @@ sub freenasVolumeCreate($$$)
return -1;
}
# Allocate volume in zpool
eval { freenasRunCmd($FREENAS_CLI_VERB_VOLUME,
"add $pool $volname ${size}M off") };
if ($@) {
my $msg = " $@";
$msg =~ s/\\n/\n /g;
warn("*** ERROR: freenasVolumeCreate: ".
"volume allocation failed:\n$msg");
# XXX the traditional default for FreeNAS seems to be true
my $sparsearg = JSON::PP::true;
if (defined($sparse) && $sparse == 0) {
$sparsearg = JSON::PP::false;
}
my $msg;
my $res = freenasRequest("$FREENAS_API_RESOURCE_VOLUME/${pool}/zvols",
"POST", undef,
{"name" => "$volname",
"volsize" => "${size}M",
"sparse" => $sparsearg },
undef, \$msg);
if (!$res) {
if ($msg) {
warn("*** ERROR: freenasVolumeCreate: ".
"volume creation failed:\n$msg");
} else {
warn("*** ERROR: freenasVolumeCreate: volume creation failed");
}
return -1;
}
# Make sure compression is disabled. Could be an option?
$res =
freenasRequest("$FREENAS_API_RESOURCE_VOLUME/${pool}/zvols/${volname}",
"PUT", undef, { "compression" => "off" });
if (!$res) {
warn("*** ERROR: freenasVolumeCreate: could not disable compression");
}
return 0;
}
......
......@@ -604,6 +604,11 @@ sub allocSlice($$$$) {
$volname = "UNKNOWN" if (!$volname);
my $size = $sconf->{'VOLSIZE'};
#
# By default, we will create "best effort" ephemeral volumes.
#
my $sparse = 1;
#
# If this is a use of a persistent store, the BSID is a unique
# volume name based on the lease ID. Look up the volume to make
......@@ -644,7 +649,7 @@ sub allocSlice($$$$) {
$priv->{'pool'} = $bsid;
$priv->{'volume'} = $vnode_id;
return freenasVolumeCreate($bsid, $vnode_id, $size);
return freenasVolumeCreate($bsid, $vnode_id, $size, $sparse);
}
# Setup device export.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment