Commit 99943a19 authored by Mike Hibler's avatar Mike Hibler

Support for frisbee direct image upload to fs node.

We have had issues with uploading images to boss where they are then written
across NFS to ops. That seems to be a network hop too far on CloudLab Utah
where we have a 10Gb control network. We get occasional transcient timeouts
from somewhere in the TCP code. With the convoluted path through real and
virtual NICs, some with offloading, some without, packets wind up getting
out of order and someone gets far enough behind to cause problems.

So we work around it.

If IMAGEUPLOADTOFS is defined in the defs-* file, we will run a frisbee
master server on the fs (ops) node and the image creation path directs the
nodes to use that server. There is a new hack configuration for the master
server "upload-only" which is extremely specific to ops: it validates the
upload with the boss master server and, if allowed, fires up an upload
server for the client to talk to. The image will thus be directly uploaded
to the local (ZFS) /proj or /groups filesystems on ops. This seems to be
enough to get around the problem.

Note that we could allow this master server to serve downloads as well to
avoid the analogous problem in that direction, but this to date has not
been a problem.

NOTE: the ops node must be in the nodes table in the DB or else boss will
not validate proxied requests from it. The standard install procedure is
supposed to add ops, but we have a couple of clusters where it is not in
the table!
parent e4485562
......@@ -63,8 +63,11 @@ boss-install:
$(INSTALL) -m 644 $(SRCDIR)/install-tarfile.1 \
$(INSTALL_DIR)/opsdir/man/man1/install-tarfile.1
control: control-subdirs
control-install:
@$(MAKE) -C imagezip install
$(MAKE) -C frisbee.redux control-install
fs-install:
......
......@@ -43,6 +43,8 @@ bootinfo_version.c: bootinfoclient.c
install:
control:
control-install:
subboss:
subboss-install:
......
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -37,6 +37,7 @@ all: boss-all tipserv-all
boss-all: capserver
tipserv-all: capture capture-tty capquery caplogserver caplog caplog.bin
client: capture capture-nossl capquery caplog caplog.bin
control:
subboss: client
include $(TESTBED_SRCDIR)/GNUmakerules
......
#
# Copyright (c) 2000-2012 University of Utah and the Flux Group.
# Copyright (c) 2000-2018 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -47,6 +47,7 @@ dijkstra-debug: Compressor.o TreeCompressor.o dijkstra.o \
OptimalIpTree.o bitmath.o $(LIBS) -o $@
boss-install:
control:
control-install:
subboss:
subboss-install:
......
......@@ -88,14 +88,20 @@ WITH_MSERVER_NULL = 1
#ifndef WITH_MSERVER_EMULAB
WITH_MSERVER_EMULAB = 1
#endif
#ifndef WITH_MSERVER_UPLOAD
WITH_MSERVER_UPLOAD = 1
#endif
include $(OBJDIR)/Makeconf
all: frisbee frisbeed mfrisbeed frisupload frisuploadd
subboss:
control:
$(MAKE) WITH_MSERVER_EMULAB=0 all
subboss:
$(MAKE) WITH_MSERVER_EMULAB=0 WITH_MSERVER_UPLOAD=0 all
include $(TESTBED_SRCDIR)/GNUmakerules
IZSRCDIR = $(TESTBED_IMAGEZIPSRCDIR)
......@@ -132,8 +138,8 @@ SERVEROBJS = server.o $(SHAREDOBJS)
# Master server configuration
#
# Default master server config
MSERVERFLAGS = -DUSE_NULL_CONFIG $(CFLAGS) -I$(OBJDIR)
MSERVEROBJS = mserver.o $(SHAREDOBJS) config.o config_null.o
MSERVERFLAGS = -DUSE_NULL_CONFIG -DUSE_UPLOAD_CONFIG $(CFLAGS) -I$(OBJDIR)
MSERVEROBJS = mserver.o $(SHAREDOBJS) config.o config_null.o config_upload.o
ifeq ($(SYSTEM),Linux)
MSERVERLIBS = -lrt
else
......@@ -284,6 +290,8 @@ config_emulab.o: $(SRCDIR)/config_emulab.c configdefs.h log.h
$(CC) -c $(MSERVERFLAGS) $(SRCDIR)/config_emulab.c
config_null.o: $(SRCDIR)/config_null.c configdefs.h log.h
$(CC) -c $(MSERVERFLAGS) $(SRCDIR)/config_null.c
config_upload.o: $(SRCDIR)/config_upload.c configdefs.h log.h
$(CC) -c $(MSERVERFLAGS) $(SRCDIR)/config_upload.c
log.o: $(SRCDIR)/log.c decls.h log.h
$(CC) $(CFLAGS) -DLOG_TESTBED=$(LOG_TESTBED) -c $(SRCDIR)/log.c
......@@ -317,6 +325,10 @@ trace.o: decls.h trace.h log.h
install: $(INSTALL_SBINDIR)/mfrisbeed $(INSTALL_SBINDIR)/frisbeed $(INSTALL_SBINDIR)/frisbee $(INSTALL_SBINDIR)/frisuploadd
control-install: control
$(INSTALL_PROGRAM) mfrisbeed $(INSTALL_SBINDIR)/mfrisbeed
$(INSTALL_PROGRAM) frisupload $(INSTALL_SBINDIR)/frisupload
subboss-install: subboss
$(MAKE) WITH_MSERVER_EMULAB=0 install
$(INSTALL_PROGRAM) frisbee $(DESTDIR)/usr/local/bin/frisbee
......
......@@ -93,6 +93,18 @@ config_init(char *style, int readit, char *opts)
FrisLog("Null config init failed");
#else
FrisLog("Not built with Null configuration");
#endif
}
if (strcmp(style, "upload-only") == 0) {
#ifdef USE_UPLOAD_CONFIG
extern struct config *upload_init(char *);
if (myconfig == NULL) {
if ((myconfig = upload_init(opts)) != NULL)
FrisLog("Using upload-only configuration");
} else
FrisLog("Upload-only config init failed");
#else
FrisLog("Not built with Upload-only configuration");
#endif
}
if (myconfig == NULL) {
......
/*
* Copyright (c) 2010-2017 University of Utah and the Flux Group.
* Copyright (c) 2010-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -945,7 +945,9 @@ allow_stddirs(char *imageid,
ci->ngids = ei->ngids;
set_put_values(put, 0);
ci->extra = NULL;
}
} else if (put != NULL && debug)
FrisInfo("authfail: image '%s' not in acceptable directory for '%s/%s'",
imageid, ei->pid, ei->gid);
if (get != NULL &&
((fdir = isindir(shdir, fpath)) ||
(fdir = isindir(pdir, fpath)) ||
......@@ -981,7 +983,9 @@ allow_stddirs(char *imageid,
ci->ngids = ei->ngids;
set_get_values(get, 0);
ci->extra = NULL;
}
} else if (get != NULL && debug)
FrisInfo("authfail: image '%s' not in acceptable directory for '%s/%s'",
imageid, ei->pid, ei->gid);
done:
free(pdir);
......@@ -1376,6 +1380,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
#endif
proxy = emulab_nodeid(req);
if (proxy == NULL) {
if (debug)
FrisInfo("authfail: node %s not found",
inet_ntoa(*req));
emulab_free_host_authinfo(get);
emulab_free_host_authinfo(put);
return 1;
......@@ -1384,17 +1391,27 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
/* Check the role of the node */
role = emulab_noderole(proxy);
if (role == NULL) {
if (debug)
FrisInfo("authfail: node '%s' has no role", proxy);
free(proxy);
emulab_free_host_authinfo(get);
emulab_free_host_authinfo(put);
return 1;
}
/* Must be inner boss, subboss or virtnode host to proxy */
if (strcmp(role, "innerboss") &&
/* XXX ops appears as a regular node */
if (strcmp(role, "node") == 0 && strcmp(proxy, "ops") == 0)
role = mystrdup("opsnode");
/* Must be ops, inner boss, subboss or virtnode host to proxy */
if (strcmp(role, "opsnode") &&
strcmp(role, "innerboss") &&
strcmp(role, "subboss") &&
strcmp(role, "sharedhost") &&
strcmp(role, "virthost")) {
if (debug)
FrisInfo("authfail: node '%s' role '%s' not a proxy",
proxy, role);
free(proxy);
free(role);
emulab_free_host_authinfo(get);
......@@ -1460,7 +1477,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
res = NULL;
} else
#endif
if (strcmp(role, "subboss") == 0) {
if (strcmp(role, "opsnode") == 0) {
res = NULL;
} else if (strcmp(role, "subboss") == 0) {
res = mydb_query("SELECT s.node_id"
" FROM subbosses as s,"
" nodes as n"
......@@ -1497,6 +1516,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
if (res) {
if (mysql_num_rows(res) == 0) {
mysql_free_result(res);
if (debug)
FrisInfo("authfail: '%s' not a proxy for '%s'",
proxy, node);
free(role);
free(proxy);
free(node);
......@@ -1535,8 +1557,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
row = mysql_fetch_row(res);
if (!row[0] || !row[1] || !row[2] || !row[3] || !row[4] ||
!row[5] || !row[6] || !row[7] || !row[8]) {
FrisError("config_host_authinfo: null pid/gid/eid/uname/uid!?");
mysql_free_result(res);
FrisInfo("authfail: null pid/gid/eid/uname/uid for node '%s'!",
node);
emulab_free_host_authinfo(get);
emulab_free_host_authinfo(put);
free(node);
......@@ -1623,8 +1646,11 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
parse_imageid(imageid,
&wantpid, &wantname, &wantvers, &wantmeta);
imageidx = emulab_imageid(wantpid, wantname);
if (imageidx == 0)
if (imageidx == 0) {
if (debug)
FrisInfo("authfail: no such image '%s'", imageid);
goto done;
}
}
if (put != NULL) {
......@@ -1727,6 +1753,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
put->imageinfo =
mymalloc(nrows *
sizeof(struct config_imageinfo));
else if (debug)
FrisInfo("authfail: PUT access to '%s' denied to '%s/%s'",
imageid, ei->pid, ei->eid);
put->numimages = 0;
for (i = 0; i < nrows; i++) {
struct emulab_ii_extra_info *ii;
......@@ -1958,6 +1987,9 @@ emulab_get_host_authinfo(struct in_addr *req, struct in_addr *host,
get->imageinfo =
mymalloc(nrows *
sizeof(struct config_imageinfo));
else if (debug)
FrisInfo("authfail: GET access to '%s' denied to '%s/%s'",
imageid, ei->pid, ei->eid);
get->numimages = 0;
for (i = 0; i < nrows; i++) {
struct emulab_ii_extra_info *ii;
......
/*
* Copyright (c) 2010-2017 University of Utah and the Flux Group.
* Copyright (c) 2010-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -984,6 +984,6 @@ mystrdup(const char *str)
struct config *
null_init(void)
{
return NULL;
return 0;
}
#endif
This diff is collapsed.
/*
* Copyright (c) 2010-2017 University of Utah and the Flux Group.
* Copyright (c) 2010-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -34,6 +34,8 @@
#define MAXGIDS 1024
#endif
#define MAXIMAGEDIRS 4
#define NOUID (-1)
/*
......
/*
* Copyright (c) 2000-2017 University of Utah and the Flux Group.
* Copyright (c) 2000-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -493,6 +493,10 @@ typedef struct {
#define MS_MSGTYPE_PUTREQUEST 3
#define MS_MSGTYPE_PUTREPLY 4
#define MS_REQUEST_GET 1
#define MS_REQUEST_PUT 2
#define MS_REQUEST_ANY 3
#define MS_METHOD_UNKNOWN 0
#define MS_METHOD_UNICAST 1
#define MS_METHOD_MULTICAST 2
......@@ -534,6 +538,8 @@ void dump_network(void);
#ifdef MASTER_SERVER
int ClientNetFindServer(in_addr_t, in_port_t, in_addr_t, char *,
int, int, int, GetReply *, struct in_addr *);
int ClientNetPutRequest(in_addr_t, in_port_t, in_addr_t, char *,
uint64_t, uint32_t, int, int, int, PutReply *);
int MsgSend(int, MasterMsg_t *, size_t, int);
int MsgReceive(int, MasterMsg_t *, size_t, int);
#endif
......
......@@ -78,6 +78,7 @@ static char * gidstr(int ngids, gid_t gids[]);
static int daemonize = 1;
int debug = 0;
static int dumpconfig = 0;
static int onlyrequests = MS_REQUEST_ANY;
static int onlymethods = (MS_METHOD_UNICAST|MS_METHOD_MULTICAST);
static int parentmethods = (MS_METHOD_UNICAST|MS_METHOD_MULTICAST);
static int myuid = NOUID;
......@@ -658,6 +659,17 @@ handle_get(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
strncpy((char *)msg->hdr.version, MS_MSGVERS_1,
sizeof(msg->hdr.version));
/*
* This server only handles uploads.
* XXX maybe we should just drop these requests and not send reply?
*/
if ((onlyrequests & MS_REQUEST_GET) == 0) {
FrisWarning("%s: %s from %s, rejected by PUT-only server",
imageid, op, clientip);
msg->body.getreply.error = MS_ERROR_NOTIMPL;
goto reply;
}
/*
* If they request a method we don't support, reject them before
* we do any other work. XXX maybe the method should not matter
......@@ -1140,6 +1152,7 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
uint64_t isize;
uint32_t mtime, timo;
int rv, wantstatus;
PutReply reply;
char *op;
/*
......@@ -1192,6 +1205,17 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
strncpy((char *)msg->hdr.version, MS_MSGVERS_1,
sizeof(msg->hdr.version));
/*
* This server only handles downloads.
* XXX maybe we should just drop these requests and not send reply?
*/
if ((onlyrequests & MS_REQUEST_PUT) == 0) {
FrisWarning("%s: %s from %s, rejected by GET-only server",
imageid, op, clientip);
msg->body.getreply.error = MS_ERROR_NOTIMPL;
goto reply;
}
/*
* Use the canonical name from here on out.
*/
......@@ -1202,15 +1226,31 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
}
/*
* XXX we don't handle mirror mode right now.
* XXX mirror mode on PUT means that we check with our parent to
* make sure that the upload would be legal, and then upload it to
* a local filesystem. We do not actually propogate it to our parent,
* so there is no real "mirroring" going on. This is just a hack so
* we can upload Emulab images on ops directly, while still relying
* on boss (the parent) to authenticate the upload.
*/
if (mirrormode) {
rv = MS_ERROR_NOTIMPL;
FrisWarning("%s: client %s %s failed: "
"upload not supported in mirror mode",
imageid, clientip, op);
msg->body.putreply.error = rv;
goto reply;
in_addr_t authip;
authip = usechildauth ? ntohl(host.s_addr) : 0;
if (!ClientNetPutRequest(ntohl(parentip.s_addr), parentport,
authip, imageid, isize, mtime, timo,
1, 5, &reply))
reply.error = MS_ERROR_FAILED;
if (debug) {
FrisLog("Parent PUT%s returns:", wantstatus? "STATUS" : "");
PrintPutInfo(imageid, &reply, 1);
}
if (reply.error) {
msg->body.putreply.error = reply.error;
FrisLog("%s: client %s authentication with parent failed: %s",
imageid, clientip, GetMSError(reply.error));
goto reply;
}
}
/*
......@@ -1238,6 +1278,23 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
config_free_host_authinfo(ai);
assert((ii->flags & (CONFIG_PATH_ISFILE|CONFIG_PATH_ISSIGFILE)) != 0);
/*
* Use values returned by parent where appropriate.
*
* XXX note that we use local values for size and signature.
* In our only use of PUT mirrormode, the parent will be returning
* the same info as we see locally since they are the same files.
*/
if (mirrormode) {
uint64_t pmaxsize;
pmaxsize = ((uint64_t)reply.himaxsize << 32) | reply.lomaxsize;
if (debug)
FrisLog("%s: replace local maxsize %llu with parent %llu",
imageid, ii->put_maxsize, pmaxsize);
ii->put_maxsize = pmaxsize;
}
/*
* If they gave us a size and it exceeds the maxsize, return an error.
* We do this even for a status-only request; they can specify a size
......@@ -1359,6 +1416,8 @@ handle_put(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
ci = startuploader(ii, myaddr, ntohl(cip->sin_addr.s_addr),
isize, mtime, (int)timo, &rv);
if (ci == NULL) {
FrisLog("%s: could not start uploader: %s",
imageid, GetMSError(rv));
msg->body.putreply.error = rv;
goto reply;
}
......@@ -1471,9 +1530,10 @@ usage(void)
{
fprintf(stderr, "mfrisbeed [-ADRd] [-X method] [-I imagedir] [-S parentIP] [-P parentport] [-p port]\n");
fprintf(stderr, "Basic:\n");
fprintf(stderr, " -C <style> configuration style: emulab, file, or null\n");
fprintf(stderr, " -C <style> configuration style: emulab, upload-only, or null\n");
fprintf(stderr, " -O <str> configuration options, style-specific\n");
fprintf(stderr, " -I <dir> default directory where images are stored\n");
fprintf(stderr, " -r <req> type of requests to serve: get, put or any\n");
fprintf(stderr, " -x <methods> transfer methods to allow from clients: ucast, mcast, bcast or any\n");
fprintf(stderr, " -X <method> transfer method to request from parent\n");
fprintf(stderr, " -p <port> port to listen on\n");
......@@ -1495,26 +1555,51 @@ get_options(int argc, char **argv)
int ch;
int forcedaemonize = 0;
while ((ch = getopt(argc, argv, "AC:O:DI:MRX:x:S:P:p:i:dhQ:")) != -1)
while ((ch = getopt(argc, argv, "AC:O:DI:MRX:x:S:P:p:i:dhQ:r:")) != -1)
switch(ch) {
case 'A':
usechildauth = 1;
break;
case 'C':
if (strcmp(optarg, "emulab") == 0 ||
strcmp(optarg, "file") == 0 ||
strcmp(optarg, "upload-only") == 0 ||
strcmp(optarg, "null") == 0)
configstyle = optarg;
else {
fprintf(stderr,
"-C should specify one: "
"'emulab', 'file', 'null'\n");
"'emulab', 'upload-only', 'null'\n");
exit(1);
}
break;
case 'O':
configopts = optarg;
break;
case 'r':
{
char *ostr, *str, *cp;
int nm = 0;
str = ostr = strdup(optarg);
while ((cp = strsep(&str, ",")) != NULL) {
if (strcmp(cp, "get") == 0)
nm |= MS_REQUEST_GET;
else if (strcmp(cp, "put") == 0)
nm |= MS_REQUEST_PUT;
else if (strcmp(cp, "any") == 0)
nm = MS_REQUEST_ANY;
}
free(ostr);
if (nm == 0) {
fprintf(stderr,
"-%c should specify one or more of: "
"'get', 'put', 'any'\n",
ch);
exit(1);
}
onlyrequests = nm;
break;
}
case 'x':
case 'X':
{
......@@ -1779,7 +1864,7 @@ startchild(struct childinfo *ci)
}
/*
* Now that we are running as the user, see if we to
* Now that we are running as the user, see if we need to
* resolve the path to catch permission problems, create
* intermediate directories, etc.
*/
......
/*
* Copyright (c) 2000-2017 University of Utah and the Flux Group.
* Copyright (c) 2000-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -1083,6 +1083,8 @@ ClientNetFindServer(in_addr_t sip, in_port_t sport,
if (sport == 0)
sport = MS_PORTNUM;
/* XXX need connection timeout! */
name.sin_family = AF_INET;
name.sin_addr.s_addr = htonl(sip);
name.sin_port = htons(sport);
......@@ -1171,6 +1173,121 @@ ClientNetFindServer(in_addr_t sip, in_port_t sport,
reply->losize = ntohl(reply->losize);
return 1;
}
/*
* Contact the master server to negotiate an upload for a 'file' to store
* under the given 'imageid'.
*
* 'sip' and 'sport' are the addr/port of the master server, 'askonly' is
* set to just see if the upload is allowed and to get characteristics of
* any existing copy of the image, 'timeout' is how long to wait for a
* response.
*
* If 'hostip' is not zero, then we are requesting information on behalf of
* that node. The calling node (us) must have "proxy" permission on the
* server for this to work.
*
* On success, return non-zero with 'reply' filled in with the server's
* response IN HOST ORDER. On failure returns zero.
*/
int
ClientNetPutRequest(in_addr_t sip, in_port_t sport,
in_addr_t hostip, char *imageid,
uint64_t isize, uint32_t mtime,
int timeout, int askonly, int reqtimo, PutReply *reply)
{
struct sockaddr_in name;
MasterMsg_t msg;
int msock, len;
if ((msock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
perror("Could not allocate socket for master server");
return 0;
}
if (sport == 0)
sport = MS_PORTNUM;
/* XXX need connection timeout! */
name.sin_family = AF_INET;
name.sin_addr.s_addr = htonl(sip);
name.sin_port = htons(sport);
if (connect(msock, (struct sockaddr *)&name, sizeof(name)) < 0) {
fprintf(stderr,
"Connecting to master server %s:%d failed: %s\n",
inet_ntoa(name.sin_addr), sport, strerror(errno));
close(msock);
return 0;
}
memset(&msg, 0, sizeof msg);
strncpy((char *)msg.hdr.version, MS_MSGVERS_1,
sizeof(msg.hdr.version));
msg.hdr.type = htonl(MS_MSGTYPE_PUTREQUEST);
msg.body.putrequest.hostip = htonl(hostip);
if (askonly)
msg.body.putrequest.status = 1;
len = strlen(imageid);
if (len > MS_MAXIDLEN)
len = MS_MAXIDLEN;
msg.body.putrequest.idlen = htons(len);
strncpy((char *)msg.body.putrequest.imageid, imageid, MS_MAXIDLEN);
if (isize > 0) {
msg.body.putrequest.hisize = htonl(isize >> 32);
msg.body.putrequest.losize = htonl(isize);
}
if (mtime)
msg.body.putrequest.mtime = htonl(mtime);
/* XXX have the server wait longer than us so we timeout first */
if (timeout)
msg.body.putrequest.timeout = htonl(timeout+2);
len = sizeof msg.hdr + sizeof msg.body.putrequest;
if (!MsgSend(msock, &msg, len, reqtimo)) {
close(msock);
return 0;
}
memset(&msg, 0, sizeof msg);
len = sizeof msg.hdr + sizeof msg.body.putreply;
if (!MsgReceive(msock, &msg, len, reqtimo)) {
close(msock);
return 0;
}
close(msock);
if (strncmp((char *)msg.hdr.version, MS_MSGVERS_1,
sizeof(msg.hdr.version))) {
fprintf(stderr,
"Got incorrect version from master server %s:%d\n",
inet_ntoa(name.sin_addr), sport);
return 0;
}
if (ntohl(msg.hdr.type) != MS_MSGTYPE_PUTREPLY) {
fprintf(stderr,
"Got incorrect reply from master server %s:%d\n",
inet_ntoa(name.sin_addr), sport);
return 0;
}
/*
* Convert the reply info to host order
*/
*reply = msg.body.putreply;
reply->error = ntohs(reply->error);
reply->addr = ntohl(reply->addr);
reply->port = ntohs(reply->port);
reply->sigtype = ntohs(reply->sigtype);
if (reply->sigtype == MS_SIGTYPE_MTIME)
*(uint32_t *)reply->signature =
ntohl(*(uint32_t *)reply->signature);
reply->hisize = ntohl(reply->hisize);
reply->losize = ntohl(reply->losize);
reply->himaxsize = ntohl(reply->himaxsize);
reply->lomaxsize = ntohl(reply->lomaxsize);
return 1;
}
#endif
/*
......
/*
* Copyright (c) 2010-2017 University of Utah and the Flux Group.
* Copyright (c) 2010-2018 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -73,9 +73,6 @@ struct in_addr mcastif;
static void usage(void);
static void parse_args(int argc, char **argv);
static int send_file(void);
static int put_request(char *imageid, in_addr_t sip, in_port_t sport,
in_addr_t hostip, uint64_t isize, uint32_t mtime,
int timeout, int askonly, int reqtimo, PutReply *reply);
int
main(int argc, char **argv)
......@@ -140,9 +137,9 @@ main(int argc, char **argv)
if (imageid && !askonly) {
fd_set set;
if (!put_request(imageid, ntohl(msip.s_addr), msport,
proxyip, filesize, mtime, 0, 1, timo,
&reply))
if (!ClientNetPutRequest(ntohl(msip.s_addr), msport,
proxyip, imageid, filesize, mtime,
0, 1, timo, &reply))
FrisFatal("Could not get upload info for '%s'",
imageid);
if (reply.error) {
......@@ -204,9 +201,9 @@ main(int argc, char **argv)
int retries = 2;
again:
if (!put_request(imageid, ntohl(msip.s_addr), msport, proxyip,
filesize, mtime, timeout, askonly, timo,
&reply))
if (!ClientNetPutRequest(ntohl(msip.s_addr), msport, proxyip,
imageid, filesize, mtime, timeout,
askonly, timo, &reply))
FrisFatal("Could not get upload info for '%s'",
imageid);
......@@ -285,8 +282,9 @@ main(int argc, char **argv)
*/
while (1) {
sleep(1);
if (!put_request(imageid, ntohl(msip.s_addr), msport,
proxyip, 0, 0, 0, 1, timo, &reply)) {
if (!ClientNetPutRequest(ntohl(msip.s_addr), msport,
proxyip, imageid, 0, 0, 0, 1, timo,
&reply)) {
FrisWarning("%s: status request failed",
imageid);
goto vdone;
......@@ -684,108 +682,3 @@ send_file(void)
return rv;
}
/*
* Contact the master server to negotiate an upload for a 'file' to store
* under the given 'imageid'.
*
* 'sip' and 'sport' are the addr/port of the master server, 'askonly' is
* set to just see if the upload is allowed and to get characteristics of
* any existing copy of the image, 'timeout' is how long to wait for a
* response.
*
* If 'hostip' is not zero, then we are requesting information on behalf of
* that node. The calling node (us) must have "proxy" permission on the
* server for this to work.
*
* On success, return non-zero with 'reply' filled in with the server's
* response IN HOST ORDER. On failure returns zero.
*/
static int
put_request(char *imageid, in_addr_t sip, in_port_t sport, in_addr_t hostip,