Commit 69376200 authored by Kirk Webb's avatar Kirk Webb
Browse files

Merge branch 'stordev-host'

parents 6d760dfc d1b13faf
......@@ -122,6 +122,9 @@ my $sysname = `uname -s`;
chomp($sysname);
my $islinux = ($sysname eq "Linux");
# ...
my $isfreenas = -e "/etc/rc.freenas" ? 1 : 0;
#
# Put this into the background and log its output. We *must* do this cause
# we do not want to halt the boot if the testbed is down!
......@@ -243,7 +246,7 @@ sub prebootvnodes($$)
#
# XXX OS dependent stuff. Should move elsewhere.
#
if ($islinux) {
if ($islinux || $isfreenas) {
# This is handled in the libvnode libraries.
return;
}
......@@ -306,7 +309,7 @@ sub postbootvnodes($$)
#
# XXX OS dependent stuff. Should move elsewhere
#
if ($islinux) {
if ($islinux || $isfreenas) {
return;
}
......
......@@ -118,6 +118,8 @@ elsif (WINDOWS()) {
# rc.progagent is run by a separate service named ProgAgent.
# It's started by EmulabStartup after rc.bootsetup runs.
"rc.tarfiles", "rc.rpms");
} elsif (STORAGEHOST()) {
@bootscripts = ("rc.misc","rc.localize","rc.keys");
}
else {
@bootscripts = ("rc.firewall", "rc.tpmsetup",
......
......@@ -52,7 +52,7 @@ use Exporter;
SIMTRAFGEN SIMHOST ISDELAYNODEPATH JAILHOST DELAYHOST STARGATE
ISFW FAKEJAILED LINUXJAILED GENVNODE GENVNODETYPE GENVNODEHOST
SHAREDHOST SUBBOSS
SHAREDHOST SUBBOSS STORAGEHOST
CONFDIR LOGDIR TMDELAY TMBRIDGES TMJAILNAME TMSIMRC TMCC TMCCBIN
TMNICKNAME TMSTARTUPCMD FINDIF
......@@ -510,6 +510,7 @@ sub JAILHOST() { return (($role eq "virthost" ||
$role eq "sharedhost") ? 1 : 0); }
sub GENVNODEHOST() { if ($role eq "virthost") { return 1; } else { return 0; }}
sub SHAREDHOST() { return ($role eq "sharedhost" ? 1 : 0); }
sub STORAGEHOST() { return ($role eq "storagehost" ? 1 : 0); }
# A delay host? Either a delay node or a node using linkdelays
sub DELAYHOST() { if (-e ISDELAYNODEPATH()) { return 1; } else { return 0; } }
......
......@@ -376,7 +376,7 @@ sub doboot()
#
# For SHAREDHOSTs we now use clusterd (no pubsubd or evproxy).
#
if (SHAREDHOST()) {
if (SHAREDHOST() || STORAGEHOST()) {
#
# Kill off pubsubd and start clusterd.
#
......
......@@ -52,7 +52,7 @@ sub LINKDELAYHOST() { if (-e TMLINKDELAY()) { return 1; } else { return 0; } }
# Exit if not a valid node to run linktest on.
#
exit(0)
if (MFS() || REMOTE() || SIMHOST() || JAILHOST() ||
if (MFS() || REMOTE() || SIMHOST() || JAILHOST() || STORAGEHOST() ||
(DELAYHOST() && !LINKDELAYHOST()));
#
......
......@@ -110,6 +110,8 @@ my $FREENAS_MNT_PREFIX = "/mnt";
my $ISCSI_GLOBAL_PORTAL = 1;
my $SER_PREFIX = "d0d0";
my $VLAN_IFACE_PREFIX = "vlan";
my $MAX_BUSY_COUNT = 5;
my $SLICE_BUSY_WAIT = 10;
# storageconfig constants
# XXX: should go somewhere more general
......@@ -292,6 +294,7 @@ sub vnodeCreate($$$$)
{
my ($vnode_id, undef, $vnconfig, $private) = @_;
my $vninfo = $private;
my $cleanup = 0;
# Create vmid from the vnode's name.
my $vmid;
......@@ -312,19 +315,29 @@ sub vnodeCreate($$$$)
# Create the experimental net (tagged vlan) interface
if (createVlanInterface($vnode_id, $vnconfig) != 0) {
TBScriptUnlock();
fatal("blockstore_vnodeCreate: ".
"Failed to create experimental network interface!");
$cleanup = 1;
warn("blockstore_vnodeCreate: ".
"Failed to create experimental network interface!");
}
# Create blockstore slice
if (runBlockstoreCmds($vnode_id, $vnconfig, $private) != 0) {
TBScriptUnlock();
fatal("blockstore_vnodeCreate: ".
"Blockstore slice creation failed!");
$cleanup = 1;
warn("blockstore_vnodeCreate: ".
"Blockstore slice creation failed!");
}
# Rain or shine, the creation attempt is done, so unlock.
TBScriptUnlock();
# Try to cleanup if something failed above. Existing callers
# appear to assume that if vnodeCreate() fails, then they don't
# need to do anything to clean up ...
if ($cleanup) {
vnodeDestroy($vnode_id, $vmid, $vnconfig, $private);
fatal("Failed creation attempt aborted.");
}
return $vmid;
}
......@@ -431,16 +444,23 @@ sub vnodeDestroy($$$$){
}
# Run through blockstore removal commands (reversed creation list).
my $failed = 0;
foreach my $sconf (@revconfigs) {
my $cmd = $sconf->{'CMD'};
if (exists($teardown_cmds{$cmd})) {
if ($teardown_cmds{$cmd}->($vnode_id, $sconf,
$vnconfig, $private) != 0) {
TBScriptUnlock();
fatal("blockstore_vnodeDestroy: ".
"Failed to execute teardown command: $cmd");
warn("*** ERROR: blockstore_vnodeDestroy: ".
"Teardown command failed: $cmd");
# Don't die yet. We want to try removing the
# interface first. Do jump out of this loop however
# since subsequent commands here may also fail (and
# perhaps cause worse fallout).
$failed = 1;
last;
}
} else {
# Escape hatch for unknown command.
TBScriptUnlock();
fatal("blockstore_vnodeDestroy: ".
"Don't know how to execute: $cmd");
......@@ -456,6 +476,7 @@ sub vnodeDestroy($$$$){
}
TBScriptUnlock();
die() if $failed; # If the command loop above failed, die now.
return 0;
}
......@@ -496,16 +517,13 @@ sub vnodeUnmount($$$$)
# such things. We check that the incoming verb is valid. Command line
# argument string needs to be untainted or this will fail.
#
# Returns numberic code indicating success, failure, internal error.
# Throws exceptions (dies), passing along errors in $@.
#
sub runFreeNASCmd($$) {
my ($verb, $argstr) = @_;
if (!exists($cliverbs{$verb})) {
warn("*** ERROR: blockstore_runFreeNASCmd: ".
"Invalid FreeNAS CLI verb: $verb");
return -1;
}
die "Invalid FreeNAS CLI verb: $verb"
unless exists($cliverbs{$verb});
print "DEBUG: blockstore_runFreeNASCmd:\n".
"\trunning: $verb $argstr\n" if $debug;
......@@ -513,17 +531,20 @@ sub runFreeNASCmd($$) {
my $output = `$FREENAS_CLI $verb $argstr`;
if ($? != 0) {
print STDERR $output if $debug;
warn("*** ERROR: blockstore_runFreeNASCmd: ".
"Error returned from FreeNAS CLI: $?");
return -1;
die "Error returned from FreeNAS CLI: $?";
}
if ($output =~ /"error": false/) {
$output =~ /"error": (true|false)/;
my $errstate = $1;
$output =~ /"message": "([^"]+)"/;
my $message = $1;
if ($errstate eq "false") {
return 0;
}
print STDERR $output if $debug;
return 1;
die $message;
}
# Run our custom FreeNAS CLI to extract info.
......@@ -774,11 +795,11 @@ sub allocSlice($$$$) {
# Allocate slice in zpool
# XXX: check on size conversion.
if (runFreeNASCmd($CLI_VERB_VOLUME,
"add $bsid $vnode_id ${size}MB off") != 0)
{
eval { runFreeNASCmd($CLI_VERB_VOLUME,
"add $bsid $vnode_id ${size}MB off") };
if ($@) {
warn("*** ERROR: blockstore_allocSlice: ".
"slice allocation failed!");
"slice allocation failed: $@");
return -1;
}
......@@ -844,11 +865,11 @@ sub exportSlice($$$$) {
my $iqn = $1; # untaint.
# Create iSCSI extent
if (runFreeNASCmd($CLI_VERB_IST_EXTENT,
"add $iqn $bsid/$vnode_id") != 0)
{
eval { runFreeNASCmd($CLI_VERB_IST_EXTENT,
"add $iqn $bsid/$vnode_id") };
if ($@) {
warn("*** ERROR: blockstore_exportSlice: ".
"Failed to create iSCSI extent!");
"Failed to create iSCSI extent: $@");
return -1;
}
......@@ -860,31 +881,31 @@ sub exportSlice($$$$) {
return -1;
}
$tag = $1; # untaint.
if (runFreeNASCmd($CLI_VERB_IST_AUTHI,
"add $tag ALL $network/$cmask") != 0)
{
eval { runFreeNASCmd($CLI_VERB_IST_AUTHI,
"add $tag ALL $network/$cmask") };
if ($@) {
warn("*** ERROR: blockstore_exportSlice: ".
"Failed to create iSCSI auth group!");
"Failed to create iSCSI auth group: $@");
return -1;
}
# Create iSCSI target
my $serial = genSerial();
if (runFreeNASCmd($CLI_VERB_IST_TARGET,
eval { runFreeNASCmd($CLI_VERB_IST_TARGET,
"add $iqn $serial $ISCSI_GLOBAL_PORTAL ".
"$tag Auto -1") != 0)
{
"$tag Auto -1") };
if ($@) {
warn("*** ERROR: blockstore_exportSlice: ".
"Failed to create iSCSI target!");
"Failed to create iSCSI target: $@");
return -1;
}
# Bind iSCSI target to slice (extent)
if (runFreeNASCmd($CLI_VERB_IST_ASSOC,
"add $iqn $iqn") != 0)
{
eval { runFreeNASCmd($CLI_VERB_IST_ASSOC,
"add $iqn $iqn") };
if ($@) {
warn("*** ERROR: blockstore_exportSlice: ".
"Failed to associate iSCSI target with extent!");
"Failed to associate iSCSI target with extent: $@");
return -1;
}
......@@ -1062,22 +1083,20 @@ sub createVlanInterface($$) {
}
# First, create the vlan interface:
my $rval = runFreeNASCmd($CLI_VERB_VLAN,
"add $piface $viface $vtag");
if ($rval != 0) {
eval { runFreeNASCmd($CLI_VERB_VLAN,
"add $piface $viface $vtag") };
if ($@) {
warn("*** ERROR: blockstore_createVlanInterface: ".
"failure while creating vlan interface!");
"failure while creating vlan interface: $@");
return -1;
}
# Next, set its address.
$rval = runFreeNASCmd($CLI_VERB_IFACE,
"add $viface $viface $ip/$mask");
if ($rval != 0) {
eval { runFreeNASCmd($CLI_VERB_IFACE,
"add $viface $viface $ip/$mask") };
if ($@) {
warn("*** ERROR: blockstore_setVlanInterfaceIPAddress: ".
"failure while setting vlan interface parameters!");
"failure while setting vlan interface parameters: $@");
return -1;
}
......@@ -1116,12 +1135,11 @@ sub removeVlanInterface($$) {
}
# Delete it!
my $rval = runFreeNASCmd($CLI_VERB_VLAN,
"del $viface");
if ($rval != 0) {
eval { runFreeNASCmd($CLI_VERB_VLAN,
"del $viface") };
if ($@) {
warn("*** ERROR: blockstore_removeVlanInterface: ".
"failure while removing vlan interface!");
"failure while removing vlan interface: $@");
return -1;
}
......@@ -1156,22 +1174,13 @@ sub unexportSlice($$$$) {
$sconf->{'UUID'} =~ /^([-\.:\w]+)$/;
my $iqn = $1; # untaint.
# Remove iSCSI extent. This will also zap the target-to-extent
# Remove iSCSI target. This will also zap the target-to-extent
# association.
if (runFreeNASCmd($CLI_VERB_IST_EXTENT,
"del $iqn") != 0)
{
eval { runFreeNASCmd($CLI_VERB_IST_TARGET,
"del $iqn") };
if ($@) {
warn("*** ERROR: blockstore_unexportSlice: ".
"Failed to remove iSCSI extent!");
return -1;
}
# Remove iSCSI target.
if (runFreeNASCmd($CLI_VERB_IST_TARGET,
"del $iqn") != 0)
{
warn("*** ERROR: blockstore_unexportSlice: ".
"Failed to remove iSCSI target!");
"Failed to remove iSCSI target: $@");
return -1;
}
......@@ -1183,11 +1192,21 @@ sub unexportSlice($$$$) {
return -1;
}
$tag = $1; # untaint.
if (runFreeNASCmd($CLI_VERB_IST_AUTHI,
"del $tag") != 0)
{
eval { runFreeNASCmd($CLI_VERB_IST_AUTHI,
"del $tag") };
if ($@) {
warn("*** ERROR: blockstore_unexportSlice: ".
"Failed to remove iSCSI auth group!");
"Failed to remove iSCSI auth group: $@");
return -1;
}
# Remove iSCSI extent.
eval { runFreeNASCmd($CLI_VERB_IST_EXTENT,
"del $iqn") };
if ($@) {
warn("*** ERROR: blockstore_unexportSlice: ".
"Failed to remove iSCSI extent: $@");
return -1;
}
......@@ -1225,17 +1244,36 @@ sub deallocSlice($$$$) {
}
# deallocate slice.
if (runFreeNASCmd($CLI_VERB_VOLUME,
"del $bsid $vnode_id") != 0)
{
warn("*** ERROR: blockstore_deallocSlice: ".
"slice removal failed!");
return -1;
my $busycount;
for ($busycount = 1; $busycount <= $MAX_BUSY_COUNT; $busycount++) {
eval { runFreeNASCmd($CLI_VERB_VOLUME,
"del $bsid $vnode_id") };
if ($@) {
if ($@ =~ /dataset is busy/) {
warn("*** WARNING: blockstore_deallocSlice: ".
"Slice is busy. Waiting a bit before trying ".
"to free again (count=$busycount).");
TBScriptUnlock(); # Don't hold up the queue. Hopefully safe!
sleep $SLICE_BUSY_WAIT;
} else {
warn("*** ERROR: blockstore_deallocSlice: ".
"slice removal failed: $@");
return -1;
}
} else {
# No error condition - jump out of loop.
last;
}
}
# Checks for lingering slices will be performed separately in
# consistency checking routines, so we don't bother here to
# check that the above actually succeeded.
# Note: Checks for lingering slices will be performed separately in
# consistency checking routines.
if ($busycount > $MAX_BUSY_COUNT) {
warn("*** WARNING: blockstore_deallocSlice: ".
"Could not free slice after several attempts!");
return -1;
}
return 0;
}
......
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