PageRenderTime 888ms CodeModel.GetById 163ms app.highlight 510ms RepoModel.GetById 84ms app.codeStats 1ms

/src/smap/configure_functions.c

https://github.com/cfenoy/slurm
C | 1556 lines | 1336 code | 158 blank | 62 comment | 373 complexity | 02d5763237d1b065d538d6cb6f6b7541 MD5 | raw file
   1/*****************************************************************************\
   2 *  configure_functions.c - Functions related to configure mode of smap.
   3 *****************************************************************************
   4 *  Copyright (C) 2002-2007 The Regents of the University of California.
   5 *  Copyright (C) 2008-2011 Lawrence Livermore National Security.
   6 *  Copyright (C) 2011 SchedMD LLC.
   7 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
   8 *  Written by Danny Auble <da@schedmd.com>
   9 *
  10 *  CODE-OCEC-09-009. All rights reserved.
  11 *
  12 *  This file is part of SLURM, a resource management program.
  13 *  For details, see <http://www.schedmd.com/slurmdocs/>.
  14 *  Please also read the included file: DISCLAIMER.
  15 *
  16 *  SLURM is free software; you can redistribute it and/or modify it under
  17 *  the terms of the GNU General Public License as published by the Free
  18 *  Software Foundation; either version 2 of the License, or (at your option)
  19 *  any later version.
  20 *
  21 *  In addition, as a special exception, the copyright holders give permission
  22 *  to link the code of portions of this program with the OpenSSL library under
  23 *  certain conditions as described in each individual source file, and
  24 *  distribute linked combinations including the two. You must obey the GNU
  25 *  General Public License in all respects for all of the code used other than
  26 *  OpenSSL. If you modify file(s) with this exception, you may extend this
  27 *  exception to your version of the file(s), but you are not obligated to do
  28 *  so. If you do not wish to do so, delete this exception statement from your
  29 *  version.  If you delete this exception statement from all source files in
  30 *  the program, then also delete it here.
  31 *
  32 *  SLURM is distributed in the hope that it will be useful, but WITHOUT ANY
  33 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  34 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
  35 *  details.
  36 *
  37 *  You should have received a copy of the GNU General Public License along
  38 *  with SLURM; if not, write to the Free Software Foundation, Inc.,
  39 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
  40\*****************************************************************************/
  41
  42#include "src/smap/smap.h"
  43#include "src/common/uid.h"
  44#include "src/common/xstring.h"
  45#include "src/common/proc_args.h"
  46
  47///////////////////////////////////////////////////////////////////////
  48
  49typedef struct {
  50	int color;
  51	int color_count;
  52	char letter;
  53	List nodes;
  54	select_ba_request_t *request;
  55} allocated_block_t;
  56
  57static int	_add_bg_record(select_ba_request_t *blockreq,
  58			       List allocated_blocks);
  59static int	_change_state_all_bps(char *com, int state);
  60static int	_change_state_bps(char *com, int state);
  61static int	_copy_allocation(char *com, List allocated_blocks);
  62static int	_create_allocation(char *com, List allocated_blocks);
  63static int	_load_configuration(char *com, List allocated_blocks);
  64static allocated_block_t *_make_request(select_ba_request_t *request);
  65static void	_print_header_command(void);
  66static void	_print_text_command(allocated_block_t *allocated_block);
  67static int	_remove_allocation(char *com, List allocated_blocks);
  68static int	_resolve(char *com);
  69static int	_save_allocation(char *com, List allocated_blocks);
  70static int      _set_layout(char *com);
  71static int      _set_base_part_cnt(char *com);
  72static int      _set_nodecard_cnt(char *com);
  73
  74int color_count = 0;
  75char error_string[255];
  76int base_part_node_cnt = 512;
  77int nodecard_node_cnt = 32;
  78char *layout_mode = "STATIC";
  79
  80static void _set_nodes(List nodes, int color, char letter)
  81{
  82	ListIterator itr;
  83	smap_node_t *smap_node;
  84	ba_mp_t *ba_mp;
  85
  86	if (!nodes || !smap_system_ptr)
  87		return;
  88
  89	itr = list_iterator_create(nodes);
  90	while ((ba_mp = list_next(itr))) {
  91		if (!ba_mp->used)
  92			continue;
  93		smap_node = smap_system_ptr->grid[ba_mp->index];
  94		smap_node->color = color;
  95		smap_node->letter = letter;
  96	}
  97	list_iterator_destroy(itr);
  98	return;
  99}
 100
 101static void _destroy_allocated_block(void *object)
 102{
 103	allocated_block_t *allocated_block = (allocated_block_t *)object;
 104
 105	if (allocated_block) {
 106		bool is_small = (allocated_block->request->conn_type[0] >=
 107				 SELECT_SMALL);
 108		if (allocated_block->nodes) {
 109			_set_nodes(allocated_block->nodes, 0, '.');
 110			bg_configure_remove_block(
 111				allocated_block->nodes, is_small);
 112			list_destroy(allocated_block->nodes);
 113		}
 114		destroy_select_ba_request(allocated_block->request);
 115		xfree(allocated_block);
 116	}
 117}
 118
 119static allocated_block_t *_make_request(select_ba_request_t *request)
 120{
 121	List results = list_create(NULL);
 122	allocated_block_t *allocated_block = NULL;
 123
 124#ifdef HAVE_BGQ
 125	results = list_create(bg_configure_destroy_ba_mp);
 126#else
 127	results = list_create(NULL);
 128#endif
 129
 130	if (bg_configure_allocate_block(request, results)) {
 131		char *pass = bg_configure_ba_passthroughs_string(
 132			request->deny_pass);
 133		if (pass) {
 134			sprintf(error_string,"THERE ARE PASSTHROUGHS IN "
 135				"THIS ALLOCATION DIM %s!!!!!!!", pass);
 136			xfree(pass);
 137		}
 138
 139		allocated_block = xmalloc(sizeof(allocated_block_t));
 140		allocated_block->request = request;
 141		allocated_block->nodes = results;
 142		allocated_block->letter = letters[color_count%62];
 143		allocated_block->color  = colors[color_count%6];
 144		allocated_block->color_count = color_count++;
 145		_set_nodes(allocated_block->nodes,
 146			   allocated_block->color,
 147			   allocated_block->letter);
 148		results = NULL;
 149	}
 150
 151	if (results)
 152		list_destroy(results);
 153	return allocated_block;
 154
 155}
 156
 157static int _full_request(select_ba_request_t *request,
 158			 bitstr_t *usable_mp_bitmap,
 159			 List allocated_blocks)
 160{
 161	char *tmp_char = NULL, *tmp_char2 = NULL;
 162	allocated_block_t *allocated_block;
 163	int rc = 1;
 164
 165	if (!strcasecmp(layout_mode,"OVERLAP"))
 166		bg_configure_reset_ba_system(true);
 167
 168	if (usable_mp_bitmap)
 169		bg_configure_ba_set_removable_mps(usable_mp_bitmap, 1);
 170
 171	/*
 172	 * Here is where we do the allocating of the partition.
 173	 * It will send a request back which we will throw into
 174	 * a list just incase we change something later.
 175	 */
 176	if (!bg_configure_new_ba_request(request)) {
 177		memset(error_string, 0, 255);
 178		if (request->size != -1) {
 179			sprintf(error_string,
 180				"Problems with request for %d\n"
 181				"Either you put in something "
 182				"that doesn't work,\n"
 183				"or we are unable to process "
 184				"your request.",
 185				request->size);
 186			rc = 0;
 187		} else {
 188			tmp_char = bg_configure_give_geo(request->geometry,
 189							 params.cluster_dims,
 190							 1);
 191			sprintf(error_string,
 192				"Problems with request of size %s\n"
 193				"Either you put in something "
 194				"that doesn't work,\n"
 195				"or we are unable to process "
 196				"your request.",
 197				tmp_char);
 198			xfree(tmp_char);
 199			rc = 0;
 200		}
 201	} else {
 202		if ((allocated_block = _make_request(request)) != NULL)
 203			list_append(allocated_blocks, allocated_block);
 204		else {
 205			if (request->geometry[0] != (uint16_t)NO_VAL)
 206				tmp_char = bg_configure_give_geo(
 207					request->geometry,
 208					params.cluster_dims, 1);
 209			tmp_char2 = bg_configure_give_geo(request->start,
 210							  params.cluster_dims,
 211							  1);
 212
 213			memset(error_string, 0, 255);
 214			sprintf(error_string,
 215				"allocate failure\nSize requested "
 216				"was %d MidPlanes\n",
 217				request->size);
 218			if (tmp_char) {
 219				sprintf(error_string + strlen(error_string),
 220					"Geo requested was %s\n", tmp_char);
 221				xfree(tmp_char);
 222			} else {
 223				sprintf(error_string + strlen(error_string),
 224					"No geometry could be laid out "
 225					"for that size\n");
 226			}
 227			sprintf(error_string + strlen(error_string),
 228				"Start position was %s", tmp_char2);
 229			xfree(tmp_char2);
 230			rc = 0;
 231		}
 232	}
 233
 234	if (usable_mp_bitmap)
 235		bg_configure_ba_reset_all_removed_mps();
 236
 237	return rc;
 238}
 239
 240static int _set_layout(char *com)
 241{
 242	int i;
 243
 244	for (i = 0; com[i]; i++) {
 245		if (!strncasecmp(com+i, "dynamic", 7)) {
 246			layout_mode = "DYNAMIC";
 247			break;
 248		} else if (!strncasecmp(com+i, "static", 6)) {
 249			layout_mode = "STATIC";
 250			break;
 251		} else if (!strncasecmp(com+i, "overlap", 7)) {
 252			layout_mode = "OVERLAP";
 253			break;
 254		}
 255	}
 256	if (com[i] == '\0') {
 257		sprintf(error_string,
 258			"You didn't put in a mode that I recognized. \n"
 259			"Please use STATIC, OVERLAP, or DYNAMIC\n");
 260		return 0;
 261	}
 262	sprintf(error_string,
 263		"LayoutMode set to %s\n", layout_mode);
 264	return 1;
 265}
 266
 267static int _set_base_part_cnt(char *com)
 268{
 269	int i;
 270
 271	for (i = 0; com[i]; i++) {
 272		if ((com[i] >= '0') && (com[i] <= '9'))
 273			break;
 274	}
 275	if (com[i] == '\0') {
 276		sprintf(error_string,
 277			"I didn't notice the number you typed in\n");
 278		return 0;
 279	}
 280
 281	base_part_node_cnt = atoi(&com[i]);
 282	memset(error_string, 0, 255);
 283	sprintf(error_string,
 284		"BasePartitionNodeCnt set to %d\n", base_part_node_cnt);
 285
 286	return 1;
 287}
 288
 289static int _set_nodecard_cnt(char *com)
 290{
 291	int i;
 292
 293	for (i = 0; com[i]; i++) {
 294		if ((com[i] >= '0') && (com[i] <= '9'))
 295			break;
 296	}
 297	if (com[i] == '\0') {
 298		sprintf(error_string,
 299			"I didn't notice the number you typed in\n");
 300		return 0;
 301	}
 302
 303	nodecard_node_cnt = atoi(&com[i]);
 304	memset(error_string, 0, 255);
 305	sprintf(error_string,
 306		"NodeCardNodeCnt set to %d\n", nodecard_node_cnt);
 307
 308	return 1;
 309}
 310
 311static int _xlate_coord(char *str, int len)
 312{
 313	if (len > 1)
 314		return xstrntol(str, NULL, len, 10);
 315	else
 316		return xstrntol(str, NULL, len, params.cluster_base);
 317}
 318
 319static int _create_allocation(char *com, List allocated_blocks)
 320{
 321	int i=6, j, geoi=-1, starti=-1, i2=0, small32=-1, small128=-1;
 322	int len = strlen(com);
 323	select_ba_request_t *request;
 324	char fini_char;
 325	int diff=0;
 326#ifndef HAVE_BGL
 327#ifdef HAVE_BGP
 328	int small16=-1;
 329#endif
 330	int small64=-1, small256=-1;
 331#endif
 332	request = (select_ba_request_t*) xmalloc(sizeof(select_ba_request_t));
 333	request->rotate = false;
 334	request->elongate = false;
 335	request->start_req = 0;
 336	request->size = 0;
 337	request->small32 = 0;
 338	request->small128 = 0;
 339	request->deny_pass = 0;
 340	request->avail_mp_bitmap = NULL;
 341	for (j = 0; j < params.cluster_dims; j++) {
 342		request->geometry[j]  = (uint16_t) NO_VAL;
 343		request->conn_type[j] = SELECT_TORUS;
 344	}
 345
 346	while (i < len) {
 347		if (!strncasecmp(com+i, "mesh", 4)
 348		    || !strncasecmp(com+i, "small", 5)
 349		    || !strncasecmp(com+i, "torus", 5)) {
 350			char conn_type[200];
 351			j = i;
 352			while (j < len) {
 353				if (com[j] == ' ')
 354					break;
 355				conn_type[j-i] = com[j];
 356				j++;
 357				if (j >= 200)
 358					break;
 359			}
 360			conn_type[(j-i)+1] = '\0';
 361			verify_conn_type(conn_type, request->conn_type);
 362			i += j;
 363		} else if (!strncasecmp(com+i, "deny", 4)) {
 364			i += 4;
 365			if (strstr(com+i, "A"))
 366				request->deny_pass |= PASS_DENY_A;
 367			if (strstr(com+i, "X"))
 368				request->deny_pass |= PASS_DENY_X;
 369			if (strstr(com+i, "Y"))
 370				request->deny_pass |= PASS_DENY_Y;
 371			if (strstr(com+i, "Z"))
 372				request->deny_pass |= PASS_DENY_Z;
 373			if (!strcasecmp(com+i, "ALL"))
 374				request->deny_pass |= PASS_DENY_ALL;
 375		} else if (!strncasecmp(com+i, "nodecard", 8)) {
 376			small32 = 0;
 377			i += 8;
 378		} else if (!strncasecmp(com+i, "quarter", 7)) {
 379			small128 = 0;
 380			i += 7;
 381		} else if (!strncasecmp(com+i, "32CN", 4)) {
 382			small32 = 0;
 383			i += 4;
 384		} else if (!strncasecmp(com+i, "128CN", 5)) {
 385			small128 = 0;
 386			i += 5;
 387		} else if (!strncasecmp(com+i, "rotate", 6)) {
 388			request->rotate = true;
 389			i += 6;
 390		} else if (!strncasecmp(com+i, "elongate", 8)) {
 391			request->elongate = true;
 392			i += 8;
 393		} else if (!strncasecmp(com+i, "start", 5)) {
 394			request->start_req = 1;
 395			i += 5;
 396		} else if (request->start_req && (starti < 0) &&
 397			   (((com[i] >= '0') && (com[i] <= '9')) ||
 398			    ((com[i] >= 'A') && (com[i] <= 'Z')))) {
 399			starti = i;
 400			i++;
 401		} else if (small32 == 0 && (com[i] >= '0' && com[i] <= '9')) {
 402			small32 = i;
 403			i++;
 404		} else if (small128 == 0 && (com[i] >= '0' && com[i] <= '9')) {
 405			small128 = i;
 406			i++;
 407		}
 408#ifdef HAVE_BGP
 409		else if (!strncasecmp(com+i, "16CN", 4)) {
 410			small16 = 0;
 411			i += 4;
 412		} else if (small16 == 0 && (com[i] >= '0' && com[i] <= '9')) {
 413			small16 = i;
 414			i++;
 415		}
 416#endif
 417#ifndef HAVE_BGL
 418		else if (!strncasecmp(com+i, "64CN", 4)) {
 419			small64 = 0;
 420			i += 4;
 421		} else if (!strncasecmp(com+i, "256CN", 5)) {
 422			small256 = 0;
 423			i += 5;
 424		} else if (small64 == 0 && (com[i] >= '0' && com[i] <= '9')) {
 425			small64 = i;
 426			i++;
 427		} else if (small256 == 0 && (com[i] >= '0' && com[i] <= '9')) {
 428			small256 = i;
 429			i++;
 430		}
 431#endif
 432		else if ((geoi < 0) &&
 433			 (((com[i] >= '0') && (com[i] <= '9')) ||
 434			  ((com[i] >= 'A') && (com[i] <= 'Z')))) {
 435			geoi = i;
 436			i++;
 437		} else {
 438			i++;
 439		}
 440
 441	}
 442
 443	if (request->conn_type[0] >= SELECT_SMALL) {
 444		int total = 512;
 445#ifdef HAVE_BGP
 446		if (small16 > 0) {
 447			request->small16 = atoi(&com[small16]);
 448			total -= request->small16 * 16;
 449		}
 450#endif
 451#ifndef HAVE_BGL
 452		if (small64 > 0) {
 453			request->small64 = atoi(&com[small64]);
 454			total -= request->small64 * 64;
 455		}
 456
 457		if (small256 > 0) {
 458			request->small256 = atoi(&com[small256]);
 459			total -= request->small256 * 256;
 460		}
 461#endif
 462
 463		if (small32 > 0) {
 464			request->small32 = atoi(&com[small32]);
 465			total -= request->small32 * 32;
 466		}
 467
 468		if (small128 > 0) {
 469			request->small128 = atoi(&com[small128]);
 470			total -= request->small128 * 128;
 471		}
 472		if (total < 0) {
 473			sprintf(error_string,
 474				"You asked for %d more nodes than "
 475				"are in a Midplane\n", total * 2);
 476			geoi = -1;
 477
 478		}
 479
 480#ifndef HAVE_BGL
 481		while (total > 0) {
 482			if (total >= 256) {
 483				request->small256++;
 484				total -= 256;
 485			} else if (total >= 128) {
 486				request->small128++;
 487				total -= 128;
 488			} else if (total >= 64) {
 489				request->small64++;
 490				total -= 64;
 491			} else if (total >= 32) {
 492				request->small32++;
 493				total -= 32;
 494			}
 495#ifdef HAVE_BGP
 496			else if (total >= 16) {
 497				request->small16++;
 498				total -= 16;
 499			}
 500#endif
 501			else
 502				break;
 503		}
 504#else
 505		while (total > 0) {
 506			if (total >= 128) {
 507				request->small128++;
 508				total -= 128;
 509			} else if (total >= 32) {
 510				request->small32++;
 511				total -= 32;
 512			} else
 513				break;
 514		}
 515#endif
 516		request->size = 1;
 517/* 		sprintf(error_string, */
 518/* 			"got %d %d %d %d %d %d", */
 519/* 			total, request->small16, request->small32, */
 520/* 			request->small64, request->small128, */
 521/* 			request->small256); */
 522	}
 523
 524	if ((geoi < 0) && !request->size) {
 525		memset(error_string, 0, 255);
 526		sprintf(error_string,
 527			"No size or dimension specified, please re-enter");
 528	} else {
 529		i2 = geoi;
 530		while (i2 < len) {
 531			if (request->size)
 532				break;
 533			if ((com[i2] == ' ') || (i2 == (len-1))) {
 534				char *p;
 535				/* for size */
 536				request->size = strtol(&com[geoi], &p, 10);
 537				if (*p == 'k' || *p == 'K') {
 538					request->size *= 2; /* (1024 / 512) */
 539					p++;
 540				}
 541				break;
 542			}
 543			if (com[i2]=='x') {
 544				request->size = -1;
 545				diff = i2 - geoi;
 546				/* for geometery */
 547				request->geometry[0] = _xlate_coord(&com[geoi],
 548								    diff);
 549				for (j = 1; j < params.cluster_dims; j++) {
 550					geoi += diff;
 551					diff = geoi;
 552					while ((com[geoi-1]!='x') && com[geoi])
 553						geoi++;
 554					if (com[geoi] == '\0')
 555						goto geo_error_message;
 556					diff = geoi - diff;
 557					request->geometry[j] =
 558						_xlate_coord(&com[geoi], diff);
 559				}
 560				break;
 561			}
 562			i2++;
 563		}
 564
 565		if (request->start_req) {
 566			i2 = starti;
 567			while (com[i2]!='x' && i2<len)
 568				i2++;
 569			diff = i2-starti;
 570			request->start[0] = _xlate_coord(&com[starti], diff);
 571
 572			for (j = 1; j < params.cluster_dims; j++) {
 573				starti += diff;
 574				if (starti == len)
 575					goto start_request;
 576				starti++;
 577				i2 = starti;
 578				if (j == (params.cluster_dims - 1))
 579					fini_char = ' ';
 580				else
 581					fini_char = 'x';
 582				while ((com[i2] != fini_char) && com[i2])
 583					i2++;
 584				diff = i2 - starti;
 585				request->start[j] = _xlate_coord(&com[starti],
 586								 diff);
 587			}
 588		}
 589	start_request:
 590		if(!_full_request(request, NULL, allocated_blocks))
 591			destroy_select_ba_request(request);
 592
 593	}
 594	return 1;
 595
 596geo_error_message:
 597	destroy_select_ba_request(request);
 598	memset(error_string, 0, 255);
 599	sprintf(error_string,
 600		"Error in geo dimension specified, please re-enter");
 601
 602	return 0;
 603}
 604
 605static int _resolve(char *com)
 606{
 607	int i=0;
 608	char *ret_str;
 609
 610	while (com[i] != '\0') {
 611		if ((i>0) && (com[i-1] != ' '))
 612			break;
 613		i++;
 614	}
 615	if (com[i] == 'r')
 616		com[i] = 'R';
 617	ret_str = resolve_mp(com+i, NULL);
 618	if (ret_str) {
 619		snprintf(error_string, sizeof(error_string), "%s", ret_str);
 620		xfree(ret_str);
 621	}
 622
 623	if (params.commandline)
 624		printf("%s", error_string);
 625	else {
 626		wnoutrefresh(text_win);
 627		doupdate();
 628	}
 629
 630	return 1;
 631}
 632
 633static int _change_state_all_bps(char *com, int state)
 634{
 635	char start_loc[32], end_loc[32];
 636	char allnodes[50];
 637	int i;
 638
 639	xassert(params.cluster_dims < 31);
 640	for (i = 0; i < params.cluster_dims; i++) {
 641		start_loc[i] = '0';
 642		end_loc[i]   = alpha_num[dim_size[i] - 1];
 643	}
 644	start_loc[i] = '\0';
 645	end_loc[i]   = '\0';
 646
 647	memset(allnodes, 0, 50);
 648	sprintf(allnodes, "%sx%s", start_loc, end_loc);
 649
 650	return _change_state_bps(allnodes, state);
 651
 652}
 653static int _change_state_bps(char *com, int state)
 654{
 655	char *host;
 656	int i = 0;
 657	uint16_t pos[params.cluster_dims];
 658	char letter = '.';
 659	bool used = false;
 660	char *c_state = "up";
 661	hostlist_t hl = NULL;
 662	int rc = 1;
 663
 664	if (state == NODE_STATE_DOWN) {
 665		letter = '#';
 666		used = true;
 667		c_state = "down";
 668	}
 669
 670	while (com[i] && (com[i] != '[') &&
 671	       ((com[i] < '0') || (com[i] > '9')) &&
 672	       ((com[i] < 'A') || (com[i] > 'Z')))
 673		i++;
 674	if (com[i] == '\0') {
 675		memset(error_string, 0, 255);
 676		sprintf(error_string,
 677			"You didn't specify any nodes to make %s. "
 678			"in statement '%s'",
 679			c_state, com);
 680		return 0;
 681	}
 682
 683	if (!(hl = hostlist_create(com+i))) {
 684		memset(error_string, 0, 255);
 685		sprintf(error_string, "Bad hostlist given '%s'", com+i);
 686		return 0;
 687
 688	}
 689
 690	while ((host = hostlist_shift(hl))) {
 691		ba_mp_t *ba_mp;
 692		smap_node_t *smap_node;
 693
 694		for (i = 0; i < params.cluster_dims; i++)
 695			pos[i] = select_char2coord(host[i]);
 696		if (!(ba_mp = bg_configure_coord2ba_mp(pos))) {
 697			memset(error_string, 0, 255);
 698			sprintf(error_string, "Bad host given '%s'", host);
 699			rc = 0;
 700			break;
 701		}
 702		bg_configure_ba_update_mp_state(ba_mp, state);
 703		smap_node = smap_system_ptr->grid[ba_mp->index];
 704		smap_node->color = 0;
 705		smap_node->letter = letter;
 706		smap_node->used = used;
 707		free(host);
 708	}
 709	hostlist_destroy(hl);
 710
 711	return rc;
 712}
 713
 714static int _remove_allocation(char *com, List allocated_blocks)
 715{
 716	ListIterator results_i;
 717	allocated_block_t *allocated_block = NULL;
 718	int i=1, found=0;
 719	int len = strlen(com);
 720	char letter;
 721
 722	while (com[i-1]!=' ' && i<len) {
 723		i++;
 724	}
 725
 726	if (i>(len-1)) {
 727		memset(error_string, 0, 255);
 728		sprintf(error_string,
 729			"You need to specify which letter to delete.");
 730		return 0;
 731	} else {
 732		letter = com[i];
 733		results_i = list_iterator_create(allocated_blocks);
 734		while ((allocated_block = list_next(results_i)) != NULL) {
 735			if (found) {
 736				allocated_block->letter =
 737					letters[color_count%62];
 738				allocated_block->color =
 739					colors[color_count%6];
 740				allocated_block->color_count = color_count++;
 741				_set_nodes(allocated_block->nodes,
 742					   allocated_block->color,
 743					   allocated_block->letter);
 744			} else if (allocated_block->letter == letter) {
 745				found = 1;
 746				color_count = allocated_block->color_count;
 747				list_delete_item(results_i);
 748			}
 749		}
 750		list_iterator_destroy(results_i);
 751	}
 752
 753	return 1;
 754}
 755
 756static int _copy_allocation(char *com, List allocated_blocks)
 757{
 758	ListIterator results_i;
 759	allocated_block_t *allocated_block = NULL;
 760	allocated_block_t *temp_block = NULL;
 761	select_ba_request_t *request = NULL;
 762
 763	int i = 1, j;
 764	int len = strlen(com);
 765	char letter = '\0';
 766	int count = 1;
 767	int *geo = NULL, *geo_ptr = NULL;
 768
 769	/* look for the space after copy */
 770	while ((com[i-1] != ' ') && (i < len))
 771		i++;
 772
 773	if (i <= len) {
 774		/* Here we are looking for a real number for the count
 775		 * instead of the params.cluster_base so atoi is ok */
 776		if ((com[i] >= '0') && (com[i] <= '9'))
 777			count = atoi(com+i);
 778		else {
 779			letter = com[i];
 780			i++;
 781			if (com[i] != '\n') {
 782				while ((com[i-1] != ' ') && (i < len))
 783					i++;
 784
 785				if ((com[i] >= '0') && (com[i] <= '9'))
 786					count = atoi(com+i);
 787			}
 788		}
 789	}
 790
 791	results_i = list_iterator_create(allocated_blocks);
 792	while ((allocated_block = list_next(results_i)) != NULL) {
 793		temp_block = allocated_block;
 794		if (allocated_block->letter != letter)
 795			continue;
 796		break;
 797	}
 798	list_iterator_destroy(results_i);
 799
 800	if (!letter)
 801		allocated_block = temp_block;
 802
 803	if (!allocated_block) {
 804		memset(error_string, 0, 255);
 805		sprintf(error_string,
 806			"Could not find requested record to copy");
 807		return 0;
 808	}
 809
 810	for (i = 0; i < count; i++) {
 811		request = (select_ba_request_t*)
 812			  xmalloc(sizeof(select_ba_request_t));
 813		for (j = 0; j < params.cluster_dims; j++) {
 814			request->geometry[j] = allocated_block->request->
 815					       geometry[j];
 816			request->conn_type[j] = allocated_block->request->
 817						conn_type[j];
 818		}
 819		request->size = allocated_block->request->size;
 820		request->rotate =allocated_block->request->rotate;
 821		request->elongate = allocated_block->request->elongate;
 822		request->deny_pass = allocated_block->request->deny_pass;
 823#ifndef HAVE_BGL
 824		request->small16 = allocated_block->request->small16;
 825		request->small64 = allocated_block->request->small64;
 826		request->small256 = allocated_block->request->small256;
 827#endif
 828		request->small32 = allocated_block->request->small32;
 829		request->small128 = allocated_block->request->small128;
 830
 831		request->rotate_count= 0;
 832		request->elongate_count = 0;
 833	       	request->elongate_geos = list_create(NULL);
 834		request->avail_mp_bitmap = NULL;
 835
 836		results_i = list_iterator_create(request->elongate_geos);
 837		while ((geo_ptr = list_next(results_i)) != NULL) {
 838			geo = xmalloc(sizeof(int) * params.cluster_dims);
 839			for (j = 0; j < params.cluster_dims; j++)
 840				geo[j] = geo_ptr[j];
 841			list_append(request->elongate_geos, geo);
 842		}
 843		list_iterator_destroy(results_i);
 844
 845		if ((allocated_block = _make_request(request)) == NULL) {
 846			memset(error_string, 0, 255);
 847			sprintf(error_string,
 848				"Problem with the copy\n"
 849				"Are you sure there is enough room for it?");
 850			xfree(request);
 851			return 0;
 852		}
 853		list_append(allocated_blocks, allocated_block);
 854	}
 855	return 1;
 856
 857}
 858
 859static int _save_allocation(char *com, List allocated_blocks)
 860{
 861	int len = strlen(com);
 862	int i=5, j=0;
 863	allocated_block_t *allocated_block = NULL;
 864	char filename[50];
 865	char *save_string = NULL;
 866	FILE *file_ptr = NULL;
 867	char *extra = NULL;
 868
 869	ListIterator results_i;
 870
 871	memset(filename, 0, 50);
 872	if (len > 5)
 873		while (i<len) {
 874
 875			while (com[i-1]!=' ' && i<len) {
 876				i++;
 877			}
 878			while (i<len && com[i]!=' ') {
 879				filename[j] = com[i];
 880				i++;
 881				j++;
 882			}
 883		}
 884	if (filename[0]=='\0') {
 885		time_t now_time = time(NULL);
 886		sprintf(filename,"bluegene.conf.%ld",
 887			(long int) now_time);
 888	}
 889
 890	file_ptr = fopen(filename,"w");
 891
 892	if (file_ptr!=NULL) {
 893		char *image_dir = NULL;
 894
 895		xstrcat(save_string,
 896			"#\n# bluegene.conf file generated by smap\n");
 897		xstrcat(save_string,
 898			"# See the bluegene.conf man page for "
 899			"more information\n");
 900		xstrcat(save_string, "#\n");
 901#ifdef HAVE_BGL
 902		image_dir = "/bgl/BlueLight/ppcfloor/bglsys/bin";
 903		xstrfmtcat(save_string, "BlrtsImage=%s/rts_hw.rts\n",
 904			   image_dir);
 905		xstrfmtcat(save_string, "LinuxImage=%s/zImage.elf\n",
 906			   image_dir);
 907		xstrfmtcat(save_string,
 908			   "MloaderImage=%s/mmcs-mloader.rts\n",
 909			   image_dir);
 910		xstrfmtcat(save_string,
 911			   "RamDiskImage=%s/ramdisk.elf\n",
 912			   image_dir);
 913
 914		xstrcat(save_string, "IONodesPerMP=8 # io poor\n");
 915		xstrcat(save_string, "# IONodesPerMP=64 # io rich\n");
 916#elif defined HAVE_BGP
 917		image_dir = "/bgsys/drivers/ppcfloor/boot";
 918		xstrfmtcat(save_string, "CnloadImage=%s/cns,%s/cnk\n",
 919			   image_dir, image_dir);
 920		xstrfmtcat(save_string, "MloaderImage=%s/uloader\n",
 921			   image_dir);
 922		xstrfmtcat(save_string,
 923			   "IoloadImage=%s/cns,%s/linux,%s/ramdisk\n",
 924			   image_dir, image_dir, image_dir);
 925		xstrcat(save_string, "IONodesPerMP=4 # io poor\n");
 926		xstrcat(save_string, "# IONodesPerMP=32 # io rich\n");
 927#else
 928		image_dir = "/bgsys/drivers/ppcfloor/boot";
 929		xstrfmtcat(save_string, "MloaderImage=%s/firmware\n",
 930			   image_dir);
 931		xstrcat(save_string, "IONodesPerMP=4 # io semi-poor\n");
 932		xstrcat(save_string, "# IONodesPerMP=16 # io rich\n");
 933#endif
 934
 935		xstrcat(save_string, "BridgeAPILogFile="
 936		       "/var/log/slurm/bridgeapi.log\n");
 937
 938		xstrcat(save_string, "BridgeAPIVerbose=2\n");
 939
 940		xstrfmtcat(save_string, "BasePartitionNodeCnt=%d\n",
 941			   base_part_node_cnt);
 942		xstrfmtcat(save_string, "NodeCardNodeCnt=%d\n",
 943			   nodecard_node_cnt);
 944		if (!list_count(allocated_blocks))
 945			xstrcat(save_string, "LayoutMode=DYNAMIC\n");
 946		else {
 947			xstrfmtcat(save_string, "LayoutMode=%s\n", layout_mode);
 948			xstrfmtcat(save_string, "#\n# Block Layout\n#\n");
 949		}
 950		results_i = list_iterator_create(allocated_blocks);
 951		while ((allocated_block = list_next(results_i)) != NULL) {
 952			select_ba_request_t *request = allocated_block->request;
 953
 954			if (request->small16 || request->small32
 955			    || request->small64 || request->small128
 956			    || request->small256) {
 957#ifdef HAVE_BGL
 958				xstrfmtcat(extra,
 959					   " 32CNBlocks=%d "
 960					   "128CNBlocks=%d",
 961					   request->small32,
 962					   request->small128);
 963#elif defined HAVE_BGP
 964				xstrfmtcat(extra,
 965					   " 16CNBlocks=%d "
 966					   "32CNBlocks=%d "
 967					   "64CNBlocks=%d "
 968					   "128CNBlocks=%d "
 969					   "256CNBlocks=%d",
 970					   request->small16,
 971					   request->small32,
 972					   request->small64,
 973					   request->small128,
 974					   request->small256);
 975#else
 976				xstrfmtcat(extra,
 977					   " 32CNBlocks=%d "
 978					   "64CNBlocks=%d "
 979					   "128CNBlocks=%d "
 980					   "256CNBlocks=%d",
 981					   request->small32,
 982					   request->small64,
 983					   request->small128,
 984					   request->small256);
 985#endif
 986			}
 987
 988			xstrfmtcat(save_string, "MPs=%s", request->save_name);
 989
 990			for (i=0; i<SYSTEM_DIMENSIONS; i++) {
 991				if (request->conn_type[i] == (uint16_t)NO_VAL)
 992					break;
 993				if (i)
 994					xstrcat(save_string, ",");
 995				else
 996					xstrcat(save_string, " Type=");
 997				xstrfmtcat(save_string, "%s", conn_type_string(
 998						   request->conn_type[i]));
 999#ifdef HAVE_BG_L_P
1000				break;
1001#endif
1002			}
1003
1004			if (extra) {
1005				xstrfmtcat(save_string, "%s\n", extra);
1006				xfree(extra);
1007			} else
1008				xstrcat(save_string, "\n");
1009
1010		}
1011		list_iterator_destroy(results_i);
1012		fputs(save_string, file_ptr);
1013		xfree(save_string);
1014		fclose (file_ptr);
1015	}
1016
1017	return 1;
1018}
1019
1020static int _add_bg_record(select_ba_request_t *blockreq, List allocated_blocks)
1021{
1022	int rc = 1;
1023#ifdef HAVE_BG
1024	char *nodes = NULL, *host;
1025	int diff = 0;
1026	int largest_diff = -1;
1027	uint16_t start[params.cluster_dims];
1028	uint16_t end[params.cluster_dims];
1029	uint16_t best_start[params.cluster_dims];
1030	int i, j = 0;
1031	hostlist_t hl = NULL;
1032	bitstr_t *mark_bitmap = NULL;
1033	char tmp_char[params.cluster_dims+1],
1034		tmp_char2[params.cluster_dims+1];
1035
1036	memset(tmp_char, 0, sizeof(tmp_char));
1037	memset(tmp_char2, 0, sizeof(tmp_char2));
1038
1039	for (i = 0; i < params.cluster_dims; i++) {
1040		best_start[0] = 0;
1041		blockreq->geometry[i] = 0;
1042		end[i] = (int16_t)-1;
1043	}
1044
1045	nodes = blockreq->save_name;
1046	if (!nodes)
1047		return SLURM_SUCCESS;
1048
1049	while (nodes[j] && (nodes[j] != '[') &&
1050	       ((nodes[j] < '0') || (nodes[j] > '9')) &&
1051	       ((nodes[j] < 'A') || (nodes[j] > 'Z')))
1052		j++;
1053	if (nodes[j] == '\0') {
1054		snprintf(error_string, sizeof(error_string),
1055			 "This block '%s' for some reason didn't contain "
1056			 "any midplanes.",
1057			 nodes);
1058		rc = 0;
1059		goto fini;
1060	}
1061
1062	if (!(hl = hostlist_create(nodes+j))) {
1063		snprintf(error_string, sizeof(error_string),
1064			 "Bad hostlist given '%s'", nodes+j);
1065		rc = 0;
1066		goto fini;
1067	}
1068	/* figure out the geo and the size */
1069	mark_bitmap = bit_alloc(smap_system_ptr->node_cnt);
1070	while ((host = hostlist_shift(hl))) {
1071		ba_mp_t *ba_mp;
1072		uint16_t pos[params.cluster_dims];
1073		for (i = 0; i < params.cluster_dims; i++)
1074			pos[i] = select_char2coord(host[i]);
1075		free(host);
1076		if (!(ba_mp = bg_configure_coord2ba_mp(pos))) {
1077			memset(error_string, 0, 255);
1078			sprintf(error_string, "Bad host given '%s'", host);
1079			rc = 0;
1080			break;
1081		}
1082		bit_set(mark_bitmap, ba_mp->index);
1083		for (i = 0; i < params.cluster_dims; i++) {
1084			if (ba_mp->coord[i] > (int16_t)end[i]) {
1085				blockreq->geometry[i]++;
1086				end[i] = ba_mp->coord[i];
1087			}
1088		}
1089	}
1090	hostlist_destroy(hl);
1091
1092	if (!rc)
1093		goto fini;
1094
1095	/* figure out the start pos */
1096	while (nodes[j] != '\0') {
1097		int mid = j   + params.cluster_dims + 1;
1098		int fin = mid + params.cluster_dims + 1;
1099		if (((nodes[j] == '[')   || (nodes[j] == ','))   &&
1100		    ((nodes[mid] == 'x') || (nodes[mid] == '-')) &&
1101		    ((nodes[fin] == ']') || (nodes[fin] == ','))) {
1102			j++;	/* Skip leading '[' or ',' */
1103			for (i = 0; i < params.cluster_dims; i++, j++)
1104				start[i] = select_char2coord(nodes[j]);
1105			j++;	/* Skip middle 'x' or '-' */
1106			for (i = 0; i < params.cluster_dims; i++, j++)
1107				end[i] = select_char2coord(nodes[j]);
1108			diff = end[0] - start[0];
1109		} else if (((nodes[j] >= '0') && (nodes[j] <= '9')) ||
1110			   ((nodes[j] >= 'A') && (nodes[j] <= 'Z'))) {
1111			for (i = 0; i < params.cluster_dims; i++, j++)
1112				start[i] = select_char2coord(nodes[j]);
1113			diff = 0;
1114		} else {
1115			j++;
1116			continue;
1117		}
1118
1119		if (diff > largest_diff) {
1120			largest_diff = diff;
1121			memcpy(best_start, start, sizeof(best_start));
1122		}
1123		if (nodes[j] != ',')
1124			break;
1125	}
1126
1127	if (largest_diff == -1) {
1128		snprintf(error_string, sizeof(error_string),
1129			 "No hostnames given here");
1130		goto fini;
1131	}
1132
1133	memcpy(blockreq->start, best_start, sizeof(blockreq->start));
1134
1135
1136	if(!_full_request(blockreq, mark_bitmap, allocated_blocks))
1137		destroy_select_ba_request(blockreq);
1138fini:
1139	FREE_NULL_BITMAP(mark_bitmap);
1140
1141#endif
1142	return rc;
1143}
1144
1145static int _load_configuration(char *com, List allocated_blocks)
1146{
1147	int len = strlen(com);
1148	int i=5, j=0;
1149	char filename[100];
1150	s_p_hashtbl_t *tbl = NULL;
1151	char *layout = NULL;
1152	select_ba_request_t **blockreq_array = NULL;
1153	int count = 0;
1154
1155	if (allocated_blocks)
1156		list_flush(allocated_blocks);
1157	else
1158		allocated_blocks = list_create(_destroy_allocated_block);
1159
1160	memset(filename, 0, 100);
1161	if (len>5)
1162		while (i<len) {
1163			while (com[i-1]!=' ' && i<len) {
1164				i++;
1165			}
1166			while (i<len && com[i]!=' ') {
1167				filename[j] = com[i];
1168				i++;
1169				j++;
1170				if (j>100) {
1171					memset(error_string, 0, 255);
1172					sprintf(error_string,
1173						"filename is too long needs "
1174						"to be under 100 chars");
1175					return 0;
1176				}
1177			}
1178		}
1179
1180	if (filename[0]=='\0') {
1181		sprintf(filename,"bluegene.conf");
1182	}
1183
1184	if (!(tbl = bg_configure_config_make_tbl(filename))) {
1185		memset(error_string,0,255);
1186		sprintf(error_string, "ERROR: couldn't open/read %s",
1187			filename);
1188		return 0;
1189	}
1190
1191	if (!s_p_get_string(&layout, "LayoutMode", tbl)) {
1192		memset(error_string,0,255);
1193		sprintf(error_string,
1194			"Warning: LayoutMode was not specified in "
1195			"bluegene.conf defaulting to STATIC partitioning");
1196	} else {
1197		_set_layout(layout);
1198		xfree(layout);
1199	}
1200
1201	if (strcasecmp(layout_mode, "DYNAMIC")) {
1202		if (!s_p_get_array((void ***)&blockreq_array,
1203				   &count, "MPs", tbl)) {
1204			if (!s_p_get_array((void ***)&blockreq_array,
1205					   &count, "BPs", tbl)) {
1206				memset(error_string, 0, 255);
1207				sprintf(error_string,
1208					"WARNING: no blocks defined in "
1209					"bluegene.conf");
1210			}
1211		}
1212
1213		for (i = 0; i < count; i++) {
1214			_add_bg_record(blockreq_array[i], allocated_blocks);
1215			/* The freeing of this will happen when
1216			   allocated_blocks gets freed.
1217			*/
1218			blockreq_array[i] = NULL;
1219		}
1220	}
1221
1222	s_p_hashtbl_destroy(tbl);
1223	return 1;
1224}
1225
1226static void _print_header_command(void)
1227{
1228	main_ycord=2;
1229	mvwprintw(text_win, main_ycord,
1230		  main_xcord, "ID");
1231	main_xcord += 4;
1232	mvwprintw(text_win, main_ycord,
1233		  main_xcord, "TYPE");
1234	main_xcord += 8;
1235	mvwprintw(text_win, main_ycord,
1236		  main_xcord, "ROTATE");
1237	main_xcord += 7;
1238	mvwprintw(text_win, main_ycord,
1239		  main_xcord, "ELONG");
1240	main_xcord += 7;
1241#ifdef HAVE_BG
1242	mvwprintw(text_win, main_ycord,
1243		  main_xcord, "MIDPLANES");
1244#else
1245	mvwprintw(text_win, main_ycord,
1246		  main_xcord, "NODES");
1247#endif
1248	main_xcord += 10;
1249
1250#ifdef HAVE_BGP
1251	mvwprintw(text_win, main_ycord,
1252		  main_xcord, "16CN");
1253	main_xcord += 5;
1254#endif
1255	mvwprintw(text_win, main_ycord,
1256		  main_xcord, "32CN");
1257	main_xcord += 5;
1258#ifndef HAVE_BGL
1259	mvwprintw(text_win, main_ycord,
1260		  main_xcord, "64CN");
1261	main_xcord += 5;
1262#endif
1263	mvwprintw(text_win, main_ycord,
1264		  main_xcord, "128CN");
1265	main_xcord += 6;
1266#ifndef HAVE_BGL
1267	mvwprintw(text_win, main_ycord,
1268		  main_xcord, "256CN");
1269	main_xcord += 6;
1270#endif
1271#ifdef HAVE_BG
1272	mvwprintw(text_win, main_ycord,
1273		  main_xcord, "MIDPLANELIST");
1274#else
1275	mvwprintw(text_win, main_ycord,
1276		  main_xcord, "NODELIST");
1277#endif
1278	main_xcord = 1;
1279	main_ycord++;
1280}
1281
1282static void _print_text_command(allocated_block_t *allocated_block)
1283{
1284	char *tmp_char = NULL;
1285
1286	wattron(text_win,
1287		COLOR_PAIR(allocated_block->color));
1288
1289	mvwprintw(text_win, main_ycord,
1290		  main_xcord, "%c", allocated_block->letter);
1291	main_xcord += 4;
1292
1293	tmp_char = conn_type_string_full(allocated_block->request->conn_type);
1294	mvwprintw(text_win, main_ycord, main_xcord, tmp_char);
1295	xfree(tmp_char);
1296	main_xcord += 8;
1297
1298	if (allocated_block->request->rotate)
1299		mvwprintw(text_win, main_ycord,
1300			  main_xcord, "Y");
1301	else
1302		mvwprintw(text_win, main_ycord,
1303			  main_xcord, "N");
1304	main_xcord += 7;
1305
1306	if (allocated_block->request->elongate)
1307		mvwprintw(text_win, main_ycord,
1308			  main_xcord, "Y");
1309	else
1310		mvwprintw(text_win, main_ycord,
1311			  main_xcord, "N");
1312	main_xcord += 7;
1313
1314	mvwprintw(text_win, main_ycord,
1315		  main_xcord, "%d", allocated_block->request->size);
1316	main_xcord += 10;
1317
1318	if (allocated_block->request->conn_type[0] >= SELECT_SMALL) {
1319#ifdef HAVE_BGP
1320		mvwprintw(text_win, main_ycord,
1321			  main_xcord, "%d",
1322			  allocated_block->request->small16);
1323		main_xcord += 5;
1324#endif
1325
1326		mvwprintw(text_win, main_ycord,
1327			  main_xcord, "%d",
1328			  allocated_block->request->small32);
1329		main_xcord += 5;
1330
1331#ifndef HAVE_BGL
1332		mvwprintw(text_win, main_ycord,
1333			  main_xcord, "%d",
1334			  allocated_block->request->small64);
1335		main_xcord += 5;
1336#endif
1337
1338		mvwprintw(text_win, main_ycord,
1339			  main_xcord, "%d",
1340			  allocated_block->request->small128);
1341		main_xcord += 6;
1342
1343#ifndef HAVE_BGL
1344		mvwprintw(text_win, main_ycord,
1345			  main_xcord, "%d",
1346			  allocated_block->request->small256);
1347		main_xcord += 6;
1348#endif
1349	} else {
1350#ifdef HAVE_BGL
1351		main_xcord += 11;
1352#elif defined HAVE_BGP
1353		main_xcord += 27;
1354#else
1355		main_xcord += 22;
1356#endif
1357	}
1358	mvwprintw(text_win, main_ycord,
1359		  main_xcord, "%s",
1360		  allocated_block->request->save_name);
1361	main_xcord = 1;
1362	main_ycord++;
1363	wattroff(text_win,
1364		 COLOR_PAIR(allocated_block->color));
1365	return;
1366}
1367
1368void get_command(void)
1369{
1370	char com[255];
1371
1372	int text_width, text_startx;
1373	allocated_block_t *allocated_block = NULL;
1374	int i = 0;
1375	int count = 0;
1376
1377	WINDOW *command_win = NULL;
1378        List allocated_blocks = NULL;
1379	ListIterator results_i;
1380
1381	if (params.commandline && !params.command) {
1382		printf("Configure won't work with commandline mode.\n");
1383		printf("Please remove the -c from the commandline.\n");
1384		bg_configure_ba_fini();
1385		exit(0);
1386	}
1387
1388	if (working_cluster_rec) {
1389		char *cluster_name = slurm_get_cluster_name();
1390		if (strcmp(working_cluster_rec->name, cluster_name)) {
1391			xfree(cluster_name);
1392			endwin();
1393			printf("To use the configure option you must be on the "
1394			       "cluster the configure is for.\nCross cluster "
1395			       "support doesn't exist today.\nSorry for the "
1396			       "inconvenince.\n");
1397			bg_configure_ba_fini();
1398			exit(0);
1399		}
1400		xfree(cluster_name);
1401	}
1402
1403	/* make sure we don't get any noisy debug */
1404	ba_configure_set_ba_debug_flags(0);
1405
1406	bg_configure_ba_setup_wires();
1407
1408	color_count = 0;
1409
1410	allocated_blocks = list_create(_destroy_allocated_block);
1411
1412	if (params.commandline) {
1413		snprintf(com, sizeof(com), "%s", params.command);
1414		goto run_command;
1415	} else {
1416		text_width = text_win->_maxx;
1417		text_startx = text_win->_begx;
1418		command_win = newwin(3, text_width - 1, LINES - 4,
1419				     text_startx + 1);
1420		curs_set(1);
1421		echo();
1422	}
1423
1424	while (strcmp(com, "quit")) {
1425		clear_window(grid_win);
1426		print_grid();
1427		clear_window(text_win);
1428		box(text_win, 0, 0);
1429		box(grid_win, 0, 0);
1430
1431		if (!params.no_header)
1432			_print_header_command();
1433
1434		if (error_string != NULL) {
1435			i = 0;
1436			while (error_string[i] != '\0') {
1437				if (error_string[i] == '\n') {
1438					main_ycord++;
1439					main_xcord=1;
1440					i++;
1441				}
1442				mvwprintw(text_win,
1443					  main_ycord,
1444					  main_xcord,
1445					  "%c",
1446					  error_string[i++]);
1447				main_xcord++;
1448			}
1449			main_ycord++;
1450			main_xcord = 1;
1451			memset(error_string, 0, 255);
1452		}
1453		results_i = list_iterator_create(allocated_blocks);
1454
1455		count = list_count(allocated_blocks)
1456			- (LINES-(main_ycord+5));
1457
1458		if (count<0)
1459			count=0;
1460		i=0;
1461		while ((allocated_block = list_next(results_i)) != NULL) {
1462			if (i >= count)
1463				_print_text_command(allocated_block);
1464			i++;
1465		}
1466		list_iterator_destroy(results_i);
1467
1468		wnoutrefresh(text_win);
1469		wnoutrefresh(grid_win);
1470		doupdate();
1471		clear_window(command_win);
1472
1473		box(command_win, 0, 0);
1474		mvwprintw(command_win, 0, 3,
1475			  "Input Command: (type quit to change view, "
1476			  "exit to exit)");
1477		wmove(command_win, 1, 1);
1478		wgetstr(command_win, com);
1479
1480		if (!strcmp(com, "exit")) {
1481			endwin();
1482			if (allocated_blocks)
1483				list_destroy(allocated_blocks);
1484			bg_configure_ba_fini();
1485			exit(0);
1486		}
1487	run_command:
1488
1489		if (!strcmp(com, "quit") || !strcmp(com, "\\q")) {
1490			break;
1491		} else if (!strncasecmp(com, "layout", 6)) {
1492			_set_layout(com);
1493		} else if (!strncasecmp(com, "basepartition", 13)) {
1494			_set_base_part_cnt(com);
1495		} else if (!strncasecmp(com, "nodecard", 8)) {
1496			_set_nodecard_cnt(com);
1497		} else if (!strncasecmp(com, "resolve", 7) ||
1498			   !strncasecmp(com, "r ", 2)) {
1499			_resolve(com);
1500		} else if (!strncasecmp(com, "resume", 6)) {
1501			mvwprintw(text_win,
1502				main_ycord,
1503				main_xcord, "%s", com);
1504		} else if (!strncasecmp(com, "drain", 5)) {
1505			mvwprintw(text_win,
1506				main_ycord,
1507				main_xcord, "%s", com);
1508		} else if (!strncasecmp(com, "alldown", 7)) {
1509			_change_state_all_bps(com, NODE_STATE_DOWN);
1510		} else if (!strncasecmp(com, "down", 4)) {
1511			_change_state_bps(com, NODE_STATE_DOWN);
1512		} else if (!strncasecmp(com, "allup", 5)) {
1513			_change_state_all_bps(com, NODE_STATE_IDLE);
1514		} else if (!strncasecmp(com, "up", 2)) {
1515			_change_state_bps(com, NODE_STATE_IDLE);
1516		} else if (!strncasecmp(com, "remove", 6)
1517			|| !strncasecmp(com, "delete", 6)
1518			|| !strncasecmp(com, "drop", 4)) {
1519			_remove_allocation(com, allocated_blocks);
1520		} else if (!strncasecmp(com, "create", 6)) {
1521			_create_allocation(com, allocated_blocks);
1522		} else if (!strncasecmp(com, "copy", 4)
1523			|| !strncasecmp(com, "c ", 2)
1524			|| !strncasecmp(com, "c\0", 2)) {
1525			_copy_allocation(com, allocated_blocks);
1526		} else if (!strncasecmp(com, "save", 4)) {
1527			_save_allocation(com, allocated_blocks);
1528		} else if (!strncasecmp(com, "load", 4)) {
1529			_load_configuration(com, allocated_blocks);
1530		} else if (!strncasecmp(com, "clear all", 9)
1531			|| !strncasecmp(com, "clear", 5)) {
1532			list_flush(allocated_blocks);
1533		} else {
1534			memset(error_string, 0, 255);
1535			sprintf(error_string, "Unknown command '%s'",com);
1536		}
1537
1538		if (params.commandline) {
1539			bg_configure_ba_fini();
1540			exit(1);
1541		}
1542	}
1543	if (allocated_blocks)
1544		list_destroy(allocated_blocks);
1545	params.display = 0;
1546	noecho();
1547
1548	clear_window(text_win);
1549	main_xcord = 1;
1550	main_ycord = 1;
1551	curs_set(0);
1552	print_date();
1553	get_job();
1554	return;
1555}
1556