| /*****************************************************************************\ |
| * 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; |
| } |