Commit 9375fe41 authored by Mike Hibler's avatar Mike Hibler

Further optimize the case where there is nothing to do.

Even when there were no changes, we were stat'ing every mountpoint.
Now we wait til after we have determined that something has changed before
we test the mountpoints.

Also, just open and append to files directly in perl rather than exec'ing
a "cat" to do it.
parent 8b120acb
#!/usr/bin/perl -wT
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -44,6 +44,7 @@ getopts('Si', \%opts);
my $TBOPS = "@TBOPSEMAIL@";
my $LINUX_FSNODE= @LINUX_FSNODE@;
my $INC_MOUNTD = @INCREMENTAL_MOUNTD@;
my $DIFFDIR = "@prefix@/log/exports";
my $etcdir;
my $exports;
......@@ -118,81 +119,58 @@ use lib "@prefix@/lib";
use libtestbed;
#
# Take our input and write it to the tail file.
# Create a new exports file by concatonating a bunch of pieces
#
open(TAIL, ">$exportstail") || fatal("Couldn't open $exportstail\n");
while (<STDIN>) {
sub buildexports($$$) {
my ($out, $head, $tail) = @_;
#
# Pass through if samba or a comment or blank line.
# We don't test samba lines since we assume the samba invocation
# of us (-S) will follow the normal invocation and have the same
# directories.
# Generate a warning so that no one tries to edit the file by hand
#
if ($issamba || $_ !~ /^\//) {
print TAIL $_;
next;
}
open(OUT, ">$out") or
fatal("Couldn't create $out\n");
print OUT <<EOF;
#
# ******************************************************************
# DO NOT EDIT THIS FILE. IT IS A CREATION, A FIGMENT, A CONTRIVANCE!
#
# Edit $exportshead, then run exports_setup on boss.
# ******************************************************************
#
EOF
;
#
# As we do this, we parse the lines and check each of the exported
# filesystems to make sure they exist. Otherwise mountd may prematurely
# fail. We used to do this on the boss-side, but that would stat the
# directories across NFS, and in some cases, before the filesystem
# was even exported!
# Now tack on the head and tail of the file.
#
my @tokens = ();
my $numdirs = 0;
my $dirsdone = 0;
foreach my $token (split) {
if (!$dirsdone) {
# starts with a slash, assume it is an exported dir
if ($token =~ /^\//) {
if (! -d "$token") {
print STDERR "$token: does not exist, ignored\n";
next;
}
$numdirs++;
} else {
$dirsdone = 1;
}
foreach my $file ($head, $tail) {
open(IN, "<$file") or
fatal("Failed to concat $file to $out\n");
while (<IN>) {
print OUT "$_";
}
push(@tokens, $token);
}
# if there were valid directories to export, do so
if ($numdirs > 0) {
print TAIL join(' ', @tokens), "\n";
close(IN);
}
close(OUT);
chmod(0644, $out);
}
close(TAIL);
chmod(0444, $exportstail);
#
# Generate a warning so that no one tries to edit the file by hand
#
open(MAP, ">$exportsnew") || fatal("Couldn't open $exportsnew\n");
print MAP
"#\n".
"# ******************************************************************\n".
"# DO NOT EDIT THIS FILE. IT IS A CREATION, A FIGMENT, A CONTRIVANCE!\n".
"#\n".
"# Edit $exportshead, then run exports_setup on boss.\n".
"# ******************************************************************\n".
"#\n";
close(MAP);
chmod(0644, $exportsnew);
# Take our input and write it to the tail file.
#
# Now tack on the head part of the file.
# We do this without any pre-checking of the contents to optimize the
# relatively common case of being called when nothing has changed.
#
system("cat $exportshead >> $exportsnew") == 0 or
fatal("Failed to concat $exportshead to $exportsnew\n");
open(TAIL, ">$exportstail") || fatal("Couldn't open $exportstail\n");
while (<STDIN>) {
print TAIL $_;
}
close(TAIL);
chmod(0444, $exportstail);
#
# Now the tail of the file.
#
system("cat $exportstail >> $exportsnew") == 0 or
fatal("Failed to concat $exportstail to $exportsnew\n");
buildexports($exportsnew, $exportshead, $exportstail);
#
# Do nothing if no change.
......@@ -205,16 +183,78 @@ my $outfile;
if ($issamba) {
system("/usr/bin/diff -q $exports $exportsnew >/dev/null");
} else {
$outfile = "/tmp/exports_diff." . time();
if (-d "$DIFFDIR") {
$outfile = "$DIFFDIR/diff." . time();
} else {
$outfile = "/dev/null";
}
system("/usr/bin/diff $exports $exportsnew >$outfile 2>&1");
}
if (! $?) {
# print "No changes to $exports; skipping ...\n";
unlink($outfile)
if ($outfile);
if ($outfile && $outfile ne "/dev/null");
exit(0);
}
#
# Go back and re-parse the file and stat each of the exported filesystems
# to make sure they exist. Otherwise mountd may prematurely fail. We used
# to do this on the boss-side, but that would stat the directories across
# NFS, and in some cases, before the filesystem was even exported!
#
# Note that we do not do this for samba as we assume that the samba
# invocation (-S) of this script will follow the normal invocation and
# have the same directories.
#
if (!$issamba) {
my $changed = 0;
open(TAIL, "<$exportstail") || fatal("Couldn't open $exportstail\n");
open(NTAIL, ">$exportstail.new") || fatal("Couldn't open $exportstail.new\n");
while(<TAIL>) {
if ($_ !~ /^\//) {
print NTAIL $_;
next;
}
my @tokens = ();
my $numdirs = 0;
my $dirsdone = 0;
foreach my $token (split) {
if (!$dirsdone) {
# starts with a slash, assume it is an exported dir
if ($token =~ /^\//) {
if (! -d "$token") {
print STDERR "$token: does not exist, ignored\n";
$changed++;
next;
}
$numdirs++;
} else {
$dirsdone = 1;
}
}
push(@tokens, $token);
}
if ($numdirs > 0) {
print NTAIL join(' ', @tokens), "\n";
}
}
close(TAIL);
close(NTAIL);
#
# If there was a bogus directory in the tail file, we have to recreate
# the new exports file again.
#
if ($changed) {
buildexports($exportsnew, $exportshead, "$exportstail.new");
}
unlink("$exportstail.new");
}
#
# Back up the existing exports, and then mv in the new one.
#
......
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