blob: bee2718e4ce23a1c80a758d95f7b4f425d698e57 [file] [log] [blame] [edit]
/*****************************************************************************\
* configure_functions.c - Functions related to configure mode of smap.
* $Id$
*****************************************************************************
* Copyright (C) 2002 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@llnl.gov>
*
* UCRL-CODE-226842.
*
* This file is part of SLURM, a resource management program.
* For details, see <http://www.llnl.gov/linux/slurm/>.
*
* SLURM is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* In addition, as a special exception, the copyright holders give permission
* to link the code of portions of this program with the OpenSSL library under
* certain conditions as described in each individual source file, and
* distribute linked combinations including the two. You must obey the GNU
* General Public License in all respects for all of the code used other than
* OpenSSL. If you modify file(s) with this exception, you may extend this
* exception to your version of the file(s), but you are not obligated to do
* so. If you do not wish to do so, delete this exception statement from your
* version. If you delete this exception statement from all source files in
* the program, then also delete it here.
*
* SLURM 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 General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along
* with SLURM; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\*****************************************************************************/
#include "src/common/uid.h"
#include "src/smap/smap.h"
typedef struct {
int color;
char letter;
List nodes;
ba_request_t *request;
} allocated_block_t;
static void _delete_allocated_blocks(List allocated_blocks);
static allocated_block_t *_make_request(ba_request_t *request);
static int _set_layout(char *com);
static int _set_base_part_cnt(char *com);
static int _set_nodecard_cnt(char *com);
static int _create_allocation(char *com, List allocated_blocks);
static int _resolve(char *com);
static int _change_state_all_bps(char *com, int state);
static int _change_state_bps(char *com, int state);
static int _remove_allocation(char *com, List allocated_blocks);
static int _alter_allocation(char *com, List allocated_blocks);
static int _copy_allocation(char *com, List allocated_blocks);
static int _save_allocation(char *com, List allocated_blocks);
static int _add_bg_record(blockreq_t *blockreq, List allocated_blocks);
static int _load_configuration(char *com, List allocated_blocks);
static void _print_header_command(void);
static void _print_text_command(allocated_block_t *allocated_block);
char error_string[255];
int base_part_node_cnt = 512;
int nodecard_node_cnt = 32;
char *layout_mode = "STATIC";
static void _delete_allocated_blocks(List allocated_blocks)
{
allocated_block_t *allocated_block = NULL;
while ((allocated_block = list_pop(allocated_blocks)) != NULL) {
remove_block(allocated_block->nodes,0);
list_destroy(allocated_block->nodes);
delete_ba_request(allocated_block->request);
xfree(allocated_block);
}
list_destroy(allocated_blocks);
}
static allocated_block_t *_make_request(ba_request_t *request)
{
List results = list_create(NULL);
ListIterator results_i;
allocated_block_t *allocated_block = NULL;
ba_node_t *current = NULL;
if (!allocate_block(request, results)){
memset(error_string,0,255);
sprintf(error_string,"allocate failure for %dx%dx%d",
request->geometry[0], request->geometry[1],
request->geometry[2]);
return NULL;
} else {
if(request->passthrough)
sprintf(error_string,"THERE ARE PASSTHROUGHS IN "
"THIS ALLOCATION!!!!!!!");
allocated_block = (allocated_block_t *)xmalloc(
sizeof(allocated_block_t));
allocated_block->request = request;
allocated_block->nodes = list_create(NULL);
results_i = list_iterator_create(results);
while ((current = list_next(results_i)) != NULL) {
list_append(allocated_block->nodes,current);
allocated_block->color = current->color;
allocated_block->letter = current->letter;
}
list_iterator_destroy(results_i);
}
list_destroy(results);
return(allocated_block);
}
static int _set_layout(char *com)
{
int i=0;
int len = strlen(com);
while(i<len) {
if(!strncasecmp(com+i, "dynamic", 7)) {
layout_mode = "DYNAMIC";
break;
} else if(!strncasecmp(com+i, "static", 6)) {
layout_mode = "STATIC";
break;
} else if(!strncasecmp(com+i, "overlap", 7)) {
layout_mode = "OVERLAP";
break;
} else {
i++;
}
}
if(i>=len) {
sprintf(error_string,
"You didn't put in a mode that I recognized. \n"
"Please use (STATIC, OVERLAP, or DYNAMIC)\n");
return 0;
}
sprintf(error_string,
"LayoutMode set to %s\n", layout_mode);
return 1;
}
static int _set_base_part_cnt(char *com)
{
int i=0;
int len = strlen(com);
while(i<len) {
if(com[i] < 58 && com[i] > 47) {
break;
} else {
i++;
}
}
if(i>=len) {
sprintf(error_string,
"I didn't notice the number you typed in\n");
return 0;
}
base_part_node_cnt = atoi(&com[i]);
sprintf(error_string,
"BasePartitionNodeCnt set to %d\n", base_part_node_cnt);
return 1;
}
static int _set_nodecard_cnt(char *com)
{
int i=0;
int len = strlen(com);
while(i<len) {
if(com[i] < 58 && com[i] > 47) {
break;
} else {
i++;
}
}
if(i>=len) {
sprintf(error_string,
"I didn't notice the number you typed in\n");
return 0;
}
nodecard_node_cnt = atoi(&com[i]);
sprintf(error_string,
"NodeCardNodeCnt set to %d\n", nodecard_node_cnt);
return 1;
}
static int _create_allocation(char *com, List allocated_blocks)
{
int i=6, geoi=-1, starti=-1, i2=0, nodecards=-1, quarters=-1;
int len = strlen(com);
allocated_block_t *allocated_block = NULL;
ba_request_t *request = (ba_request_t*) xmalloc(sizeof(ba_request_t));
int diff=0;
request->geometry[0] = (uint16_t)NO_VAL;
request->conn_type=SELECT_TORUS;
request->rotate = false;
request->elongate = false;
request->start_req=0;
request->size = 0;
request->nodecards = 0;
request->quarters = 0;
request->passthrough = false;
request->avail_node_bitmap = NULL;
while(i<len) {
if(!strncasecmp(com+i, "mesh", 4)) {
request->conn_type=SELECT_MESH;
i+=4;
} else if(!strncasecmp(com+i, "small", 5)) {
request->conn_type = SELECT_SMALL;
i+=5;
} else if(!strncasecmp(com+i, "nodecard", 8)) {
nodecards=0;
i+=5;
} else if(!strncasecmp(com+i, "quarter", 7)) {
quarters=0;
i+=6;
} else if(!strncasecmp(com+i, "rotate", 6)) {
request->rotate=true;
i+=6;
} else if(!strncasecmp(com+i, "elongate", 8)) {
request->elongate=true;
i+=8;
} else if(!strncasecmp(com+i, "start", 5)) {
request->start_req=1;
i+=5;
} else if(request->start_req
&& starti<0
&& ((com[i] >= '0' && com[i] <= '9')
|| (com[i] >= 'A' && com[i] <= 'Z'))) {
starti=i;
i++;
} else if(nodecards == 0 && (com[i] < 58 && com[i] > 47)) {
nodecards=i;
i++;
} else if(quarters == 0 && (com[i] < 58 && com[i] > 47)) {
quarters=i;
i++;
} else if(geoi<0 && ((com[i] >= '0' && com[i] <= '9')
|| (com[i] >= 'A' && com[i] <= 'Z'))) {
geoi=i;
i++;
} else {
i++;
}
}
if(request->conn_type == SELECT_SMALL) {
if(nodecards > 0) {
request->nodecards = atoi(&com[nodecards]);
nodecards = request->nodecards/4;
request->nodecards = nodecards*4;
}
request->quarters = 4;
if(request->nodecards > 0)
request->quarters -= nodecards;
if(request->quarters > 4) {
request->quarters = 4;
request->nodecards = 0;
} else if(request->nodecards > 16) {
request->quarters = 0;
request->nodecards = 16;
}
quarters = request->quarters*4;
nodecards = request->nodecards;
if((quarters+nodecards) > 16) {
sprintf(error_string,
"please specify a complete split of a "
"Base Partion\n"
"(i.e. nodecards=4)");
geoi = -1;
}
request->size = 1;
}
if(geoi<0 && !request->size) {
memset(error_string,0,255);
sprintf(error_string,
"No size or dimension specified, please re-enter");
} else {
i2=geoi;
while(i2<len) {
if(request->size)
break;
if(com[i2]==' ' || i2==(len-1)) {
/* for size */
request->size = atoi(&com[geoi]);
break;
}
if(com[i2]=='x') {
diff = i2-geoi;
/* for geometery */
if(diff>1) {
request->geometry[X] =
xstrntol(&com[geoi],
NULL, diff,
10);
} else {
request->geometry[X] =
xstrntol(&com[geoi],
NULL, diff,
HOSTLIST_BASE);
}
geoi += diff;
diff = geoi;
while(com[geoi-1]!='x' && geoi<len)
geoi++;
if(geoi==len)
goto geo_error_message;
diff = geoi - diff;
if(diff>1) {
request->geometry[Y] =
xstrntol(&com[geoi],
NULL, diff,
10);
} else {
request->geometry[Y] =
xstrntol(&com[geoi],
NULL, diff,
HOSTLIST_BASE);
}
geoi += diff;
diff = geoi;
while(com[geoi-1]!='x' && geoi<len)
geoi++;
if(geoi==len)
goto geo_error_message;
diff = geoi - diff;
if(diff>1) {
request->geometry[Z] =
xstrntol(&com[geoi],
NULL, diff,
10);
} else {
request->geometry[Z] =
xstrntol(&com[geoi],
NULL, diff,
HOSTLIST_BASE);
}
request->size = -1;
break;
}
i2++;
}
if(request->start_req) {
i2 = starti;
while(com[i2]!='x' && i2<len)
i2++;
diff = i2-starti;
if(diff>1) {
request->start[X] = xstrntol(&com[starti],
NULL, diff,
10);
} else {
request->start[X] = xstrntol(&com[starti],
NULL, diff,
HOSTLIST_BASE);
}
starti += diff;
if(starti==len)
goto start_request;
starti++;
i2 = starti;
while(com[i2]!='x' && i2<len)
i2++;
diff = i2-starti;
if(diff>1) {
request->start[Y] = xstrntol(&com[starti],
NULL, diff,
10);
} else {
request->start[Y] = xstrntol(&com[starti],
NULL, diff,
HOSTLIST_BASE);
}
starti += diff;
if(starti==len)
goto start_request;
starti++;
i2 = starti;
while(com[i2]!=' ' && i2<len)
i2++;
diff = i2-starti;
if(diff>1) {
request->start[Z] = xstrntol(&com[starti],
NULL, diff,
10);
} else {
request->start[Z] = xstrntol(&com[starti],
NULL, diff,
HOSTLIST_BASE);
}
}
start_request:
if(!strcasecmp(layout_mode,"OVERLAP"))
reset_ba_system(true);
/*
Here is where we do the allocating of the partition.
It will send a request back which we will throw into
a list just incase we change something later.
*/
if(!new_ba_request(request)) {
memset(error_string,0,255);
if(request->size!=-1) {
sprintf(error_string,
"Problems with request for %d\n"
"Either you put in something "
"that doesn't work,\n"
"or we are unable to process "
"your request.",
request->size);
} else
sprintf(error_string,
"Problems with request for %dx%dx%d\n"
"Either you put in something "
"that doesn't work,\n"
"or we are unable to process "
"your request.",
request->geometry[0],
request->geometry[1],
request->geometry[2]);
} else {
if((allocated_block = _make_request(request)) != NULL)
list_append(allocated_blocks,
allocated_block);
else {
i2 = strlen(error_string);
sprintf(error_string+i2,
"\nGeo requested was %d (%dx%dx%d)\n"
"Start position was %dx%dx%d",
request->size,
request->geometry[0],
request->geometry[1],
request->geometry[2],
request->start[0],
request->start[1],
request->start[2]);
}
}
}
return 1;
geo_error_message:
memset(error_string,0,255);
sprintf(error_string,
"Error in geo dimension "
"specified, please re-enter");
return 0;
}
static int _resolve(char *com)
{
int i=0;
#ifdef HAVE_BG_FILES
int len=strlen(com);
char *rack_mid = NULL;
int *coord = NULL;
#endif
while(com[i-1] != ' ' && com[i] != '\0')
i++;
if(com[i] == 'r')
com[i] = 'R';
memset(error_string,0,255);
#ifdef HAVE_BG_FILES
if (!have_db2) {
sprintf(error_string, "Must be on BG SN to resolve\n");
goto resolve_error;
}
if(len-i<3) {
sprintf(error_string, "Must enter 3 coords to resolve.\n");
goto resolve_error;
}
if(com[i] != 'R') {
rack_mid = find_bp_rack_mid(com+i);
if(rack_mid)
sprintf(error_string,
"X=%c Y=%c Z=%c resolves to %s\n",
com[X+i],com[Y+i],com[Z+i], rack_mid);
else
sprintf(error_string,
"X=%c Y=%c Z=%c has no resolve\n",
com[X+i],com[Y+i],com[Z+i]);
} else {
coord = find_bp_loc(com+i);
if(coord)
sprintf(error_string,
"%s resolves to X=%d Y=%d Z=%d\n",
com+i,coord[X],coord[Y],coord[Z]);
else
sprintf(error_string, "%s has no resolve.\n",
com+i);
}
resolve_error:
#else
sprintf(error_string,
"Must be on BG SN to resolve.\n");
#endif
wnoutrefresh(text_win);
doupdate();
return 1;
}
static int _change_state_all_bps(char *com, int state)
{
char allnodes[50];
memset(allnodes,0,50);
#ifdef HAVE_BG
sprintf(allnodes, "000x%c%c%c",
alpha_num[DIM_SIZE[X]-1], alpha_num[DIM_SIZE[Y]-1],
alpha_num[DIM_SIZE[Z]-1]);
#else
sprintf(allnodes, "0-%d",
DIM_SIZE[X]);
#endif
return _change_state_bps(allnodes, state);
}
static int _change_state_bps(char *com, int state)
{
int i=0, x;
int len = strlen(com);
int start[SYSTEM_DIMENSIONS], end[SYSTEM_DIMENSIONS];
#ifdef HAVE_BG
int number=0, y=0, z=0, j=0;
#endif
char letter = '.';
char opposite = '#';
bool used = false;
char *c_state = "up";
if(state == NODE_STATE_DOWN) {
letter = '#';
opposite = '.';
used = true;
c_state = "down";
}
while(i<len
&& (com[i] < '0' || com[i] > 'Z'
|| (com[i] > '9' && com[i] < 'A')))
i++;
if(i>(len-1)) {
memset(error_string,0,255);
sprintf(error_string,
"You didn't specify any nodes to make %s. "
"in statement '%s'",
c_state, com);
return 0;
}
#ifdef HAVE_BG
if ((com[i+3] == 'x')
|| (com[i+3] == '-')) {
for(j=0; j<3; j++)
if((i+j)>len
|| (com[i+j] < '0' || com[i+j] > 'Z'
|| (com[i+j] > '9' && com[i+j] < 'A')))
goto error_message2;
number = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
start[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
start[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
start[Z] = (number % HOSTLIST_BASE);
i += 4;
for(j=0; j<3; j++)
if((i+j)>len
|| (com[i+j] < '0' || com[i+j] > 'Z'
|| (com[i+j] > '9' && com[i+j] < 'A')))
goto error_message2;
number = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
end[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
end[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
end[Z] = (number % HOSTLIST_BASE);
} else {
for(j=0; j<3; j++)
if((i+j)>len
|| (com[i+j] < '0' || com[i+j] > 'Z'
|| (com[i+j] > '9' && com[i+j] < 'A')))
goto error_message2;
number = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
start[X] = end[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
start[Y] = end[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
start[Z] = end[Z] = (number % HOSTLIST_BASE);
}
if((start[X]>end[X]
|| start[Y]>end[Y]
|| start[Z]>end[Z])
|| (start[X]<0
|| start[Y]<0
|| start[Z]<0)
|| (end[X]>DIM_SIZE[X]-1
|| end[Y]>DIM_SIZE[Y]-1
|| end[Z]>DIM_SIZE[Z]-1))
goto error_message;
for(x=start[X];x<=end[X];x++) {
for(y=start[Y];y<=end[Y];y++) {
for(z=start[Z];z<=end[Z];z++) {
if(ba_system_ptr->grid[x][y][z].letter
!= opposite)
continue;
ba_system_ptr->grid[x][y][z].color = 0;
ba_system_ptr->grid[x][y][z].letter = letter;
ba_system_ptr->grid[x][y][z].used = used;
}
}
}
#else
if ((com[i+3] == 'x')
|| (com[i+3] == '-')) {
start[X] = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);;
i += 4;
end[X] = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
} else {
start[X] = end[X] = xstrntol(com + i, NULL,
BA_SYSTEM_DIMENSIONS,
HOSTLIST_BASE);
}
if((start[X]>end[X])
|| (start[X]<0)
|| (end[X]>DIM_SIZE[X]-1))
goto error_message;
for(x=start[X];x<=end[X];x++) {
ba_system_ptr->grid[x].color = 0;
ba_system_ptr->grid[x].letter = letter;
ba_system_ptr->grid[x].used = used;
}
#endif
return 1;
error_message:
memset(error_string,0,255);
#ifdef HAVE_BG
sprintf(error_string,
"Problem with base partitions, "
"specified range was %d%d%dx%d%d%d",
alpha_num[start[X]],alpha_num[start[Y]],alpha_num[start[Z]],
alpha_num[end[X]],alpha_num[end[Y]],alpha_num[end[Z]]);
#else
sprintf(error_string,
"Problem with nodes, specified range was %d-%d",
start[X],end[X]);
#endif
return 0;
#ifdef HAVE_BG
error_message2:
memset(error_string,0,255);
sprintf(error_string,
"There was a problem with '%s'\nIn your request '%s'"
"You need to specify XYZ or XYZxXYZ",
com+i,com);
return 0;
#endif
}
static int _remove_allocation(char *com, List allocated_blocks)
{
ListIterator results_i;
allocated_block_t *allocated_block = NULL;
int i=6, found=0;
int len = strlen(com);
char letter;
int color_count = 0;
while(com[i-1]!=' ' && i<len) {
i++;
}
if(i>(len-1)) {
memset(error_string,0,255);
sprintf(error_string,
"You need to specify which letter to delete.");
return 0;
} else {
letter = com[i];
results_i = list_iterator_create(allocated_blocks);
while((allocated_block = list_next(results_i)) != NULL) {
if(found) {
if(redo_block(allocated_block->nodes,
allocated_block->
request->geometry,
allocated_block->
request->conn_type,
color_count) == SLURM_ERROR) {
memset(error_string,0,255);
sprintf(error_string,
"problem redoing the part.");
return 0;
}
allocated_block->letter =
letters[color_count%62];
allocated_block->color =
colors[color_count%6];
} else if(allocated_block->letter == letter) {
found=1;
remove_block(allocated_block->nodes,
color_count);
list_destroy(allocated_block->nodes);
delete_ba_request(allocated_block->request);
list_remove(results_i);
color_count--;
}
color_count++;
}
list_iterator_destroy(results_i);
}
return 1;
}
static int _alter_allocation(char *com, List allocated_blocks)
{
/* this doesn't do anything yet. */
/* int torus=SELECT_TORUS, i=5, i2=0; */
/* int len = strlen(com); */
/* bool rotate = false; */
/* bool elongate = false; */
/* while(i<len) { */
/* while(com[i-1]!=' ' && i<len) { */
/* i++; */
/* } */
/* if(!strncasecmp(com+i, "mesh", 4)) { */
/* torus=SELECT_MESH; */
/* i+=4; */
/* } else if(!strncasecmp(com+i, "rotate", 6)) { */
/* rotate=true; */
/* i+=6; */
/* } else if(!strncasecmp(com+i, "elongate", 8)) { */
/* elongate=true; */
/* i+=8; */
/* } else if(com[i] < 58 && com[i] > 47) { */
/* i2=i; */
/* i++; */
/* } else { */
/* i++; */
/* } */
/* } */
return 1;
}
static int _copy_allocation(char *com, List allocated_blocks)
{
ListIterator results_i;
allocated_block_t *allocated_block = NULL;
allocated_block_t *temp_block = NULL;
ba_request_t *request = NULL;
int i=0;
int len = strlen(com);
char letter = '\0';
int count = 1;
int *geo = NULL, *geo_ptr = NULL;
while(com[i-1]!=' ' && i<=len) {
i++;
}
if(i<=len) {
/* Here we are looking for a real number for the count
instead of the HOSTLIST_BASE so atoi is ok
*/
if(com[i]>='0' && com[i]<='9')
count = atoi(com+i);
else {
letter = com[i];
i++;
if(com[i]!='\n') {
while(com[i-1]!=' ' && i<len)
i++;
if(com[i]>='0' && com[i]<='9')
count = atoi(com+i);
}
}
}
results_i = list_iterator_create(allocated_blocks);
while((allocated_block = list_next(results_i)) != NULL) {
temp_block = allocated_block;
if(allocated_block->letter != letter)
continue;
break;
}
list_iterator_destroy(results_i);
if(!letter)
allocated_block = temp_block;
if(!allocated_block) {
memset(error_string,0,255);
sprintf(error_string,
"Could not find requested record to copy");
return 0;
}
for(i=0;i<count;i++) {
request = (ba_request_t*) xmalloc(sizeof(ba_request_t));
request->geometry[X] = allocated_block->request->geometry[X];
request->geometry[Y] = allocated_block->request->geometry[Y];
request->geometry[Z] = allocated_block->request->geometry[Z];
request->size = allocated_block->request->size;
request->conn_type=allocated_block->request->conn_type;
request->rotate =allocated_block->request->rotate;
request->elongate = allocated_block->request->elongate;
request->nodecards = allocated_block->request->nodecards;
request->quarters = allocated_block->request->quarters;
request->rotate_count= 0;
request->elongate_count = 0;
request->elongate_geos = list_create(NULL);
request->avail_node_bitmap = NULL;
results_i = list_iterator_create(request->elongate_geos);
while ((geo_ptr = list_next(results_i)) != NULL) {
geo = xmalloc(sizeof(int)*3);
geo[X] = geo_ptr[X];
geo[Y] = geo_ptr[Y];
geo[Z] = geo_ptr[Z];
list_append(request->elongate_geos, geo);
}
list_iterator_destroy(results_i);
if((allocated_block = _make_request(request)) == NULL) {
memset(error_string,0,255);
sprintf(error_string,
"Problem with the copy\n"
"Are you sure there is enough room for it?");
xfree(request);
return 0;
}
list_append(allocated_blocks, allocated_block);
}
return 1;
}
static int _save_allocation(char *com, List allocated_blocks)
{
int len = strlen(com);
int i=5, j=0;
allocated_block_t *allocated_block = NULL;
char filename[20];
char save_string[255];
FILE *file_ptr = NULL;
char *conn_type = NULL;
char extra[20];
ListIterator results_i;
memset(filename,0,20);
if(len>5)
while(i<len) {
while(com[i-1]!=' ' && i<len) {
i++;
}
while(i<len && com[i]!=' ') {
filename[j] = com[i];
i++;
j++;
}
}
if(filename[0]=='\0') {
time_t now_time = time(NULL);
sprintf(filename,"bluegene.conf.%ld",
(long int) now_time);
}
file_ptr = fopen(filename,"w");
if (file_ptr!=NULL) {
fputs ("#\n# bluegene.conf file generated by smap\n", file_ptr);
fputs ("# See the bluegene.conf man page for more information\n",
file_ptr);
fputs ("#\n", file_ptr);
fputs ("BlrtsImage="
"/bgl/BlueLight/ppcfloor/bglsys/bin/rts_hw.rts\n",
file_ptr);
fputs ("LinuxImage="
"/bgl/BlueLight/ppcfloor/bglsys/bin/zImage.elf\n",
file_ptr);
fputs ("MloaderImage="
"/bgl/BlueLight/ppcfloor/bglsys/bin/mmcs-mloader.rts\n",
file_ptr);
fputs ("RamDiskImage="
"/bgl/BlueLight/ppcfloor/bglsys/bin/ramdisk.elf\n",
file_ptr);
fputs ("BridgeAPILogFile="
"/var/log/slurm/bridgeapi.log\n",
file_ptr);
fputs ("Numpsets=8\n", file_ptr);
fputs ("BridgeAPIVerbose=0\n", file_ptr);
sprintf(save_string, "BasePartitionNodeCnt=%d\n",
base_part_node_cnt);
fputs (save_string,file_ptr);
sprintf(save_string, "NodeCardNodeCnt=%d\n",
nodecard_node_cnt);
fputs (save_string,file_ptr);
sprintf(save_string, "LayoutMode=%s\n",
layout_mode);
fputs (save_string,file_ptr);
fputs("#\n# Block Layout\n#\n", file_ptr);
results_i = list_iterator_create(allocated_blocks);
while((allocated_block = list_next(results_i)) != NULL) {
memset(save_string,0,255);
memset(extra,0,20);
if(allocated_block->request->conn_type == SELECT_TORUS)
conn_type = "TORUS";
else if(allocated_block->request->conn_type
== SELECT_MESH)
conn_type = "MESH";
else {
conn_type = "SMALL";
sprintf(extra, " NodeCards=%d Quarters=%d",
allocated_block->request->nodecards,
allocated_block->request->quarters);
}
sprintf(save_string, "BPs=%s Type=%s%s\n",
allocated_block->request->save_name,
conn_type, extra);
fputs (save_string,file_ptr);
}
fclose (file_ptr);
}
return 1;
}
static int _add_bg_record(blockreq_t *blockreq, List allocated_blocks)
{
#ifdef HAVE_BG
char *nodes = NULL, *conn_type = NULL;
int bp_count = 0;
int start[BA_SYSTEM_DIMENSIONS];
int end[BA_SYSTEM_DIMENSIONS];
int start1[BA_SYSTEM_DIMENSIONS];
int end1[BA_SYSTEM_DIMENSIONS];
int geo[BA_SYSTEM_DIMENSIONS];
char com[255];
int j = 0, number;
int len = 0;
int x,y,z;
start1[X] = 0;
start1[Y] = 0;
start1[Z] = 0;
geo[X] = 0;
geo[Y] = 0;
geo[Z] = 0;
start1[X] = -1;
start1[Y] = -1;
start1[Z] = -1;
end1[X] = -1;
end1[Y] = -1;
end1[Z] = -1;
switch(blockreq->conn_type) {
case SELECT_MESH:
conn_type = "mesh";
break;
case SELECT_SMALL:
conn_type = "small";
break;
case SELECT_TORUS:
default:
conn_type = "torus";
break;
}
nodes = blockreq->block;
if(!nodes)
return SLURM_SUCCESS;
len = strlen(nodes);
while (nodes[j] != '\0') {
if(j > len)
break;
else if ((nodes[j] == '[' || nodes[j] == ',')
&& (nodes[j+8] == ']' || nodes[j+8] == ',')
&& (nodes[j+4] == 'x' || nodes[j+4] == '-')) {
j++;
number = xstrntol(nodes + j, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
start[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
start[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
start[Z] = (number % HOSTLIST_BASE);
j += 4;
number = xstrntol(nodes + j, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
end[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
end[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
end[Z] = (number % HOSTLIST_BASE);
j += 3;
if(!bp_count) {
start1[X] = start[X];
start1[Y] = start[Y];
start1[Z] = start[Z];
}
for (x = start[X]; x <= end[X]; x++)
for (y = start[Y]; y <= end[Y]; y++)
for (z = start[Z]; z <= end[Z]; z++) {
if(x>end1[X]) {
geo[X]++;
end1[X] = x;
}
if(y>end1[Y]) {
geo[Y]++;
end1[Y] = y;
}
if(z>end1[Z]) {
geo[Z]++;
end1[Z] = z;
}
bp_count++;
}
if(nodes[j] != ',')
break;
j--;
} else if((nodes[j] >= '0' && nodes[j] <= '9')
|| (nodes[j] >= 'A' && nodes[j] <= 'Z')) {
number = xstrntol(nodes + j, NULL,
BA_SYSTEM_DIMENSIONS, HOSTLIST_BASE);
start[X] = number / (HOSTLIST_BASE * HOSTLIST_BASE);
start[Y] = (number % (HOSTLIST_BASE * HOSTLIST_BASE))
/ HOSTLIST_BASE;
start[Z] = (number % HOSTLIST_BASE);
j+=3;
if(!bp_count) {
start1[X] = start[X];
start1[Y] = start[Y];
start1[Z] = start[Z];
}
if(start[X]>end1[X]) {
geo[X]++;
end1[X] = start[X];
}
if(start[Y]>end1[Y]) {
geo[Y]++;
end1[Y] = start[Y];
}
if(start[Z]>end1[Z]) {
geo[Z]++;
end1[Z] = start[Z];
}
bp_count++;
if(nodes[j] != ',')
break;
j--;
}
j++;
}
memset(com,0,255);
sprintf(com,"create %dx%dx%d %s start %dx%dx%d "
"nodecards=%d quarters=%d",
geo[X], geo[Y], geo[Z], conn_type,
start1[X], start1[Y], start1[Z],
blockreq->nodecards, blockreq->quarters);
_create_allocation(com, allocated_blocks);
#endif
return SLURM_SUCCESS;
}
static int _load_configuration(char *com, List allocated_blocks)
{
int len = strlen(com);
int i=5, j=0;
char filename[100];
s_p_hashtbl_t *tbl = NULL;
char *layout = NULL;
blockreq_t **blockreq_array = NULL;
int count = 0;
_delete_allocated_blocks(allocated_blocks);
allocated_blocks = list_create(NULL);
memset(filename,0,100);
if(len>5)
while(i<len) {
while(com[i-1]!=' ' && i<len) {
i++;
}
while(i<len && com[i]!=' ') {
filename[j] = com[i];
i++;
j++;
if(j>100) {
memset(error_string,0,255);
sprintf(error_string,
"filename is too long needs "
"to be under 100 chars");
return 0;
}
}
}
if(filename[0]=='\0') {
sprintf(filename,"bluegene.conf");
}
tbl = s_p_hashtbl_create(bg_conf_file_options);
if(s_p_parse_file(tbl, filename) == SLURM_ERROR) {
memset(error_string,0,255);
sprintf(error_string, "ERROR: couldn't open/read %s",
filename);
return 0;
}
if (!s_p_get_string(&layout, "LayoutMode", tbl)) {
memset(error_string,0,255);
sprintf(error_string,
"Warning: LayoutMode was not specified in "
"bluegene.conf defaulting to STATIC partitioning");
} else {
_set_layout(layout);
xfree(layout);
}
if(strcasecmp(layout_mode, "DYNAMIC")) {
if (!s_p_get_array((void ***)&blockreq_array,
&count, "BPs", tbl)) {
memset(error_string,0,255);
sprintf(error_string,
"WARNING: no blocks defined in "
"bluegene.conf");
}
for (i = 0; i < count; i++) {
_add_bg_record(blockreq_array[i], allocated_blocks);
}
}
s_p_hashtbl_destroy(tbl);
return 1;
}
static void _print_header_command(void)
{
main_ycord=2;
mvwprintw(text_win, main_ycord,
main_xcord, "ID");
main_xcord += 4;
mvwprintw(text_win, main_ycord,
main_xcord, "TYPE");
main_xcord += 7;
mvwprintw(text_win, main_ycord,
main_xcord, "ROTATE");
main_xcord += 7;
mvwprintw(text_win, main_ycord,
main_xcord, "ELONG");
main_xcord += 7;
#ifdef HAVE_BG
mvwprintw(text_win, main_ycord,
main_xcord, "BP_COUNT");
#else
mvwprintw(text_win, main_ycord,
main_xcord, "NODES");
#endif
main_xcord += 10;
mvwprintw(text_win, main_ycord,
main_xcord, "NODECARDS");
main_xcord += 11;
mvwprintw(text_win, main_ycord,
main_xcord, "QUARTERS");
main_xcord += 10;
#ifdef HAVE_BG
mvwprintw(text_win, main_ycord,
main_xcord, "BP_LIST");
#else
mvwprintw(text_win, main_ycord,
main_xcord, "NODELIST");
#endif
main_xcord = 1;
main_ycord++;
}
static void _print_text_command(allocated_block_t *allocated_block)
{
wattron(text_win,
COLOR_PAIR(allocated_block->color));
mvwprintw(text_win, main_ycord,
main_xcord, "%c",allocated_block->letter);
main_xcord += 4;
if(allocated_block->request->conn_type==SELECT_TORUS)
mvwprintw(text_win, main_ycord,
main_xcord, "TORUS");
else if (allocated_block->request->conn_type==SELECT_MESH)
mvwprintw(text_win, main_ycord,
main_xcord, "MESH");
else
mvwprintw(text_win, main_ycord,
main_xcord, "SMALL");
main_xcord += 7;
if(allocated_block->request->rotate)
mvwprintw(text_win, main_ycord,
main_xcord, "Y");
else
mvwprintw(text_win, main_ycord,
main_xcord, "N");
main_xcord += 7;
if(allocated_block->request->elongate)
mvwprintw(text_win, main_ycord,
main_xcord, "Y");
else
mvwprintw(text_win, main_ycord,
main_xcord, "N");
main_xcord += 7;
mvwprintw(text_win, main_ycord,
main_xcord, "%d",allocated_block->request->size);
main_xcord += 10;
if(allocated_block->request->conn_type == SELECT_SMALL) {
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->nodecards);
main_xcord += 11;
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->quarters);
main_xcord += 10;
} else
main_xcord += 21;
mvwprintw(text_win, main_ycord,
main_xcord, "%s",
allocated_block->request->save_name);
main_xcord = 1;
main_ycord++;
wattroff(text_win,
COLOR_PAIR(allocated_block->color));
return;
}
void get_command(void)
{
char com[255];
int text_width, text_startx;
allocated_block_t *allocated_block = NULL;
int i=0;
int count=0;
WINDOW *command_win;
List allocated_blocks;
ListIterator results_i;
if(params.commandline) {
printf("Configure won't work with commandline mode.\n");
printf("Please remove the -c from the commandline.\n");
ba_fini();
exit(0);
}
init_wires();
allocated_blocks = list_create(NULL);
text_width = text_win->_maxx;
text_startx = text_win->_begx;
command_win = newwin(3, text_width - 1, LINES - 4, text_startx + 1);
echo();
while (strcmp(com, "quit")) {
clear_window(grid_win);
print_grid(0);
clear_window(text_win);
box(text_win, 0, 0);
box(grid_win, 0, 0);
if (!params.no_header)
_print_header_command();
if(error_string!=NULL) {
i=0;
while(error_string[i]!='\0') {
if(error_string[i]=='\n') {
main_ycord++;
main_xcord=1;
i++;
}
mvwprintw(text_win,
main_ycord,
main_xcord,
"%c",
error_string[i++]);
main_xcord++;
}
main_ycord++;
main_xcord=1;
memset(error_string,0,255);
}
results_i = list_iterator_create(allocated_blocks);
count = list_count(allocated_blocks)
- (LINES-(main_ycord+5));
if(count<0)
count=0;
i=0;
while((allocated_block = list_next(results_i)) != NULL) {
if(i>=count)
_print_text_command(allocated_block);
i++;
}
list_iterator_destroy(results_i);
wnoutrefresh(text_win);
wnoutrefresh(grid_win);
doupdate();
clear_window(command_win);
box(command_win, 0, 0);
mvwprintw(command_win, 0, 3,
"Input Command: (type quit to change view, "
"exit to exit)");
wmove(command_win, 1, 1);
wgetstr(command_win, com);
if (!strcmp(com, "exit")) {
endwin();
_delete_allocated_blocks(allocated_blocks);
ba_fini();
exit(0);
} if (!strcmp(com, "quit")) {
break;
} else if (!strncasecmp(com, "layout", 6)) {
_set_layout(com);
} else if (!strncasecmp(com, "basepartition", 13)) {
_set_base_part_cnt(com);
} else if (!strncasecmp(com, "nodecard", 8)) {
_set_nodecard_cnt(com);
} else if (!strncasecmp(com, "resolve", 7) ||
!strncasecmp(com, "r ", 2)) {
_resolve(com);
} else if (!strncasecmp(com, "resume", 6)) {
mvwprintw(text_win,
main_ycord,
main_xcord, "%s", com);
} else if (!strncasecmp(com, "drain", 5)) {
mvwprintw(text_win,
main_ycord,
main_xcord, "%s", com);
} else if (!strncasecmp(com, "alldown", 7)) {
_change_state_all_bps(com, NODE_STATE_DOWN);
} else if (!strncasecmp(com, "down", 4)) {
_change_state_bps(com, NODE_STATE_DOWN);
} else if (!strncasecmp(com, "allup", 5)) {
_change_state_all_bps(com, NODE_STATE_IDLE);
} else if (!strncasecmp(com, "up", 2)) {
_change_state_bps(com, NODE_STATE_IDLE);
} else if (!strncasecmp(com, "remove", 6)
|| !strncasecmp(com, "delete", 6)
|| !strncasecmp(com, "drop", 4)) {
_remove_allocation(com, allocated_blocks);
} else if (!strncasecmp(com, "alter", 5)) {
_alter_allocation(com, allocated_blocks);
} else if (!strncasecmp(com, "create", 6)) {
_create_allocation(com, allocated_blocks);
} else if (!strncasecmp(com, "copy", 4)
|| !strncasecmp(com, "c ", 2)
|| !strncasecmp(com, "c\0", 2)) {
_copy_allocation(com, allocated_blocks);
} else if (!strncasecmp(com, "save", 4)) {
_save_allocation(com, allocated_blocks);
} else if (!strncasecmp(com, "load", 4)) {
_load_configuration(com, allocated_blocks);
} else if (!strncasecmp(com, "clear all", 9)
|| !strncasecmp(com, "clear", 5)) {
_delete_allocated_blocks(allocated_blocks);
allocated_blocks = list_create(NULL);
} else {
memset(error_string,0,255);
sprintf(error_string, "Unknown command '%s'",com);
}
}
_delete_allocated_blocks(allocated_blocks);
params.display = 0;
noecho();
clear_window(text_win);
main_xcord = 1;
main_ycord = 1;
print_date();
get_job(0);
return;
}