Commit 68ef86b0 authored by Mike Hibler's avatar Mike Hibler

Finish ZFS_NOEXPORT support for NFS-based admin MFS filesystems.

This gets rid of the last vestige of reliance on the ZFS sharenfs
attribute for exporting the NFS MFSes. Twas a royal PITA.
parent e646215f
......@@ -386,7 +386,7 @@ sub TB_OSID_VERSLEN() { 12; }
sub TB_OSID_MBKERNEL() { "_KERNEL_"; } # multiboot kernel OSID
# Magic OSID path
sub TB_OSID_PATH_NFS() { "fs:/nfsroot" };
sub TB_OSID_PATH_NFS() { "@NFSMFS_ROOT@" ? "fs:@NFSMFS_ROOT@" : "" };
# Magic MFS constants
sub TB_OSID_FREEBSD_MFS() { "FREEBSD-MFS" };
......
......@@ -4467,5 +4467,24 @@ sub HasStartupAgent($)
return $query_result->numrows;
}
#
# Check and see if the node is currently in the admin MFS or would be at
# the next reboot (i.e., someone has done "node_admin -n on").
#
# This is for nodes where we need to construct or grant access to a
# node-specific admin MFS instance. Currently this is only used for NFS-based
# admin MFSes on the Moonshot nodes.
#
sub NeedsAdminMFS($)
{
my ($self) = @_;
if ($self->op_mode() eq "PXEFBSD" || $self->next_op_mode() eq "PXEFBSD") {
return 1;
}
return 0;
}
# _Always_ make sure that this 1 is at the end of the file...
1;
......@@ -69,7 +69,7 @@ use vars qw(@ISA @EXPORT);
TBSetExptFirewallVlan TBClearExptFirewallVlan
TBNodeConsoleTail TBExptGetSwapoutAction TBExptGetSwapState
TBNodeSubNodes
TBNodeAdminOSID TBNodeDiskloadOSID
TBNodeAdminOSID TBNodeNFSAdmin TBNodeDiskloadOSID
TBNodeType TBNodeTypeProcInfo TBNodeTypeBiosWaittime
TBExptPortRange
TBWideareaNodeID TBTipServers
......@@ -1532,6 +1532,22 @@ sub TBNodeAdminOSID($)
return 0;
}
#
# Returns 1 if node uses NFS-based admin MFS, 0 ow.
#
sub TBNodeNFSAdmin($)
{
my ($nodeid) = @_;
my $node = LocalNodeLookup($nodeid);
if ($node) {
require OSImage;
return OSImage->Lookup($node->adminmfs_osid())->IsNfsMfs();
}
return 0;
}
sub TBNodeDiskloadOSID($)
{
my ($nodeid) = @_;
......
......@@ -50,6 +50,7 @@ my $quiet = 0;
# Configure variables
my $TB = "@prefix@";
my $TESTMODE = @TESTMODE@;
my $NFSMFS = "@NFSMFS_ROOT";
# Turn off line buffering on output
$| = 1;
......@@ -473,7 +474,7 @@ foreach my $node (@freed_nodes) {
#
# Remember if node has a dynamic (aka, NFS) MFS
#
if (OSImage->Lookup($node->adminmfs_osid())->IsNfsMfs()) {
if ($NFSMFS && OSImage->Lookup($node->adminmfs_osid())->IsNfsMfs()) {
push(@dynmfsnodes, $node_id);
}
......@@ -717,7 +718,7 @@ if (@dynanodes) {
# XXX make sure that the nodes have destroyed their dynamic
# (aka NFS-based) MFSes.
#
if (@dynmfsnodes) {
if ($NFSMFS && @dynmfsnodes) {
system("$dynmfssetup -Df @dynmfsnodes") == 0 ||
print STDERR "*** WARNING: could not remove MFSes for @dynmfsnodes!\n";
}
......
......@@ -82,6 +82,7 @@ my $WITHAMD = @WITHAMD@;
my $INC_MOUNTD = @INCREMENTAL_MOUNTD@;
my $NOVNODENFS = @NOVIRTNFSMOUNTS@;
my $TBLOG = "@TBLOGFACIL@";
my $NFSMFSROOT = "@NFSMFS_ROOT@";
# XXX for TESTMODE: output to stdout
my $TOSTDOUT = 0;
......@@ -249,7 +250,8 @@ $nodes_result =
" i.IP,u.admin,r.sharing_mode,r.erole,nt.isvirtnode, ".
" e.nfsmounts as e_nfsmounts, ".
" n.nfsmounts as n_nfsmounts, ".
" va.attrvalue as routable_ip ".
" va.attrvalue as routable_ip, ".
" n.op_mode,n.next_op_mode ".
"from reserved as r ".
"left join experiments as e on r.pid=e.pid and r.eid=e.eid ".
"left join nodes as n on r.node_id=n.node_id ".
......@@ -338,6 +340,7 @@ my $lastpid = "";
my $lastgid = "";
my $lastadmin = "";
my $lasterole = "";
my @nfsmfsnodes = ();
my @mountpoints = fsinit();
......@@ -378,6 +381,17 @@ while ($row = $nodes_result->fetchrow_hashref) {
next;
}
# If we support NFS-based MFS, remember nodes that need an MFS exported
# XXX we do this before eliminating non-nfs experiment nodes
if ($NFSMFSROOT && $WITHZFS && $ZFS_NOEXPORT) {
if (defined($row->{'op_mode'}) && defined($row->{'next_op_mode'}) &&
($row->{'op_mode'} eq "PXEFBSD" ||
$row->{'next_op_mode'} eq "PXEFBSD") &&
TBNodeNFSAdmin($node_id)) {
push(@nfsmfsnodes, $node_id);
}
}
# Skip nodes that belong to a "no nfs" experiment or are marked "no nfs".
next
if ($enonfs || $nnonfs || $enfs eq "none" ||
......@@ -602,6 +616,24 @@ if ($ZFS_NOEXPORT) {
push(@bossmounts, $fs);
}
}
#
# If we have any NFS-based MFS filesystems, export those.
#
foreach my $node (sort(@nfsmfsnodes)) {
my $str = "$NFSMFSROOT/$node";
if ($LINUX_FSNODE) {
print MAP "$str -rw,no_root_squash,no_subtree_check $node\n";
print "$str -rw,no_root_squash,no_subtree_check $node\n"
if ($debug);
}
else {
print MAP "$str -maproot=$NFSMAPTOUSER $node\n";
print "$str -maproot=$NFSMAPTOUSER $node\n"
if ($debug);
}
}
}
close(MAP);
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -45,6 +45,7 @@ my $TBOPS = "@TBOPSEMAIL@";
my $LINUX_FSNODE= @LINUX_FSNODE@;
my $INC_MOUNTD = @INCREMENTAL_MOUNTD@;
my $DIFFDIR = "@prefix@/log/exports";
my $NFSROOT = "@NFSMFS_ROOT@";
my $etcdir;
my $exports;
......@@ -163,8 +164,19 @@ EOF
# We do this without any pre-checking of the contents to optimize the
# relatively common case of being called when nothing has changed.
#
# XXX one exception: if this is an NFS-based MFS filesystem, we have to
# check and see if the FS has been renamed. When we do a "node_admin off"
# we rename the "pcX" FS to "pcX-DEAD" because we don't want to yank the
# FS out from under the node while it is still running. But this is done
# on "fs" (nfsmfs_setup.proxy) and "boss" doesn't know about it, so it will
# continue to tell us "pcX" should be exported.
#
open(TAIL, ">$exportstail") || fatal("Couldn't open $exportstail\n");
while (<STDIN>) {
if (/^($NFSROOT\/\S+)/ && ! -d "$1" && -d "$1-DEAD") {
my $str = $1;
s/$str/$str-DEAD/;
}
print TAIL $_;
}
close(TAIL);
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2005-2016 University of Utah and the Flux Group.
# Copyright (c) 2005-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -60,6 +60,7 @@ my $TB = "@prefix@";
my $TESTMODE = @TESTMODE@;
my $TBOPS = "@TBOPSEMAIL@";
my $ELABINELAB = @ELABINELAB@;
my $NFSMFS = "@NFSMFS_ROOT@";
my $nodereboot = "$TB/bin/node_reboot";
my $power = "$TB/bin/power";
......@@ -622,6 +623,8 @@ sub TBAdminMfsCreate($$@)
{
my ($args, $failedref, @nodes) = @_;
return 0
if (!$NFSMFS);
return 0
if (@nodes == 0);
......@@ -681,6 +684,8 @@ sub TBAdminMfsDestroy($$@)
{
my ($args, $failedref, @nodes) = @_;
return 0
if (!$NFSMFS);
return 0
if (@nodes == 0);
......
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
# Copyright (c) 2000-2017 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -59,8 +59,11 @@ my $TBOPS = "@TBOPSEMAIL@";
my $TESTMODE = @TESTMODE@;
my $FSNODE = "@FSNODE@";
my $WITHZFS = @WITHZFS@;
my $ZFSNOEXPORT = "@ZFS_NOEXPORT@";
my $SSH = "$TB/bin/sshtb -n -l root -host $FSNODE";
my $PROG = "$TB/sbin/nfsmfs_setup.proxy";
my $EXPORTSSETUP= "$TB/sbin/exports_setup";
my $NFSROOT = "@NFSMFS_ROOT@";
#
# We don't want to run this script unless its the real version.
......@@ -78,6 +81,11 @@ if ($WITHZFS == 0) {
" Only implemented with ZFS FS node right now.\n");
}
if ($NFSROOT eq "") {
die("*** $0:\n".
" Must set NFSMFS_ROOT in defs file.");
}
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/sbin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
......@@ -152,7 +160,8 @@ foreach my $nodeid (@ARGV) {
}
if (!$nocheck) {
if (OSImage->Lookup($nodeobj->adminmfs_osid())->IsNfsMfs()) {
if (OSImage->Lookup($nodeobj->adminmfs_osid())->IsNfsMfs() &&
$nodeobj->NeedsAdminMFS()) {
push @nodes, $nodeid;
}
} else {
......@@ -184,6 +193,12 @@ if (!$TESTMODE) {
system("$SSH $PROG $opts @nodes") == 0 or
fatal("Failed: $SSH $PROG $opts @nodes: $?");
# XXX do exports_setup
if ($ZFSNOEXPORT) {
system($EXPORTSSETUP) == 0 or
fatal("$EXPORTSSETUP failed");
}
#
# Release the lock!
#
......
......@@ -47,8 +47,9 @@ my $force = 0;
#
my $TBOPS = "@TBOPSEMAIL@";
my $ZFSROOT = "@ZFS_ROOT@";
my $ZFSNOEXPORT = "@ZFS_NOEXPORT@";
my $MOUNTPOINT = "/nfsroot";
my $MOUNTPOINT = "@NFSMFS_ROOT@";
my $ZFS = "/sbin/zfs";
my $MOUNT = "/sbin/mount";
......@@ -89,6 +90,10 @@ if (! -x "$ZFS") {
fatal("Can only be used with ZFS right now!");
}
if ($MOUNTPOINT eq "") {
fatal("Must set NFSMFS_ROOT in defs file!");
}
if (defined($opts{'D'})) {
$destroy = 1;
}
......@@ -109,7 +114,7 @@ if (@ARGV < 1) {
#
# Make sure the golden filesystem exists
#
if (!$destroy && system("$ZFS list -o name -t snapshot | grep -q $GOLDEN")) {
if (!$destroy && system("$ZFS list -H $GOLDEN >/dev/null 2>&1")) {
fatal("ZFS snapshot '$GOLDEN' does not exist");
}
......@@ -197,8 +202,10 @@ foreach my $nodeid (@ARGV) {
# Create the MFS
if (!exists($mfs{$nodeid})) {
$cmd = "$ZFS clone -o sharenfs='$nodeid -maproot=root' $GOLDEN".
" $ZFSROOT$MOUNTPOINT/$nodeid";
# For ZFS_NOEXPORT, we rely on exports_setup to expose the FS
my $opt = $ZFSNOEXPORT ?
"" : "-o sharenfs='$nodeid -maproot=root'";
$cmd = "$ZFS clone $opt $GOLDEN $ZFSROOT$MOUNTPOINT/$nodeid";
if (mysystem($cmd)) {
push(@failed, $nodeid);
}
......@@ -208,12 +215,12 @@ foreach my $nodeid (@ARGV) {
}
#
# Odd...sometimes the (un)export doesn't happen
# Odd...sometimes the (un)export doesn't happen.
#
# XXX again, this can be a brutally expensive command, so only do it if
# we have to.
#
if ($changed) {
if (!$ZFSNOEXPORT && $changed) {
mysystem("$ZFS share -a");
}
......
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