Commit a60cc3f7 authored by Mike Hibler's avatar Mike Hibler

Add config function to canonicalize the image name passed in.

This is strictly for the benefit of the Emulab config where you can
request an image name by either ID or path, e.g. "testbed/FOO" or
"/proj/testbed/images/FOO.ndz". Previously, simultaneous requests
under both names would start up two different servers because we didn't
know they were the same image. Not really a problem for downloads,
but really not a good thing for uploads!
parent 355f5aa8
/*
* Copyright (c) 2010-2012 University of Utah and the Flux Group.
* Copyright (c) 2010-2014 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -210,6 +210,18 @@ config_get_server_address(struct config_imageinfo *ii, int methods, int first,
addr, port, method);
}
/*
* Convert a user requested name (imageid) into its canonical form.
* Returns the canonical name (which may be the same as passed in) or
* NULL on an error. The returned string should be freed by the caller.
*/
char *
config_canonicalize_imageid(char *imageid)
{
assert(myconfig != NULL);
return myconfig->config_canonicalize_imageid(imageid);
}
void
config_dump(FILE *fd)
{
......
......@@ -1729,6 +1729,27 @@ dump_image_aliases(FILE *fd)
free(lastpid);
}
static char *
emulab_canonicalize_imageid(char *path)
{
MYSQL_RES *res;
MYSQL_ROW row;
char *iid = NULL;
res = mydb_query("SELECT CONCAT(pid,'/',imagename) FROM images"
" WHERE path='%s'", 1, path);
if (res != NULL) {
if (mysql_num_rows(res) > 0) {
row = mysql_fetch_row(res);
if (row[0])
iid = strdup(row[0]);
}
mysql_free_result(res);
}
return iid;
}
static void
emulab_dump(FILE *fd)
{
......@@ -1785,6 +1806,7 @@ struct config emulab_config = {
emulab_get_host_authinfo,
emulab_free_host_authinfo,
emulab_get_server_address,
emulab_canonicalize_imageid,
emulab_save,
emulab_restore,
emulab_free,
......
......@@ -694,6 +694,14 @@ dump_host_authinfo(FILE *fd, char *node, char *cmd,
}
#endif
static char *
null_canonicalize_imageid(char *imageid)
{
if (imageid != NULL)
return mystrdup(imageid);
return NULL;
}
static void
null_dump(FILE *fd)
{
......@@ -707,6 +715,7 @@ struct config null_config = {
null_get_host_authinfo,
null_free_host_authinfo,
null_get_server_address,
null_canonicalize_imageid,
null_save,
null_restore,
null_free,
......
......@@ -75,6 +75,7 @@ struct config {
void (*config_free_host_authinfo)(struct config_host_authinfo *);
int (*config_get_server_address)(struct config_imageinfo *, int, int,
in_addr_t *, in_port_t *, int *);
char *(*config_canonicalize_imageid)(char *);
void *(*config_save)(void);
int (*config_restore)(void *);
void (*config_free)(void *);
......@@ -94,6 +95,7 @@ extern int config_auth_by_IP(int, struct in_addr *, struct in_addr *,
char *, struct config_host_authinfo **);
extern int config_get_server_address(struct config_imageinfo *, int, int,
in_addr_t *, in_port_t *, int *);
extern char * config_canonicalize_imageid(char *);
extern void * config_save(void);
extern int config_restore(void *);
extern void config_dump(FILE *);
......
......@@ -585,7 +585,7 @@ handle_get(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
MasterMsg_t *msg)
{
struct in_addr host;
char imageid[MS_MAXIDLEN+1];
char imageid[MS_MAXIDLEN+1], *cimageid;
char clientip[sizeof("XXX.XXX.XXX.XXX")+1];
int len;
struct config_host_authinfo *ai;
......@@ -612,18 +612,33 @@ handle_get(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
len = ntohs(msg->body.getrequest.idlen);
memcpy(imageid, msg->body.getrequest.imageid, len);
imageid[len] = '\0';
cimageid = config_canonicalize_imageid(imageid);
if (cimageid != NULL && strcmp(cimageid, imageid) == 0) {
free(cimageid);
cimageid = NULL;
}
methods = msg->body.getrequest.methods;
wantstatus = msg->body.getrequest.status;
op = wantstatus ? "GETSTATUS" : "GET";
strncpy(clientip, inet_ntoa(cip->sin_addr), sizeof clientip);
if (host.s_addr != cip->sin_addr.s_addr)
FrisLog("%s: %s from %s (for %s), methods: 0x%x",
imageid, op, clientip, inet_ntoa(host), methods);
else
FrisLog("%s: %s from %s, (methods: 0x%x)",
imageid, op, clientip, methods);
if (cimageid == NULL) {
if (host.s_addr != cip->sin_addr.s_addr)
FrisLog("%s: %s from %s (for %s), methods: 0x%x",
imageid, op, clientip, inet_ntoa(host),
methods);
else
FrisLog("%s: %s from %s, (methods: 0x%x)",
imageid, op, clientip, methods);
} else {
if (host.s_addr != cip->sin_addr.s_addr)
FrisLog("%s (%s): %s from %s (for %s), methods: 0x%x",
imageid, cimageid, op, clientip,
inet_ntoa(host), methods);
else
FrisLog("%s (%s): %s from %s, (methods: 0x%x)",
imageid, cimageid, op, clientip, methods);
}
memset(msg, 0, sizeof *msg);
msg->hdr.type = htonl(MS_MSGTYPE_GETREPLY);
strncpy((char *)msg->hdr.version, MS_MSGVERS_1,
......@@ -638,6 +653,15 @@ handle_get(int sock, struct sockaddr_in *sip, struct sockaddr_in *cip,
if (methods == 0)
goto badmethod;
/*
* Use the canonical name from here on out.
*/
if (cimageid != NULL) {
strcpy(imageid, cimageid);
free(cimageid);
cimageid = NULL;
}
/*
* In mirrormode, we first validate access with our parent
* before doing anything locally.
......
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