Commit 4a8604b1 authored by Mike Hibler's avatar Mike Hibler

Introducing TMCD version 38! Returns additional "loadinfo" info.

New loadinfo returns:

IMAGELOW, IMAGEHIGH: range of sectors covered by the image.
    This is NOT the same as what imageinfo or imagedump will show.
    For partition images, these low and high values are adjusted
    for the MBR offset of the partition in question. So when loading
    a Linux image, expect values like 6G and 12G. The intent here
    (not yet realized) is that these values will be used to construct
    an MBR/GPT on the fly, rather than using hardcode magic MBR versions.
    You can get the uncompressed size of the image with (high - low + 1).

IMAGESSIZE: the units of the low/high values.
    Always 512 right now, may be 4096 someday.

IMAGERELOC: non-zero if the image can be placed at an offset other
    than IMAGELOW (i.e., it can be relocated). This may or may not
    prove useful for dynamic MBR construction...we will see.

Probably didn't need to bump the version here, but I am playing it safe.
parent 75c8443a
/* /*
* Copyright (c) 2000-2013 University of Utah and the Flux Group. * Copyright (c) 2000-2014 University of Utah and the Flux Group.
* *
* {{{EMULAB-LICENSE * {{{EMULAB-LICENSE
* *
...@@ -46,4 +46,4 @@ ...@@ -46,4 +46,4 @@
* it in clientside/tmcc/common/libsetup.pm! * it in clientside/tmcc/common/libsetup.pm!
*/ */
#define DEFAULT_VERSION 2 #define DEFAULT_VERSION 2
#define CURRENT_VERSION 37 #define CURRENT_VERSION 38
...@@ -81,7 +81,7 @@ use librc; ...@@ -81,7 +81,7 @@ use librc;
# IMPORTANT NOTE: if you change the version here, you must also change it # IMPORTANT NOTE: if you change the version here, you must also change it
# in clientside/lib/tmcd/tmcd.h! # in clientside/lib/tmcd/tmcd.h!
# #
sub TMCD_VERSION() { 37; }; sub TMCD_VERSION() { 38; };
libtmcc::configtmcc("version", TMCD_VERSION()); libtmcc::configtmcc("version", TMCD_VERSION());
# Control tmcc timeout. # Control tmcc timeout.
......
...@@ -172,7 +172,7 @@ MYSQL_RES * mydb_query(char *query, int ncols, ...); ...@@ -172,7 +172,7 @@ MYSQL_RES * mydb_query(char *query, int ncols, ...);
int mydb_update(char *query, ...); int mydb_update(char *query, ...);
static int safesymlink(char *name1, char *name2); static int safesymlink(char *name1, char *name2);
static int getImageInfo(char *path, char *nodeid, char *pid, char *imagename, static int getImageInfo(char *path, char *nodeid, char *pid, char *imagename,
unsigned int *mtime, unsigned int *chunks); unsigned int *mtime, off_t *isize);
static int getrandomchars(char *buf, int len); static int getrandomchars(char *buf, int len);
/* socket timeouts */ /* socket timeouts */
...@@ -5195,8 +5195,10 @@ COMMAND_PROTOTYPE(doloadinfo) ...@@ -5195,8 +5195,10 @@ COMMAND_PROTOTYPE(doloadinfo)
* Get the address the node should contact to load its image * Get the address the node should contact to load its image
*/ */
res = mydb_query("select loadpart,OS,mustwipe,mbr_version,access_key," res = mydb_query("select loadpart,OS,mustwipe,mbr_version,access_key,"
" i.imageid,prepare,i.imagename,p.pid,g.gid,i.path, " " i.imageid,prepare,i.imagename,p.pid,g.gid,i.path,"
" o.version,pa.partition " " o.version,pa.partition,i.size,"
" lba_low,i.lba_high,i.lba_size,i.relocatable,"
" UNIX_TIMESTAMP(updated) "
"from current_reloads as r " "from current_reloads as r "
"left join images as i on i.imageid=r.image_id " "left join images as i on i.imageid=r.image_id "
"left join frisbee_blobs as f on f.imageid=i.imageid " "left join frisbee_blobs as f on f.imageid=i.imageid "
...@@ -5207,7 +5209,7 @@ COMMAND_PROTOTYPE(doloadinfo) ...@@ -5207,7 +5209,7 @@ COMMAND_PROTOTYPE(doloadinfo)
" pa.node_id=r.node_id and " " pa.node_id=r.node_id and "
" pa.osid=i.default_osid and loadpart=0 " " pa.osid=i.default_osid and loadpart=0 "
"where r.node_id='%s' order by r.idx", "where r.node_id='%s' order by r.idx",
13, reqp->nodeid); 19, reqp->nodeid);
if (!res) { if (!res) {
error("doloadinfo: %s: DB Error getting loading address!\n", error("doloadinfo: %s: DB Error getting loading address!\n",
...@@ -5544,14 +5546,16 @@ COMMAND_PROTOTYPE(doloadinfo) ...@@ -5544,14 +5546,16 @@ COMMAND_PROTOTYPE(doloadinfo)
row[8], row[9], row[7]); row[8], row[9], row[7]);
/* /*
* Vnodes also get a time stamp for the imagepath. * All images version 38 and above, or just vnodes
* This is not strictly necessary since the master * prior to that get additional info:
* frisbee server will return this info, but vnodes *
* use this to create a file name before calling * all nodes v38+: mtime, chunks, sector range and
* the server. * size, relocatable flag
* pre-v38 vnodes: mtime, chunks.
*/ */
if (reqp->isvnode) { if (vers >= 38 || reqp->isvnode) {
unsigned int mtime, chunks; unsigned int mtime, chunks;
off_t isize;
if (!row[10] || !row[10][0]) { if (!row[10] || !row[10][0]) {
error("doloadinfo: %s: No path" error("doloadinfo: %s: No path"
...@@ -5560,15 +5564,70 @@ COMMAND_PROTOTYPE(doloadinfo) ...@@ -5560,15 +5564,70 @@ COMMAND_PROTOTYPE(doloadinfo)
mysql_free_result(res); mysql_free_result(res);
return 1; return 1;
} }
if (getImageInfo(row[10], reqp->nodeid, /*
row[8], row[7], &mtime, &chunks)) { * If mtime and size are set in the DB, use
mysql_free_result(res); * those values. Otherwise, take extraordinary
return 1; * measures to get the values.
*/
if (row[13] && row[13][0])
isize = (off_t)strtoll(row[13], 0, 0);
else
isize = 0;
if (row[18] && row[18][0])
mtime = strtol(row[18], 0, 0);
else
mtime = 0;
if (isize == 0 || mtime == 0) {
if (getImageInfo(row[10], reqp->nodeid,
row[8], row[7],
&mtime, &isize)) {
mysql_free_result(res);
return 1;
}
} }
bufp += OUTPUT(bufp, ebufp - bufp, bufp += OUTPUT(bufp, ebufp - bufp,
" IMAGEMTIME=%u", mtime); " IMAGEMTIME=%u", mtime);
/* XXX assumes chunksize of 1MB */
chunks = (unsigned)((isize + 1024*1024 - 1) /
(1024*1024));
bufp += OUTPUT(bufp, ebufp - bufp, bufp += OUTPUT(bufp, ebufp - bufp,
" IMAGECHUNKS=%u", chunks); " IMAGECHUNKS=%u", chunks);
/*
* Starting with version 38, we return DB
* info about the sector range occupied by
* the image and whether it is relocatable.
*
* XXX if lba_high==0 then assume the DB
* fields have not been initialized and
* don't return this info.
*/
if (vers >= 38 && row[15] && row[15][0] &&
strcmp(row[15], "0") != 0) {
if (row[14]) {
bufp += OUTPUT(bufp,
ebufp - bufp,
" IMAGELOW=%s",
row[14]);
}
if (row[15]) {
bufp += OUTPUT(bufp,
ebufp - bufp,
" IMAGEHIGH=%s",
row[15]);
}
if (row[16]) {
bufp += OUTPUT(bufp,
ebufp - bufp,
" IMAGESSIZE=%s",
row[16]);
}
if (row[17]) {
bufp += OUTPUT(bufp,
ebufp - bufp,
" IMAGERELOC=%s",
row[17]);
}
}
} }
} }
/* Tack on the newline, finally */ /* Tack on the newline, finally */
...@@ -12332,7 +12391,7 @@ COMMAND_PROTOTYPE(dogeniinvalid) ...@@ -12332,7 +12391,7 @@ COMMAND_PROTOTYPE(dogeniinvalid)
*/ */
static int static int
getImageInfo(char *path, char *nodeid, char *pid, char *imagename, getImageInfo(char *path, char *nodeid, char *pid, char *imagename,
unsigned int *mtime, unsigned int *chunks) unsigned int *mtime, off_t *isize)
{ {
struct stat sb; struct stat sb;
...@@ -12390,7 +12449,7 @@ getImageInfo(char *path, char *nodeid, char *pid, char *imagename, ...@@ -12390,7 +12449,7 @@ getImageInfo(char *path, char *nodeid, char *pid, char *imagename,
goto badimage2; goto badimage2;
} }
*mtime = sb.st_mtime; *mtime = sb.st_mtime;
*chunks = sb.st_size / (1024*1024); *isize = sb.st_size;
return 0; return 0;
} }
......
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