Commit 48e85114 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge remote-tracking branch 'central/master' into imageversion

parents 95ca5100 33a20ab7
...@@ -82,6 +82,7 @@ use APT_Instance; ...@@ -82,6 +82,7 @@ use APT_Instance;
use GeniXML; use GeniXML;
use GeniHRN; use GeniHRN;
use WebTask; use WebTask;
use libaudit;
# Protos # Protos
sub fatal($); sub fatal($);
...@@ -378,7 +379,11 @@ if (defined($instance)) { ...@@ -378,7 +379,11 @@ if (defined($instance)) {
} }
# Let parent exit; # Let parent exit;
sleep(2); sleep(2);
POSIX::setsid(); if (0) {
AuditStart(0, undef, LIBAUDIT_LOGTBLOGS()|LIBAUDIT_LOGONLY());
AddAuditInfo("cc", "aptnet-logs\@flux.utah.edu");
}
POSIX::setsid();
} }
my $seconds = 1200; my $seconds = 1200;
my $interval = 5; my $interval = 5;
......
...@@ -377,7 +377,7 @@ main(int argc, char **argv) ...@@ -377,7 +377,7 @@ main(int argc, char **argv)
case 'C': case 'C':
mem = atoi(optarg); mem = atoi(optarg);
if (mem < 1) if (mem < 0)
mem = 1; mem = 1;
else if (mem > MAXCHUNKBUFS) else if (mem > MAXCHUNKBUFS)
mem = MAXCHUNKBUFS; mem = MAXCHUNKBUFS;
...@@ -386,7 +386,7 @@ main(int argc, char **argv) ...@@ -386,7 +386,7 @@ main(int argc, char **argv)
case 'W': case 'W':
mem = atoi(optarg); mem = atoi(optarg);
if (mem < 1) if (mem < 0)
mem = 1; mem = 1;
else if (mem > MAXWRITEBUFMEM) else if (mem > MAXWRITEBUFMEM)
mem = MAXWRITEBUFMEM; mem = MAXWRITEBUFMEM;
...@@ -406,7 +406,8 @@ main(int argc, char **argv) ...@@ -406,7 +406,8 @@ main(int argc, char **argv)
maxreadahead = atoi(optarg); maxreadahead = atoi(optarg);
if (maxinprogress < maxreadahead * 4) { if (maxinprogress < maxreadahead * 4) {
maxinprogress = maxreadahead * 4; maxinprogress = maxreadahead * 4;
if (maxinprogress > maxchunkbufs) if (maxchunkbufs > 0 &&
maxinprogress > maxchunkbufs)
maxinprogress = maxchunkbufs; maxinprogress = maxchunkbufs;
} }
break; break;
...@@ -1931,23 +1932,28 @@ PlayFrisbee(void) ...@@ -1931,23 +1932,28 @@ PlayFrisbee(void)
maxchunkbufs = TotalChunkCount; maxchunkbufs = TotalChunkCount;
/* /*
* If we have partitioned up the memory and have allocated * There is no point in having more chunkbufs than there are
* more chunkbufs than chunks in the file, reallocate the * chunks in the file. If we have partitioned up the memory,
* excess to disk buffering. If the user has explicitly * reallocate the excess to disk buffering. Otherwise, we just
* partitioned the memory, we leave everything as is. * adjust the chunkbuf count.
*/ */
if (maxmem != 0 && maxchunkbufs > TotalChunkCount) { if (maxchunkbufs > TotalChunkCount) {
int excessmb; if (maxmem != 0) {
int excessmb = (int)
excessmb = (int)((((unsigned long long) ((((unsigned long long)
(maxchunkbufs - TotalChunkCount) * (maxchunkbufs - TotalChunkCount) *
sizeof(ChunkBuffer_t)) / (1024 * 1024))); sizeof(ChunkBuffer_t)) / (1024 * 1024)));
maxchunkbufs = TotalChunkCount; if (excessmb > 0) {
if (excessmb > 0) { maxwritebufmem += excessmb;
maxwritebufmem += excessmb; ImageUnzipSetMemory((unsigned long long)
ImageUnzipSetMemory((unsigned long long) maxwritebufmem*1024*1024);
maxwritebufmem*1024*1024); }
} }
maxchunkbufs = TotalChunkCount;
if (maxinprogress > maxchunkbufs)
maxinprogress = maxchunkbufs;
if (maxreadahead > maxchunkbufs)
maxreadahead = maxchunkbufs;
} }
FrisLog("Joined the team after %d sec. ID is %u. " FrisLog("Joined the team after %d sec. ID is %u. "
......
...@@ -54,6 +54,7 @@ extern int debug; ...@@ -54,6 +54,7 @@ extern int debug;
struct emulab_configstate { struct emulab_configstate {
int image_maxsize; /* sitevar:images/create/maxsize (in GB) */ int image_maxsize; /* sitevar:images/create/maxsize (in GB) */
int image_maxwait; /* sitevar:images/create/maxwait (in min) */ int image_maxwait; /* sitevar:images/create/maxwait (in min) */
int image_maxiwait; /* sitevar:images/create/idlewait (in min) */
int image_maxrate_dyn; /* sitevar:images/frisbee/maxrate_dynamic */ int image_maxrate_dyn; /* sitevar:images/frisbee/maxrate_dynamic */
int image_maxrate_std; /* sitevar:images/frisbee/maxrate_std (in MB/s) */ int image_maxrate_std; /* sitevar:images/frisbee/maxrate_std (in MB/s) */
int image_maxrate_usr; /* sitevar:images/frisbee/maxrate_usr (in MB/s) */ int image_maxrate_usr; /* sitevar:images/frisbee/maxrate_usr (in MB/s) */
...@@ -99,6 +100,7 @@ static int INELABINELAB = 0; ...@@ -99,6 +100,7 @@ static int INELABINELAB = 0;
static uint64_t put_maxsize = 10000000000ULL; /* zero means no limit */ static uint64_t put_maxsize = 10000000000ULL; /* zero means no limit */
static uint32_t put_maxwait = 2000; /* zero means no limit */ static uint32_t put_maxwait = 2000; /* zero means no limit */
static uint32_t put_maxiwait = 120; /* zero means no limit */
static uint32_t get_maxrate_dyn = 0; /* non-zero means use dynamic */ static uint32_t get_maxrate_dyn = 0; /* non-zero means use dynamic */
static uint32_t get_maxrate_std = 72000000; /* zero means no limit */ static uint32_t get_maxrate_std = 72000000; /* zero means no limit */
static uint32_t get_maxrate_usr = 54000000; /* zero means no limit */ static uint32_t get_maxrate_usr = 54000000; /* zero means no limit */
...@@ -187,6 +189,17 @@ emulab_read(void) ...@@ -187,6 +189,17 @@ emulab_read(void)
FrisLog(" image_put_maxwait = %d min", FrisLog(" image_put_maxwait = %d min",
(int)(put_maxwait/60)); (int)(put_maxwait/60));
val = emulab_getsitevar("images/create/idlewait");
if (val) {
ival = atoi(val);
/* in minutes, allow up to about 10TB @ 10MB/sec */
if (ival >= 0 && ival < 20000)
put_maxiwait = (uint32_t)ival * 60;
free(val);
}
FrisLog(" image_put_maxiwait = %d min",
(int)(put_maxiwait/60));
val = emulab_getsitevar("images/frisbee/maxrate_dyn"); val = emulab_getsitevar("images/frisbee/maxrate_dyn");
if (val) { if (val) {
ival = atoi(val); ival = atoi(val);
...@@ -234,6 +247,7 @@ emulab_save(void) ...@@ -234,6 +247,7 @@ emulab_save(void)
cs->image_maxsize = put_maxsize; cs->image_maxsize = put_maxsize;
cs->image_maxwait = put_maxwait; cs->image_maxwait = put_maxwait;
cs->image_maxiwait = put_maxiwait;
cs->image_maxrate_dyn = get_maxrate_dyn; cs->image_maxrate_dyn = get_maxrate_dyn;
cs->image_maxrate_std = get_maxrate_std; cs->image_maxrate_std = get_maxrate_std;
cs->image_maxrate_usr = get_maxrate_usr; cs->image_maxrate_usr = get_maxrate_usr;
...@@ -252,6 +266,9 @@ emulab_restore(void *state) ...@@ -252,6 +266,9 @@ emulab_restore(void *state)
put_maxwait = cs->image_maxwait; put_maxwait = cs->image_maxwait;
FrisLog(" image_put_maxwait = %d min", FrisLog(" image_put_maxwait = %d min",
(int)(put_maxwait/60)); (int)(put_maxwait/60));
put_maxiwait = cs->image_maxiwait;
FrisLog(" image_put_maxiwait = %d min",
(int)(put_maxiwait/60));
get_maxrate_dyn = cs->image_maxrate_dyn; get_maxrate_dyn = cs->image_maxrate_dyn;
FrisLog(" image_get_maxrate_dyn = %s", FrisLog(" image_get_maxrate_dyn = %s",
get_maxrate_dyn ? "true" : "false"); get_maxrate_dyn ? "true" : "false");
...@@ -354,13 +371,14 @@ set_get_values(struct config_host_authinfo *ai, int ix) ...@@ -354,13 +371,14 @@ set_get_values(struct config_host_authinfo *ai, int ix)
/* and whack the put_* fields */ /* and whack the put_* fields */
ii->put_maxsize = 0; ii->put_maxsize = 0;
ii->put_timeout = 0; ii->put_timeout = 0;
ii->put_itimeout = 0;
ii->put_options = NULL; ii->put_options = NULL;
ii->put_oldversion = NULL; ii->put_oldversion = NULL;
} }
/* /*
* Set the PUT maxsize/options for a particular node/image. * Set the PUT maxsize/options for a particular node/image.
* XXX right now these are completely pulled out of our posterior. * XXX right now these mostly come from the DB.
*/ */
static void static void
set_put_values(struct config_host_authinfo *ai, int ix) set_put_values(struct config_host_authinfo *ai, int ix)
...@@ -372,6 +390,7 @@ set_put_values(struct config_host_authinfo *ai, int ix) ...@@ -372,6 +390,7 @@ set_put_values(struct config_host_authinfo *ai, int ix)
/* put_timeout */ /* put_timeout */
ii->put_timeout = put_maxwait; ii->put_timeout = put_maxwait;
ii->put_itimeout = put_maxiwait;
/* put_oldversion */ /* put_oldversion */
/* /*
......
...@@ -156,6 +156,7 @@ set_get_values(struct config_host_authinfo *ai, int ix) ...@@ -156,6 +156,7 @@ set_get_values(struct config_host_authinfo *ai, int ix)
/* and whack the put_* fields */ /* and whack the put_* fields */
ai->imageinfo[ix].put_maxsize = 0; ai->imageinfo[ix].put_maxsize = 0;
ai->imageinfo[ix].put_timeout = 0; ai->imageinfo[ix].put_timeout = 0;
ai->imageinfo[ix].put_itimeout = 0;
ai->imageinfo[ix].put_oldversion = NULL; ai->imageinfo[ix].put_oldversion = NULL;
ai->imageinfo[ix].put_options = NULL; ai->imageinfo[ix].put_options = NULL;
} }
...@@ -172,6 +173,7 @@ set_put_values(struct config_host_authinfo *ai, int ix) ...@@ -172,6 +173,7 @@ set_put_values(struct config_host_authinfo *ai, int ix)
/* put_timeout */ /* put_timeout */
ai->imageinfo[ix].put_timeout = 900; ai->imageinfo[ix].put_timeout = 900;
ai->imageinfo[ix].put_itimeout = 120;
/* put_oldversion */ /* put_oldversion */
ai->imageinfo[ix].put_oldversion = NULL; ai->imageinfo[ix].put_oldversion = NULL;
......
...@@ -32,6 +32,7 @@ struct config_imageinfo { ...@@ -32,6 +32,7 @@ struct config_imageinfo {
char *put_options; /* command line options for PUT server */ char *put_options; /* command line options for PUT server */
uint64_t put_maxsize; /* maximum size for this image */ uint64_t put_maxsize; /* maximum size for this image */
int put_timeout; /* max time to allow PUT server to run */ int put_timeout; /* max time to allow PUT server to run */
int put_itimeout; /* max time to allow per-socket-op to run */
char *put_oldversion; /* where to save the old version */ char *put_oldversion; /* where to save the old version */
void *extra; /* config-type specific info */ void *extra; /* config-type specific info */
}; };
......
/* /*
* Copyright (c) 2010-2013 University of Utah and the Flux Group. * Copyright (c) 2010-2014 University of Utah and the Flux Group.
* *
* {{{EMULAB-LICENSE * {{{EMULAB-LICENSE
* *
...@@ -47,6 +47,7 @@ static char *path; ...@@ -47,6 +47,7 @@ static char *path;
static uint64_t maxsize = 0; static uint64_t maxsize = 0;
static int bufsize = (64 * 1024);; static int bufsize = (64 * 1024);;
static int timeout = 0; static int timeout = 0;
static int idletimeout = 0;
static int sock = -1; static int sock = -1;
/* Globals */ /* Globals */
...@@ -71,6 +72,9 @@ main(int argc, char **argv) ...@@ -71,6 +72,9 @@ main(int argc, char **argv)
FrisLog("%s: listening on port %d for image data from %s (max of %llu bytes)", FrisLog("%s: listening on port %d for image data from %s (max of %llu bytes)",
path, portnum, inet_ntoa(clientip), maxsize); path, portnum, inet_ntoa(clientip), maxsize);
if (idletimeout || timeout)
FrisLog("%s: using idletimeout=%ds, timeout=%ds\n",
path, idletimeout, timeout);
rv = recv_file(); rv = recv_file();
close(sock); close(sock);
...@@ -82,7 +86,7 @@ static void ...@@ -82,7 +86,7 @@ static void
parse_args(int argc, char **argv) parse_args(int argc, char **argv)
{ {
int ch; int ch;
while ((ch = getopt(argc, argv, "m:p:i:b:T:s:")) != -1) { while ((ch = getopt(argc, argv, "m:p:i:b:I:T:s:")) != -1) {
switch (ch) { switch (ch) {
case 'm': case 'm':
if (!inet_aton(optarg, &clientip)) { if (!inet_aton(optarg, &clientip)) {
...@@ -109,6 +113,14 @@ parse_args(int argc, char **argv) ...@@ -109,6 +113,14 @@ parse_args(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'I':
idletimeout = atoi(optarg);
if (idletimeout < 0 || idletimeout > (24 * 60 * 60)) {
fprintf(stderr, "Invalid idle timeout %d\n",
idletimeout);
exit(1);
}
break;
case 'T': case 'T':
timeout = atoi(optarg); timeout = atoi(optarg);
if (timeout < 0 || timeout > (24 * 60 * 60)) { if (timeout < 0 || timeout > (24 * 60 * 60)) {
...@@ -129,6 +141,17 @@ parse_args(int argc, char **argv) ...@@ -129,6 +141,17 @@ parse_args(int argc, char **argv)
if (clientip.s_addr == 0 || portnum == 0 || argc < 1) if (clientip.s_addr == 0 || portnum == 0 || argc < 1)
usage(); usage();
/*
* If both timeouts are set, make sure they play nice
*/
if (idletimeout > 0 && timeout > 0) {
/* idletimeout should be <= timeout */
if (idletimeout > timeout)
idletimeout = timeout;
/* if the are equal, no need for the idletimeout */
if (idletimeout == timeout)
idletimeout = 0;
}
path = argv[0]; path = argv[0];
} }
...@@ -146,6 +169,7 @@ usage(void) ...@@ -146,6 +169,7 @@ usage(void)
" -p <port> TCP port number on which to listen for client.\n" " -p <port> TCP port number on which to listen for client.\n"
" -i <iface> Interface on which to listen (specified by local IP).\n" " -i <iface> Interface on which to listen (specified by local IP).\n"
" -I <timo> Max time (in seconds) to allow connect to be idle (no traffic from client).\n"
" -T <timo> Max time (in seconds) to wait for upload to complete.\n" " -T <timo> Max time (in seconds) to wait for upload to complete.\n"
" -s <size> Maximum amount of data (in bytes) to upload.\n" " -s <size> Maximum amount of data (in bytes) to upload.\n"
"\n\n"; "\n\n";
...@@ -157,7 +181,7 @@ usage(void) ...@@ -157,7 +181,7 @@ usage(void)
static sigjmp_buf toenv; static sigjmp_buf toenv;
static void static void
send_timeout(int sig) recv_timeout(int sig)
{ {
siglongjmp(toenv, 1); siglongjmp(toenv, 1);
} }
...@@ -177,6 +201,14 @@ recv_file() ...@@ -177,6 +201,14 @@ recv_file()
int rv = 1; int rv = 1;
char *stat; char *stat;
gettimeofday(&st, NULL); /* XXX for early errors */
/*
* If we have an overall timeout (timeout > 0) then just set the
* alarm to that and we will longjmp if we hit it.
*
* Idletimeout are handled by the connection.
*/
if (timeout > 0) { if (timeout > 0) {
struct itimerval it; struct itimerval it;
...@@ -186,13 +218,11 @@ recv_file() ...@@ -186,13 +218,11 @@ recv_file()
} }
it.it_value.tv_sec = timeout; it.it_value.tv_sec = timeout;
it.it_value.tv_usec = 0; it.it_value.tv_usec = 0;
it.it_interval = it.it_value; it.it_interval.tv_sec = it.it_interval.tv_usec = 0;
signal(SIGALRM, recv_timeout);
signal(SIGALRM, send_timeout);
setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_REAL, &it, NULL);
} }
gettimeofday(&st, NULL); /* XXX for early errors */
wbuf = malloc(bufsize); wbuf = malloc(bufsize);
if (wbuf == NULL) { if (wbuf == NULL) {
FrisError("Could not allocate %d byte buffer, try using -b", FrisError("Could not allocate %d byte buffer, try using -b",
...@@ -209,7 +239,7 @@ recv_file() ...@@ -209,7 +239,7 @@ recv_file()
goto done; goto done;
} }
conn = conn_accept_tcp(sock, &clientip); conn = conn_accept_tcp(sock, &clientip, idletimeout, idletimeout);
if (conn == NULL) { if (conn == NULL) {
FrisError("Error accepting from %s", inet_ntoa(clientip)); FrisError("Error accepting from %s", inet_ntoa(clientip));
goto done; goto done;
...@@ -226,7 +256,10 @@ recv_file() ...@@ -226,7 +256,10 @@ recv_file()
cc = remaining; cc = remaining;
ncc = conn_read(conn, wbuf, cc); ncc = conn_read(conn, wbuf, cc);
if (ncc < 0) { if (ncc < 0) {
FrisPwarning("socket read"); if (conn_timeout(conn))
rv = 2;
else
FrisPwarning("socket read");
goto done; goto done;
} }
if (ncc == 0) if (ncc == 0)
...@@ -252,8 +285,7 @@ recv_file() ...@@ -252,8 +285,7 @@ recv_file()
if (timeout) { if (timeout) {
struct itimerval it; struct itimerval it;
it.it_value.tv_sec = 0; it.it_value.tv_sec = it.it_value.tv_usec = 0;
it.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &it, NULL); setitimer(ITIMER_REAL, &it, NULL);
} }
......
...@@ -288,6 +288,7 @@ struct uploadextra { ...@@ -288,6 +288,7 @@ struct uploadextra {
char *realname; char *realname;
uint64_t isize; uint64_t isize;
uint32_t mtime; uint32_t mtime;
int itimeout;
}; };
static struct childinfo *findchild(char *, int, int); static struct childinfo *findchild(char *, int, int);
...@@ -370,6 +371,7 @@ copy_imageinfo(struct config_imageinfo *ii) ...@@ -370,6 +371,7 @@ copy_imageinfo(struct config_imageinfo *ii)
goto fail; goto fail;
nii->put_maxsize = ii->put_maxsize; nii->put_maxsize = ii->put_maxsize;
nii->put_timeout = ii->put_timeout; nii->put_timeout = ii->put_timeout;
nii->put_itimeout = ii->put_itimeout;
/* XXX don't care about extra right now */ /* XXX don't care about extra right now */
return nii; return nii;
...@@ -1168,16 +1170,18 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip, ...@@ -1168,16 +1170,18 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
/* /*
* They gave us an mtime and it is "bad", return an error. * They gave us an mtime and it is "bad", return an error.
* XXX somewhat arbitrary: cannot set a time in the future. * XXX somewhat arbitrary: cannot set a time in the future.
* XXX cut them some slack on the future time thing, up to 10s okay.
*/ */
if (mtime) { if (mtime) {
struct timeval now; struct timeval now;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
if (mtime > now.tv_sec) { if (mtime > (now.tv_sec + 10)) {
rv = MS_ERROR_BADMTIME; rv = MS_ERROR_BADMTIME;
FrisWarning("%s: client %s %s failed: " FrisWarning("%s: client %s %s failed: "
"attempt to set mtime in the future", "attempt to set mtime in the future "
imageid, clientip, op); "(%u > %u)\n",
imageid, clientip, op, mtime, now.tv_sec);
msg->body.putreply.error = rv; msg->body.putreply.error = rv;
goto reply; goto reply;
} }
...@@ -1666,15 +1670,23 @@ startchild(struct childinfo *ci) ...@@ -1666,15 +1670,23 @@ startchild(struct childinfo *ci)
switch (ci->ptype) { switch (ci->ptype) {
case PTYPE_SERVER: case PTYPE_SERVER:
{
int timo = ci->timeout;
/* XXX compensate for 2s sleep in handle_get */
if (timo)
timo += 2;
pname = FRISBEE_SERVER; pname = FRISBEE_SERVER;
opts = ci->imageinfo->get_options ? opts = ci->imageinfo->get_options ?
ci->imageinfo->get_options : ""; ci->imageinfo->get_options : "";
snprintf(argbuf, sizeof argbuf, snprintf(argbuf, sizeof argbuf,
"%s -i %s -T %d %s %s -m %s -p %d %s", "%s -i %s -T %d %s %s -m %s -p %d %s",
pname, ifacestr, ci->timeout, opts, pname, ifacestr, timo, opts,
ci->method == CONFIG_IMAGE_BCAST ? "-b" : "", ci->method == CONFIG_IMAGE_BCAST ? "-b" : "",
inet_ntoa(in), ci->port, ci->imageinfo->path); inet_ntoa(in), ci->port, ci->imageinfo->path);
break; break;
}
case PTYPE_CLIENT: case PTYPE_CLIENT:
pname = FRISBEE_CLIENT; pname = FRISBEE_CLIENT;
snprintf(argbuf, sizeof argbuf, snprintf(argbuf, sizeof argbuf,
...@@ -1687,15 +1699,24 @@ startchild(struct childinfo *ci) ...@@ -1687,15 +1699,24 @@ startchild(struct childinfo *ci)
break; break;
case PTYPE_UPLOADER: case PTYPE_UPLOADER:
{ {
int timo = ci->timeout;
int itimo =
((struct uploadextra *)ci->extra)->itimeout;
uint64_t isize = uint64_t isize =
((struct uploadextra *)ci->extra)->isize; ((struct uploadextra *)ci->extra)->isize;
/* XXX compensate for 2s sleep in handle_put */
if (timo)
timo += 2;
if (itimo)
itimo += 2;
pname = FRISBEE_UPLOAD; pname = FRISBEE_UPLOAD;
opts = ci->imageinfo->put_options ? opts = ci->imageinfo->put_options ?
ci->imageinfo->put_options : ""; ci->imageinfo->put_options : "";
snprintf(argbuf, sizeof argbuf, snprintf(argbuf, sizeof argbuf,
"%s -i %s -T %d %s -s %llu -m %s -p %d %s", "%s -i %s -I %d -T %d %s -s %llu -m %s -p %d %s",
pname, ifacestr, ci->timeout, opts, pname, ifacestr, itimo, timo, opts,
(unsigned long long)isize,