blob: 3ac4a2c7f0de007c63690b6e3268d2f32abe67d1 [file] [log] [blame] [edit]
/*****************************************************************************\
* configure_functions.c - Functions related to configure mode of smap.
*****************************************************************************
* Copyright (C) 2002-2007 The Regents of the University of California.
* Copyright (C) 2008-2011 Lawrence Livermore National Security.
* Copyright (C) 2011 SchedMD LLC.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Danny Auble <da@schedmd.com>
*
* CODE-OCEC-09-009. All rights reserved.
*
* This file is part of SLURM, a resource management program.
* For details, see <http://www.schedmd.com/slurmdocs/>.
* Please also read the included file: DISCLAIMER.
*
* 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/smap/smap.h"
#include "src/common/uid.h"
#include "src/common/xstring.h"
#include "src/common/proc_args.h"
///////////////////////////////////////////////////////////////////////
typedef struct {
int color;
int color_count;
char letter;
List nodes;
select_ba_request_t *request;
} allocated_block_t;
static int _add_bg_record(select_ba_request_t *blockreq,
List allocated_blocks);
static int _change_state_all_bps(char *com, int state);
static int _change_state_bps(char *com, int state);
static int _copy_allocation(char *com, List allocated_blocks);
static int _create_allocation(char *com, List allocated_blocks);
static int _load_configuration(char *com, List allocated_blocks);
static allocated_block_t *_make_request(select_ba_request_t *request);
static void _print_header_command(void);
static void _print_text_command(allocated_block_t *allocated_block);
static int _remove_allocation(char *com, List allocated_blocks);
static int _resolve(char *com);
static int _save_allocation(char *com, List allocated_blocks);
static int _set_layout(char *com);
static int _set_base_part_cnt(char *com);
static int _set_nodecard_cnt(char *com);
int color_count = 0;
char error_string[255];
int base_part_node_cnt = 512;
int nodecard_node_cnt = 32;
char *layout_mode = "STATIC";
static void _set_nodes(List nodes, int color, char letter)
{
ListIterator itr;
smap_node_t *smap_node;
ba_mp_t *ba_mp;
if (!nodes || !smap_system_ptr)
return;
itr = list_iterator_create(nodes);
while ((ba_mp = list_next(itr))) {
if (!ba_mp->used)
continue;
smap_node = smap_system_ptr->grid[ba_mp->index];
smap_node->color = color;
smap_node->letter = letter;
}
list_iterator_destroy(itr);
return;
}
static void _destroy_allocated_block(void *object)
{
allocated_block_t *allocated_block = (allocated_block_t *)object;
if (allocated_block) {
bool is_small = (allocated_block->request->conn_type[0] >=
SELECT_SMALL);
if (allocated_block->nodes) {
_set_nodes(allocated_block->nodes, 0, '.');
bg_configure_remove_block(
allocated_block->nodes, is_small);
list_destroy(allocated_block->nodes);
}
destroy_select_ba_request(allocated_block->request);
xfree(allocated_block);
}
}
static allocated_block_t *_make_request(select_ba_request_t *request)
{
List results = list_create(NULL);
allocated_block_t *allocated_block = NULL;
#ifdef HAVE_BGQ
results = list_create(bg_configure_destroy_ba_mp);
#else
results = list_create(NULL);
#endif
if (bg_configure_allocate_block(request, results)) {
char *pass = bg_configure_ba_passthroughs_string(
request->deny_pass);
if (pass) {
sprintf(error_string,"THERE ARE PASSTHROUGHS IN "
"THIS ALLOCATION DIM %s!!!!!!!", pass);
xfree(pass);
}
allocated_block = xmalloc(sizeof(allocated_block_t));
allocated_block->request = request;
allocated_block->nodes = results;
allocated_block->letter = letters[color_count%62];
allocated_block->color = colors[color_count%6];
allocated_block->color_count = color_count++;
_set_nodes(allocated_block->nodes,
allocated_block->color,
allocated_block->letter);
results = NULL;
}
if (results)
list_destroy(results);
return allocated_block;
}
static int _full_request(select_ba_request_t *request,
bitstr_t *usable_mp_bitmap,
List allocated_blocks)
{
char *tmp_char = NULL, *tmp_char2 = NULL;
allocated_block_t *allocated_block;
int rc = 1;
if (!strcasecmp(layout_mode,"OVERLAP"))
bg_configure_reset_ba_system(true);
if (usable_mp_bitmap)
bg_configure_ba_set_removable_mps(usable_mp_bitmap, 1);
/*
* 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 (!bg_configure_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);
rc = 0;
} else {
tmp_char = bg_configure_give_geo(request->geometry,
params.cluster_dims,
1);
sprintf(error_string,
"Problems with request of size %s\n"
"Either you put in something "
"that doesn't work,\n"
"or we are unable to process "
"your request.",
tmp_char);
xfree(tmp_char);
rc = 0;
}
} else {
if ((allocated_block = _make_request(request)) != NULL)
list_append(allocated_blocks, allocated_block);
else {
if (request->geometry[0] != (uint16_t)NO_VAL)
tmp_char = bg_configure_give_geo(
request->geometry,
params.cluster_dims, 1);
tmp_char2 = bg_configure_give_geo(request->start,
params.cluster_dims,
1);
memset(error_string, 0, 255);
sprintf(error_string,
"allocate failure\nSize requested "
"was %d MidPlanes\n",
request->size);
if (tmp_char) {
sprintf(error_string + strlen(error_string),
"Geo requested was %s\n", tmp_char);
xfree(tmp_char);
} else {
sprintf(error_string + strlen(error_string),
"No geometry could be laid out "
"for that size\n");
}
sprintf(error_string + strlen(error_string),
"Start position was %s", tmp_char2);
xfree(tmp_char2);
rc = 0;
}
}
if (usable_mp_bitmap)
bg_configure_ba_reset_all_removed_mps();
return rc;
}
static int _set_layout(char *com)
{
int i;
for (i = 0; com[i]; i++) {
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;
}
}
if (com[i] == '\0') {
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;
for (i = 0; com[i]; i++) {
if ((com[i] >= '0') && (com[i] <= '9'))
break;
}
if (com[i] == '\0') {
sprintf(error_string,
"I didn't notice the number you typed in\n");
return 0;
}
base_part_node_cnt = atoi(&com[i]);
memset(error_string, 0, 255);
sprintf(error_string,
"BasePartitionNodeCnt set to %d\n", base_part_node_cnt);
return 1;
}
static int _set_nodecard_cnt(char *com)
{
int i;
for (i = 0; com[i]; i++) {
if ((com[i] >= '0') && (com[i] <= '9'))
break;
}
if (com[i] == '\0') {
sprintf(error_string,
"I didn't notice the number you typed in\n");
return 0;
}
nodecard_node_cnt = atoi(&com[i]);
memset(error_string, 0, 255);
sprintf(error_string,
"NodeCardNodeCnt set to %d\n", nodecard_node_cnt);
return 1;
}
static int _xlate_coord(char *str, int len)
{
if (len > 1)
return xstrntol(str, NULL, len, 10);
else
return xstrntol(str, NULL, len, params.cluster_base);
}
static int _create_allocation(char *com, List allocated_blocks)
{
int i=6, j, geoi=-1, starti=-1, i2=0, small32=-1, small128=-1;
int len = strlen(com);
select_ba_request_t *request;
char fini_char;
int diff=0;
#ifndef HAVE_BGL
#ifdef HAVE_BGP
int small16=-1;
#endif
int small64=-1, small256=-1;
#endif
request = (select_ba_request_t*) xmalloc(sizeof(select_ba_request_t));
request->rotate = false;
request->elongate = false;
request->start_req = 0;
request->size = 0;
request->small32 = 0;
request->small128 = 0;
request->deny_pass = 0;
request->avail_mp_bitmap = NULL;
for (j = 0; j < params.cluster_dims; j++) {
request->geometry[j] = (uint16_t) NO_VAL;
request->conn_type[j] = SELECT_TORUS;
}
while (i < len) {
if (!strncasecmp(com+i, "mesh", 4)
|| !strncasecmp(com+i, "small", 5)
|| !strncasecmp(com+i, "torus", 5)) {
char conn_type[200];
j = i;
while (j < len) {
if (com[j] == ' ')
break;
conn_type[j-i] = com[j];
j++;
if (j >= 200)
break;
}
conn_type[(j-i)+1] = '\0';
verify_conn_type(conn_type, request->conn_type);
i += j;
} else if (!strncasecmp(com+i, "deny", 4)) {
i += 4;
if (strstr(com+i, "A"))
request->deny_pass |= PASS_DENY_A;
if (strstr(com+i, "X"))
request->deny_pass |= PASS_DENY_X;
if (strstr(com+i, "Y"))
request->deny_pass |= PASS_DENY_Y;
if (strstr(com+i, "Z"))
request->deny_pass |= PASS_DENY_Z;
if (!strcasecmp(com+i, "ALL"))
request->deny_pass |= PASS_DENY_ALL;
} else if (!strncasecmp(com+i, "nodecard", 8)) {
small32 = 0;
i += 8;
} else if (!strncasecmp(com+i, "quarter", 7)) {
small128 = 0;
i += 7;
} else if (!strncasecmp(com+i, "32CN", 4)) {
small32 = 0;
i += 4;
} else if (!strncasecmp(com+i, "128CN", 5)) {
small128 = 0;
i += 5;
} 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 (small32 == 0 && (com[i] >= '0' && com[i] <= '9')) {
small32 = i;
i++;
} else if (small128 == 0 && (com[i] >= '0' && com[i] <= '9')) {
small128 = i;
i++;
}
#ifdef HAVE_BGP
else if (!strncasecmp(com+i, "16CN", 4)) {
small16 = 0;
i += 4;
} else if (small16 == 0 && (com[i] >= '0' && com[i] <= '9')) {
small16 = i;
i++;
}
#endif
#ifndef HAVE_BGL
else if (!strncasecmp(com+i, "64CN", 4)) {
small64 = 0;
i += 4;
} else if (!strncasecmp(com+i, "256CN", 5)) {
small256 = 0;
i += 5;
} else if (small64 == 0 && (com[i] >= '0' && com[i] <= '9')) {
small64 = i;
i++;
} else if (small256 == 0 && (com[i] >= '0' && com[i] <= '9')) {
small256 = i;
i++;
}
#endif
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[0] >= SELECT_SMALL) {
int total = 512;
#ifdef HAVE_BGP
if (small16 > 0) {
request->small16 = atoi(&com[small16]);
total -= request->small16 * 16;
}
#endif
#ifndef HAVE_BGL
if (small64 > 0) {
request->small64 = atoi(&com[small64]);
total -= request->small64 * 64;
}
if (small256 > 0) {
request->small256 = atoi(&com[small256]);
total -= request->small256 * 256;
}
#endif
if (small32 > 0) {
request->small32 = atoi(&com[small32]);
total -= request->small32 * 32;
}
if (small128 > 0) {
request->small128 = atoi(&com[small128]);
total -= request->small128 * 128;
}
if (total < 0) {
sprintf(error_string,
"You asked for %d more nodes than "
"are in a Midplane\n", total * 2);
geoi = -1;
}
#ifndef HAVE_BGL
while (total > 0) {
if (total >= 256) {
request->small256++;
total -= 256;
} else if (total >= 128) {
request->small128++;
total -= 128;
} else if (total >= 64) {
request->small64++;
total -= 64;
} else if (total >= 32) {
request->small32++;
total -= 32;
}
#ifdef HAVE_BGP
else if (total >= 16) {
request->small16++;
total -= 16;
}
#endif
else
break;
}
#else
while (total > 0) {
if (total >= 128) {
request->small128++;
total -= 128;
} else if (total >= 32) {
request->small32++;
total -= 32;
} else
break;
}
#endif
request->size = 1;
/* sprintf(error_string, */
/* "got %d %d %d %d %d %d", */
/* total, request->small16, request->small32, */
/* request->small64, request->small128, */
/* request->small256); */
}
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))) {
char *p;
/* for size */
request->size = strtol(&com[geoi], &p, 10);
if (*p == 'k' || *p == 'K') {
request->size *= 2; /* (1024 / 512) */
p++;
}
break;
}
if (com[i2]=='x') {
request->size = -1;
diff = i2 - geoi;
/* for geometery */
request->geometry[0] = _xlate_coord(&com[geoi],
diff);
for (j = 1; j < params.cluster_dims; j++) {
geoi += diff;
diff = geoi;
while ((com[geoi-1]!='x') && com[geoi])
geoi++;
if (com[geoi] == '\0')
goto geo_error_message;
diff = geoi - diff;
request->geometry[j] =
_xlate_coord(&com[geoi], diff);
}
break;
}
i2++;
}
if (request->start_req) {
i2 = starti;
while (com[i2]!='x' && i2<len)
i2++;
diff = i2-starti;
request->start[0] = _xlate_coord(&com[starti], diff);
for (j = 1; j < params.cluster_dims; j++) {
starti += diff;
if (starti == len)
goto start_request;
starti++;
i2 = starti;
if (j == (params.cluster_dims - 1))
fini_char = ' ';
else
fini_char = 'x';
while ((com[i2] != fini_char) && com[i2])
i2++;
diff = i2 - starti;
request->start[j] = _xlate_coord(&com[starti],
diff);
}
}
start_request:
if(!_full_request(request, NULL, allocated_blocks))
destroy_select_ba_request(request);
}
return 1;
geo_error_message:
destroy_select_ba_request(request);
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;
char *ret_str;
while (com[i] != '\0') {
if ((i>0) && (com[i-1] != ' '))
break;
i++;
}
if (com[i] == 'r')
com[i] = 'R';
ret_str = resolve_mp(com+i, NULL);
if (ret_str) {
snprintf(error_string, sizeof(error_string), "%s", ret_str);
xfree(ret_str);
}
if (params.commandline)
printf("%s", error_string);
else {
wnoutrefresh(text_win);
doupdate();
}
return 1;
}
static int _change_state_all_bps(char *com, int state)
{
char start_loc[32], end_loc[32];
char allnodes[50];
int i;
xassert(params.cluster_dims < 31);
for (i = 0; i < params.cluster_dims; i++) {
start_loc[i] = '0';
end_loc[i] = alpha_num[dim_size[i] - 1];
}
start_loc[i] = '\0';
end_loc[i] = '\0';
memset(allnodes, 0, 50);
sprintf(allnodes, "%sx%s", start_loc, end_loc);
return _change_state_bps(allnodes, state);
}
static int _change_state_bps(char *com, int state)
{
char *host;
int i = 0;
uint16_t pos[params.cluster_dims];
char letter = '.';
bool used = false;
char *c_state = "up";
hostlist_t hl = NULL;
int rc = 1;
if (state == NODE_STATE_DOWN) {
letter = '#';
used = true;
c_state = "down";
}
while (com[i] && (com[i] != '[') &&
((com[i] < '0') || (com[i] > '9')) &&
((com[i] < 'A') || (com[i] > 'Z')))
i++;
if (com[i] == '\0') {
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;
}
if (!(hl = hostlist_create(com+i))) {
memset(error_string, 0, 255);
sprintf(error_string, "Bad hostlist given '%s'", com+i);
return 0;
}
while ((host = hostlist_shift(hl))) {
ba_mp_t *ba_mp;
smap_node_t *smap_node;
for (i = 0; i < params.cluster_dims; i++)
pos[i] = select_char2coord(host[i]);
if (!(ba_mp = bg_configure_coord2ba_mp(pos))) {
memset(error_string, 0, 255);
sprintf(error_string, "Bad host given '%s'", host);
rc = 0;
break;
}
bg_configure_ba_update_mp_state(ba_mp, state);
smap_node = smap_system_ptr->grid[ba_mp->index];
smap_node->color = 0;
smap_node->letter = letter;
smap_node->used = used;
free(host);
}
hostlist_destroy(hl);
return rc;
}
static int _remove_allocation(char *com, List allocated_blocks)
{
ListIterator results_i;
allocated_block_t *allocated_block = NULL;
int i=1, found=0;
int len = strlen(com);
char letter;
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) {
allocated_block->letter =
letters[color_count%62];
allocated_block->color =
colors[color_count%6];
allocated_block->color_count = color_count++;
_set_nodes(allocated_block->nodes,
allocated_block->color,
allocated_block->letter);
} else if (allocated_block->letter == letter) {
found = 1;
color_count = allocated_block->color_count;
list_delete_item(results_i);
}
}
list_iterator_destroy(results_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;
select_ba_request_t *request = NULL;
int i = 1, j;
int len = strlen(com);
char letter = '\0';
int count = 1;
int *geo = NULL, *geo_ptr = NULL;
/* look for the space after copy */
while ((com[i-1] != ' ') && (i < len))
i++;
if (i <= len) {
/* Here we are looking for a real number for the count
* instead of the params.cluster_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 = (select_ba_request_t*)
xmalloc(sizeof(select_ba_request_t));
for (j = 0; j < params.cluster_dims; j++) {
request->geometry[j] = allocated_block->request->
geometry[j];
request->conn_type[j] = allocated_block->request->
conn_type[j];
}
request->size = allocated_block->request->size;
request->rotate =allocated_block->request->rotate;
request->elongate = allocated_block->request->elongate;
request->deny_pass = allocated_block->request->deny_pass;
#ifndef HAVE_BGL
request->small16 = allocated_block->request->small16;
request->small64 = allocated_block->request->small64;
request->small256 = allocated_block->request->small256;
#endif
request->small32 = allocated_block->request->small32;
request->small128 = allocated_block->request->small128;
request->rotate_count= 0;
request->elongate_count = 0;
request->elongate_geos = list_create(NULL);
request->avail_mp_bitmap = NULL;
results_i = list_iterator_create(request->elongate_geos);
while ((geo_ptr = list_next(results_i)) != NULL) {
geo = xmalloc(sizeof(int) * params.cluster_dims);
for (j = 0; j < params.cluster_dims; j++)
geo[j] = geo_ptr[j];
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[50];
char *save_string = NULL;
FILE *file_ptr = NULL;
char *extra = NULL;
ListIterator results_i;
memset(filename, 0, 50);
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) {
char *image_dir = NULL;
xstrcat(save_string,
"#\n# bluegene.conf file generated by smap\n");
xstrcat(save_string,
"# See the bluegene.conf man page for "
"more information\n");
xstrcat(save_string, "#\n");
#ifdef HAVE_BGL
image_dir = "/bgl/BlueLight/ppcfloor/bglsys/bin";
xstrfmtcat(save_string, "BlrtsImage=%s/rts_hw.rts\n",
image_dir);
xstrfmtcat(save_string, "LinuxImage=%s/zImage.elf\n",
image_dir);
xstrfmtcat(save_string,
"MloaderImage=%s/mmcs-mloader.rts\n",
image_dir);
xstrfmtcat(save_string,
"RamDiskImage=%s/ramdisk.elf\n",
image_dir);
xstrcat(save_string, "IONodesPerMP=8 # io poor\n");
xstrcat(save_string, "# IONodesPerMP=64 # io rich\n");
#elif defined HAVE_BGP
image_dir = "/bgsys/drivers/ppcfloor/boot";
xstrfmtcat(save_string, "CnloadImage=%s/cns,%s/cnk\n",
image_dir, image_dir);
xstrfmtcat(save_string, "MloaderImage=%s/uloader\n",
image_dir);
xstrfmtcat(save_string,
"IoloadImage=%s/cns,%s/linux,%s/ramdisk\n",
image_dir, image_dir, image_dir);
xstrcat(save_string, "IONodesPerMP=4 # io poor\n");
xstrcat(save_string, "# IONodesPerMP=32 # io rich\n");
#else
image_dir = "/bgsys/drivers/ppcfloor/boot";
xstrfmtcat(save_string, "MloaderImage=%s/firmware\n",
image_dir);
xstrcat(save_string, "IONodesPerMP=4 # io semi-poor\n");
xstrcat(save_string, "# IONodesPerMP=16 # io rich\n");
#endif
xstrcat(save_string, "BridgeAPILogFile="
"/var/log/slurm/bridgeapi.log\n");
xstrcat(save_string, "BridgeAPIVerbose=2\n");
xstrfmtcat(save_string, "BasePartitionNodeCnt=%d\n",
base_part_node_cnt);
xstrfmtcat(save_string, "NodeCardNodeCnt=%d\n",
nodecard_node_cnt);
if (!list_count(allocated_blocks))
xstrcat(save_string, "LayoutMode=DYNAMIC\n");
else {
xstrfmtcat(save_string, "LayoutMode=%s\n", layout_mode);
xstrfmtcat(save_string, "#\n# Block Layout\n#\n");
}
results_i = list_iterator_create(allocated_blocks);
while ((allocated_block = list_next(results_i)) != NULL) {
select_ba_request_t *request = allocated_block->request;
if (request->small16 || request->small32
|| request->small64 || request->small128
|| request->small256) {
#ifdef HAVE_BGL
xstrfmtcat(extra,
" 32CNBlocks=%d "
"128CNBlocks=%d",
request->small32,
request->small128);
#elif defined HAVE_BGP
xstrfmtcat(extra,
" 16CNBlocks=%d "
"32CNBlocks=%d "
"64CNBlocks=%d "
"128CNBlocks=%d "
"256CNBlocks=%d",
request->small16,
request->small32,
request->small64,
request->small128,
request->small256);
#else
xstrfmtcat(extra,
" 32CNBlocks=%d "
"64CNBlocks=%d "
"128CNBlocks=%d "
"256CNBlocks=%d",
request->small32,
request->small64,
request->small128,
request->small256);
#endif
}
xstrfmtcat(save_string, "MPs=%s", request->save_name);
for (i=0; i<SYSTEM_DIMENSIONS; i++) {
if (request->conn_type[i] == (uint16_t)NO_VAL)
break;
if (i)
xstrcat(save_string, ",");
else
xstrcat(save_string, " Type=");
xstrfmtcat(save_string, "%s", conn_type_string(
request->conn_type[i]));
#ifdef HAVE_BG_L_P
break;
#endif
}
if (extra) {
xstrfmtcat(save_string, "%s\n", extra);
xfree(extra);
} else
xstrcat(save_string, "\n");
}
list_iterator_destroy(results_i);
fputs(save_string, file_ptr);
xfree(save_string);
fclose (file_ptr);
}
return 1;
}
static int _add_bg_record(select_ba_request_t *blockreq, List allocated_blocks)
{
int rc = 1;
#ifdef HAVE_BG
char *nodes = NULL, *host;
int diff = 0;
int largest_diff = -1;
uint16_t start[params.cluster_dims];
uint16_t end[params.cluster_dims];
uint16_t best_start[params.cluster_dims];
int i, j = 0;
hostlist_t hl = NULL;
bitstr_t *mark_bitmap = NULL;
char tmp_char[params.cluster_dims+1],
tmp_char2[params.cluster_dims+1];
memset(tmp_char, 0, sizeof(tmp_char));
memset(tmp_char2, 0, sizeof(tmp_char2));
for (i = 0; i < params.cluster_dims; i++) {
best_start[0] = 0;
blockreq->geometry[i] = 0;
end[i] = (int16_t)-1;
}
nodes = blockreq->save_name;
if (!nodes)
return SLURM_SUCCESS;
while (nodes[j] && (nodes[j] != '[') &&
((nodes[j] < '0') || (nodes[j] > '9')) &&
((nodes[j] < 'A') || (nodes[j] > 'Z')))
j++;
if (nodes[j] == '\0') {
snprintf(error_string, sizeof(error_string),
"This block '%s' for some reason didn't contain "
"any midplanes.",
nodes);
rc = 0;
goto fini;
}
if (!(hl = hostlist_create(nodes+j))) {
snprintf(error_string, sizeof(error_string),
"Bad hostlist given '%s'", nodes+j);
rc = 0;
goto fini;
}
/* figure out the geo and the size */
mark_bitmap = bit_alloc(smap_system_ptr->node_cnt);
while ((host = hostlist_shift(hl))) {
ba_mp_t *ba_mp;
uint16_t pos[params.cluster_dims];
for (i = 0; i < params.cluster_dims; i++)
pos[i] = select_char2coord(host[i]);
free(host);
if (!(ba_mp = bg_configure_coord2ba_mp(pos))) {
memset(error_string, 0, 255);
sprintf(error_string, "Bad host given '%s'", host);
rc = 0;
break;
}
bit_set(mark_bitmap, ba_mp->index);
for (i = 0; i < params.cluster_dims; i++) {
if (ba_mp->coord[i] > (int16_t)end[i]) {
blockreq->geometry[i]++;
end[i] = ba_mp->coord[i];
}
}
}
hostlist_destroy(hl);
if (!rc)
goto fini;
/* figure out the start pos */
while (nodes[j] != '\0') {
int mid = j + params.cluster_dims + 1;
int fin = mid + params.cluster_dims + 1;
if (((nodes[j] == '[') || (nodes[j] == ',')) &&
((nodes[mid] == 'x') || (nodes[mid] == '-')) &&
((nodes[fin] == ']') || (nodes[fin] == ','))) {
j++; /* Skip leading '[' or ',' */
for (i = 0; i < params.cluster_dims; i++, j++)
start[i] = select_char2coord(nodes[j]);
j++; /* Skip middle 'x' or '-' */
for (i = 0; i < params.cluster_dims; i++, j++)
end[i] = select_char2coord(nodes[j]);
diff = end[0] - start[0];
} else if (((nodes[j] >= '0') && (nodes[j] <= '9')) ||
((nodes[j] >= 'A') && (nodes[j] <= 'Z'))) {
for (i = 0; i < params.cluster_dims; i++, j++)
start[i] = select_char2coord(nodes[j]);
diff = 0;
} else {
j++;
continue;
}
if (diff > largest_diff) {
largest_diff = diff;
memcpy(best_start, start, sizeof(best_start));
}
if (nodes[j] != ',')
break;
}
if (largest_diff == -1) {
snprintf(error_string, sizeof(error_string),
"No hostnames given here");
goto fini;
}
memcpy(blockreq->start, best_start, sizeof(blockreq->start));
if(!_full_request(blockreq, mark_bitmap, allocated_blocks))
destroy_select_ba_request(blockreq);
fini:
FREE_NULL_BITMAP(mark_bitmap);
#endif
return rc;
}
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;
select_ba_request_t **blockreq_array = NULL;
int count = 0;
if (allocated_blocks)
list_flush(allocated_blocks);
else
allocated_blocks = list_create(_destroy_allocated_block);
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");
}
if (!(tbl = bg_configure_config_make_tbl(filename))) {
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, "MPs", tbl)) {
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);
/* The freeing of this will happen when
allocated_blocks gets freed.
*/
blockreq_array[i] = NULL;
}
}
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 += 8;
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, "MIDPLANES");
#else
mvwprintw(text_win, main_ycord,
main_xcord, "NODES");
#endif
main_xcord += 10;
#ifdef HAVE_BGP
mvwprintw(text_win, main_ycord,
main_xcord, "16CN");
main_xcord += 5;
#endif
mvwprintw(text_win, main_ycord,
main_xcord, "32CN");
main_xcord += 5;
#ifndef HAVE_BGL
mvwprintw(text_win, main_ycord,
main_xcord, "64CN");
main_xcord += 5;
#endif
mvwprintw(text_win, main_ycord,
main_xcord, "128CN");
main_xcord += 6;
#ifndef HAVE_BGL
mvwprintw(text_win, main_ycord,
main_xcord, "256CN");
main_xcord += 6;
#endif
#ifdef HAVE_BG
mvwprintw(text_win, main_ycord,
main_xcord, "MIDPLANELIST");
#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)
{
char *tmp_char = NULL;
wattron(text_win,
COLOR_PAIR(allocated_block->color));
mvwprintw(text_win, main_ycord,
main_xcord, "%c", allocated_block->letter);
main_xcord += 4;
tmp_char = conn_type_string_full(allocated_block->request->conn_type);
mvwprintw(text_win, main_ycord, main_xcord, tmp_char);
xfree(tmp_char);
main_xcord += 8;
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[0] >= SELECT_SMALL) {
#ifdef HAVE_BGP
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->small16);
main_xcord += 5;
#endif
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->small32);
main_xcord += 5;
#ifndef HAVE_BGL
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->small64);
main_xcord += 5;
#endif
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->small128);
main_xcord += 6;
#ifndef HAVE_BGL
mvwprintw(text_win, main_ycord,
main_xcord, "%d",
allocated_block->request->small256);
main_xcord += 6;
#endif
} else {
#ifdef HAVE_BGL
main_xcord += 11;
#elif defined HAVE_BGP
main_xcord += 27;
#else
main_xcord += 22;
#endif
}
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 = NULL;
List allocated_blocks = NULL;
ListIterator results_i;
if (params.commandline && !params.command) {
printf("Configure won't work with commandline mode.\n");
printf("Please remove the -c from the commandline.\n");
bg_configure_ba_fini();
exit(0);
}
if (working_cluster_rec) {
char *cluster_name = slurm_get_cluster_name();
if (strcmp(working_cluster_rec->name, cluster_name)) {
xfree(cluster_name);
endwin();
printf("To use the configure option you must be on the "
"cluster the configure is for.\nCross cluster "
"support doesn't exist today.\nSorry for the "
"inconvenince.\n");
bg_configure_ba_fini();
exit(0);
}
xfree(cluster_name);
}
/* make sure we don't get any noisy debug */
ba_configure_set_ba_debug_flags(0);
bg_configure_ba_setup_wires();
color_count = 0;
allocated_blocks = list_create(_destroy_allocated_block);
if (params.commandline) {
snprintf(com, sizeof(com), "%s", params.command);
goto run_command;
} else {
text_width = text_win->_maxx;
text_startx = text_win->_begx;
command_win = newwin(3, text_width - 1, LINES - 4,
text_startx + 1);
curs_set(1);
echo();
}
while (strcmp(com, "quit")) {
clear_window(grid_win);
print_grid();
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();
if (allocated_blocks)
list_destroy(allocated_blocks);
bg_configure_ba_fini();
exit(0);
}
run_command:
if (!strcmp(com, "quit") || !strcmp(com, "\\q")) {
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, "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)) {
list_flush(allocated_blocks);
} else {
memset(error_string, 0, 255);
sprintf(error_string, "Unknown command '%s'",com);
}
if (params.commandline) {
bg_configure_ba_fini();
exit(1);
}
}
if (allocated_blocks)
list_destroy(allocated_blocks);
params.display = 0;
noecho();
clear_window(text_win);
main_xcord = 1;
main_ycord = 1;
curs_set(0);
print_date();
get_job();
return;
}