Commit 9c6e2ba5 authored by Kirk Webb's avatar Kirk Webb

Initial "storageconfig" support added to tmcd.

Add the command and code to return information to storage infrastructure
hosts when they query tmcd about their pseudo-VMs.  Corresponding slice and
export information is returned.
parent 4a94877e
/*
* Copyright (c) 2013 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
* This file is part of the Emulab network testbed software.
*
* This file is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this file. If not, see <http://www.gnu.org/licenses/>.
*
* }}}
*/
/* Blockstore subsystem definitions */
#ifndef BSDEFS_H
#define BSDEFS_H
#include "tbdefs.h"
#define BS_VNODE_TYPE "blockstore"
/* Blockstore classes */
#define BS_CLASS_SAN "SAN"
#define BS_CLASS_LOCAL "local"
/* Blockstore protocols (a.k.a. bus type) */
#define BS_PROTO_ISCSI "iSCSI"
#define BS_PROTO_SCSI "SCSI"
/* Definitions related to iSCSI */
#define BS_IQN_PREFIX "iqn.2001-01.net.emulab"
#define BS_IQN_MAXSIZE sizeof(BS_IQN_PREFIX) + TBDB_FLEN_PID + \
TBDB_FLEN_EID + TBDB_FLEN_BSVOL
#define BS_PERMS_ISCSI_RO "RO" /* read/write */
#define BS_PERMS_ISCSI_RW "RW" /* read/write */
#define BS_PERMS_ISCSI_DEF BS_PERMS_ISCSI_RW
#endif /* BSDEFS_H */
......@@ -42,6 +42,7 @@
#define TBDB_FLEN_RPMS 4096
#define TBDB_FLEN_TINYTEXT (256 + 1)
#define TBDB_FLEN_UUID (64 + 1)
#define TBDB_FLEN_BSVOL (32 + 1)
/*
* Event system stuff.
......
......@@ -51,6 +51,7 @@
#include "ssl.h"
#include "log.h"
#include "tbdefs.h"
#include "bsdefs.h"
#include "bootwhat.h"
#include "bootinfo.h"
......@@ -275,6 +276,7 @@ COMMAND_PROTOTYPE(dostartcmd);
COMMAND_PROTOTYPE(dostartstat);
COMMAND_PROTOTYPE(doready);
COMMAND_PROTOTYPE(doreadycount);
COMMAND_PROTOTYPE(dostorageconfig);
COMMAND_PROTOTYPE(domounts);
COMMAND_PROTOTYPE(dosfshostid);
COMMAND_PROTOTYPE(doloadinfo);
......@@ -388,6 +390,7 @@ struct command {
{ "startstat", FULLCONFIG_NONE, 0, dostartstat },
{ "readycount", FULLCONFIG_NONE, F_ALLOCATED, doreadycount },
{ "ready", FULLCONFIG_NONE, F_ALLOCATED, doready },
{ "storageconfig", FULLCONFIG_ALL, F_ALLOCATED, dostorageconfig},
{ "mounts", FULLCONFIG_ALL, F_ALLOCATED, domounts },
{ "sfshostid", FULLCONFIG_NONE, F_ALLOCATED, dosfshostid },
{ "loadinfo", FULLCONFIG_NONE, 0, doloadinfo},
......@@ -3974,6 +3977,144 @@ COMMAND_PROTOTYPE(doreadycount)
return 0;
}
/*
* Return information on storage composition. This ultimately looks like
* a series of commands that results in a layering of: remote disk
* mounts, local disk checks, aggregate creation (volume managment),
* slicing operations, and finally exports.
*
* XXX: initially we will just spit out minimal information:
* 1) slices and exports for storage host "vnodes"
* 2) remote disk mounts for client nodes
*/
COMMAND_PROTOTYPE(dostorageconfig)
{
MYSQL_RES *res, *res2;
MYSQL_ROW row, row2;
char buf[MYBUFSIZE];
char *bufp, *ebufp = &buf[sizeof(buf)];
char iqn[BS_IQN_MAXSIZE];
char *vname, *bsid, *class, *protocol, *perms;
unsigned int volsize, bsidx;
int nrows, nattrs;
int cmdidx = 1;
/* Request for a blockstore VM? If so, return blockstore slice info */
if (reqp->isvnode &&
(strcmp(reqp->type, BS_VNODE_TYPE) == 0)) {
/* Do Stuff:
0) A vlan interface setup is handled elsewhere (ifconfig).
1) Grab reservation info, log error if it does not exist and
return nothing.
- What local blockstore to slice (bs_id)
- Size (in mebibytes)
- Permissions (node and/or lan)
- Other attributes ... ?
2) Construct volume name
- "pid:eid:vname"
*/
res = mydb_query("select bsidx,bs_id,vname,size "
"from reserved_blockstores "
"where exptidx=%d and "
"vnode_id='%s'",
4, reqp->exptidx, reqp->vnodeid);
if (!res) {
error("STORAGECONFIG: %s: DB Error getting reserved "
"info.\n",
reqp->vnodeid);
return 1;
}
nrows = (int) mysql_num_rows(res);
if (nrows != 1) {
/* Should only be one reserved row per blockstore vm. */
error("STORAGECONFIG: %s: Wrong number of reserved "
"entries for blockstore vm: %d.\n",
reqp->vnodeid, nrows);
mysql_free_result(res);
return 0;
}
row = mysql_fetch_row(res);
bsidx = atoi(row[0]);
bsid = row[1];
vname = row[2];
volsize = atoi(row[3]);
res2 = mydb_query("select attrkey,attrvalue "
"from virt_blockstore_attributes "
"where exptidx=%d and vname='%s'",
2, reqp->exptidx, vname);
if (!res2) {
error("STORAGECONFIG: %s: DB Error getting vattrs.\n",
reqp->vnodeid);
return 1;
}
/* Find out what type of blockstore we are dealing with and
grab some additional attributes. */
nrows = nattrs = (int) mysql_num_rows(res2);
class = protocol = perms = "\0";
while (nrows--) {
char *key, *val;
row2 = mysql_fetch_row(res2);
key = row2[0];
val = row2[1];
if (strcmp(key,"class") == 0) {
class = val;
} else if (strcmp(key,"protocol") == 0) {
protocol = val;
} else if (strcmp(key,"permissions") == 0) {
perms = val;
}
}
/* iSCSI blockstore */
if ((strcmp(class, BS_CLASS_SAN) == 0) &&
(strcmp(protocol, BS_PROTO_ISCSI) == 0)) {
/* Do we have explicit permissions to pass along?
If not, pass the default permissions. */
perms = strlen(perms) ? perms : BS_PERMS_ISCSI_DEF;
/* Construct IQN string. */
if (snprintf(iqn, sizeof(iqn), "%s:%s:%s:%s",
BS_IQN_PREFIX, reqp->pid,
reqp->eid, vname) >= sizeof(iqn)) {
error("STORAGECONFIG: %s: Not enough room in "
"IQN string buffer", reqp->vnodeid);
mysql_free_result(res);
mysql_free_result(res2);
return 1;
}
bufp = buf;
bufp += OUTPUT(bufp, ebufp-bufp,
"CMD=SLICE IDX=%d "
"CLASS=%s PROTO=%s BSID=%s "
"VOLNAME=%s VOLSIZE=%d\n",
cmdidx++, class, protocol, bsid,
iqn, volsize);
client_writeback(sock, buf, strlen(buf), tcp);
bufp = buf;
bufp += OUTPUT(bufp, ebufp-bufp,
"CMD=EXPORT IDX=%d "
"VOLNAME=%s PERMS=%s\n",
cmdidx++, iqn, perms);
client_writeback(sock, buf, strlen(buf), tcp);
}
mysql_free_result(res);
mysql_free_result(res2);
return 0;
}
/* nothing to return... */
return 0;
}
/*
* Return mount stuff.
*/
......
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