Commit 4109cb4b authored by Mike Hibler's avatar Mike Hibler

Add new "imageinfo" command and use it in tmcd and libosload.

Imageinfo hides the nastiness of what we need to do to get size or mtime
info about shared images for which the caller does not have direct access.
In these cases we need to make a proxied frisbee master server query and
parse its output.
parent e08bfeec
......@@ -50,9 +50,9 @@ my $TBLOADWAIT = (10 * 60);
my $OUTERBOSS = "@OUTERBOSS_NODENAME@";
my $osselect = "$TB/bin/os_select";
my $TBUISP = "$TB/bin/tbuisp";
my $IMAGEINFO = "$TB/sbin/imageinfo";
# Locals
my $FRISBEE = "$TB/sbin/frisbee";
my %imageinfo = (); # Per imageid DB info.
my $debug = 0;
my %children = (); # Child pids in when asyncmode=1
......@@ -798,15 +798,12 @@ sub GetImageInfo($;$)
#
# For either case, making a proxy query request via frisbee will
# tell us whether the image is accessible and, if so, its size.
# "imageinfo" makes that call for us.
#
my $frisimageid = $rowref->{'pid'} . "/" . $rowref->{'imagename'};
my $attr = `$FRISBEE -S localhost -Q $frisimageid -P $node`;
if ($attr =~ /error=0/) {
if ($attr =~ /size=(\d+)/) {
$imagesize = $1;
} else {
$imagesize = 1 * 1024 * 1024 * 1024;
}
my $sizestr = `$IMAGEINFO -qs -N $node $frisimageid`;
if ($sizestr =~ /^(\d+)$/) {
$imagesize = $1;
} else {
tberror "$image: access not allowed or image does not exist.";
$imageinfo{$imageid} = 'BADIMAGE';
......
......@@ -4849,12 +4849,42 @@ COMMAND_PROTOTYPE(doloadinfo)
return 1;
}
else if (stat(row[10], &sb)) {
error("doloadinfo: %s: Could not stat path %s"
" associated with imageid %s: %s\n",
reqp->nodeid, row[10], row[5],
strerror(errno));
mysql_free_result(res);
return 1;
char _buf[512];
FILE *cfd;
/*
* The image may not be directly
* accessible since tmcd runs as
* "nobody". If so, use the imageinfo
* helper to get the info via the
* frisbee master server.
*/
snprintf(_buf, sizeof _buf,
"%s/sbin/imageinfo -qm -N %s "
"%s/%s",
TBROOT, reqp->isvnode ?
reqp->pnodeid : reqp->nodeid,
row[8], row[7]);
if ((cfd = popen(_buf, "r")) == NULL) {
badimage:
error("doloadinfo: %s: "
"Could not determine "
"mtime for %s/%s\n",
reqp->nodeid,
row[8], row[7]);
mysql_free_result(res);
return 1;
}
_buf[0] = 0;
fgets(_buf, sizeof _buf, cfd);
pclose(cfd);
sb.st_mtime = 0;
if (_buf[0] != 0 && _buf[0] != '\n') {
sscanf(_buf, "%u",
&sb.st_mtime);
}
if (sb.st_mtime == 0)
goto badimage;
}
bufp += OUTPUT(bufp, ebufp - bufp,
" IMAGEMTIME=%u\n",
......
......@@ -30,7 +30,7 @@ SBIN_SCRIPTS = vlandiff vlansync withadminprivs export_tables cvsupd.pl \
prereserve grantimage getimages localize_mfs \
management_iface sharevlan check-shared-bw \
addspecialdevice addspecialiface imagehash clone_image \
addvpubaddr
addvpubaddr imageinfo
WEB_SBIN_SCRIPTS= webnewnode webdeletenode webspewconlog webarchive_list \
webwanodecheckin webspewimage
......@@ -90,7 +90,7 @@ post-install:
chmod u+s $(INSTALL_LIBEXECDIR)/xlogin
#
# Control node installation (okay, plastic)
# Control node installation (aka, ops)
#
control-install:
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2012 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
use strict;
use Getopt::Std;
use File::stat;
#
# Get basic info for an image.
#
# This is intended for use by non-admin process on boss which might have
# Emulab-permitted download access but not physical access to the image
# (i.e., it is a shared image). Uses the frisbee mserver to get the info.
#
sub usage()
{
print("Usage: imageinfo [-N nodeid] [-s] [-m] <imageid>\n" .
"Options:\n".
" -d Turn on debug mode\n".
" -N nodeid Use the frisbee master server to get info on behalf of nodeid\n".
" -q Don't print message on error, just exit non-zero\n".
" -s Just print the size of the image in bytes\n".
" -m Just print the modtime of the image in seconds since epoch\n");
exit(-1);
}
my $optlist = "dsmN:q";
my $debug = 0;
my $quiet = 0;
my $showall = 1;
my $showsize = 0;
my $showmtime = 0;
my $nodeid;
#
# Configure variables
#
my $TB = "@prefix@";
my $frisbee = "$TB/sbin/frisbee";
# Protos
sub fatal($);
#
# Untaint the path
#
$ENV{'PATH'} = "$TB/bin:$TB/sbin:/bin:/usr/bin:/usr/bin:/usr/sbin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
#
# Turn off line buffering on output
#
$| = 1;
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use Node;
use Image;
#
# Parse command arguments. Once we return from getopts, all that should be
# left are the required arguments.
#
my %options = ();
if (! getopts($optlist, \%options)) {
usage();
}
if (defined($options{"d"})) {
$debug = 1;
}
if (defined($options{"q"})) {
$quiet = 1;
}
if (defined($options{"s"})) {
$showsize = 1;
$showall = $showmtime = 0;
}
if (defined($options{"m"})) {
$showmtime = 1;
$showall = $showsize = 0;
}
if (defined($options{"N"})) {
my $node = Node->Lookup($options{"N"});
if (!defined($node)) {
fatal("No such node exists");
}
$nodeid = $node->node_id();
}
usage()
if (@ARGV != 1);
my $image = Image->Lookup($ARGV[0]);
if (!defined($image)) {
fatal("No such image exists");
}
my $imagename = $image->imagename();
my $imagepid = $image->pid();
my $imagepath = $image->path();
if (!defined($nodeid) && ! -R $imagepath) {
fatal("$imagepid/$imagename: image file is not readable, must use -N\n");
}
my ($isize, $imtime);
if (!defined($nodeid)) {
print STDERR "Doing stat on $imagepath\n"
if ($debug);
$isize = stat($imagepath)->size;
$imtime = stat($imagepath)->mtime;
} else {
print STDERR "Using frisbee on $imagepid/$imagename\n"
if ($debug);
my $attr = `$frisbee -S localhost -Q $imagepid/$imagename -P $nodeid`;
if ($attr =~ /error=0/) {
if ($attr =~ /size=(\d+)/) {
$isize = $1;
}
if ($attr =~ /sigtype=0x1/ && $attr =~ /sig=(0x[0-9a-f]+)/) {
$imtime = hex($1);
}
} else {
fatal("$imagepid/$imagename: access not allowed or image does not exist");
}
}
if ($showall) {
if (defined($isize)) {
printf "size=%lu\n", $isize;
}
if (defined($imtime)) {
printf "mtime=%lu\n", $imtime;
}
} elsif ($showsize && defined($isize)) {
printf "%lu\n", $isize;
} elsif ($showmtime && defined($imtime)) {
printf "%lu\n", $imtime;
}
exit(0);
sub fatal($)
{
my ($mesg) = $_[0];
exit(-1)
if ($quiet);
die("*** $0:\n".
" $mesg\n");
}
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