diff --git a/src/sinfo/opts.c b/src/sinfo/opts.c index 28f7211ae49822b6dab8829c5f06eb69690ba5fb..10bacb106dc15ece1d5434edcdef8e1e1a7ab58a 100644 --- a/src/sinfo/opts.c +++ b/src/sinfo/opts.c @@ -36,7 +36,6 @@ #include "src/sinfo/sinfo.h" -#define OPT_SUMMARIZE 0x01 #define OPT_NODE_STATE 0x02 #define OPT_PARTITION 0x03 #define OPT_NODE 0x04 @@ -59,31 +58,29 @@ int parse_command_line(int argc, char *argv[]) option tag, docstr, argstr } */ poptContext context; - int next_opt, curr_opt; + int curr_opt; int rc = 0; /* Declare the Options */ static const struct poptOption options[] = { {"exact", 'e', POPT_ARG_NONE, ¶ms.exact_match, OPT_EXACT, - "group node only on exact match of configuration",NULL}, + "group nodes only on exact match of configuration",NULL}, {"iterate", 'i', POPT_ARG_INT, ¶ms.iterate, OPT_ITERATE, "specify an interation period", "seconds"}, {"state", 't', POPT_ARG_STRING, &temp_state, OPT_NODE_STATE, "specify the what state of nodes to view", "node_state"}, - {"partition", 'p', POPT_ARG_NONE, ¶ms.partition_flag, - OPT_PARTITION, - "show partition information and optionally specify a specific partition", - "PARTITION"}, - {"node", 'n', POPT_ARG_NONE, ¶ms.node_flag, OPT_NODE, - "specify a specific node", "NODE"}, + {"partition", 'p', POPT_ARG_STRING, ¶ms.partition, + OPT_PARTITION, "report on specific partition", "PARTITION"}, + {"nodes", 'n', POPT_ARG_STRING, ¶ms.nodes, OPT_NODE, + "report on specific node(s)", "NODES"}, + {"Node", 'N', POPT_ARG_NONE, ¶ms.node_flag, OPT_FORMAT, + "Node-centric format", NULL}, {"long", 'l', POPT_ARG_NONE, ¶ms.long_output, OPT_FORMAT, "long output - displays more information", NULL}, {"summarize", 's', POPT_ARG_NONE, ¶ms.summarize, - OPT_VERBOSE, - "summarize partitition information, do not show individual nodes", - NULL}, + OPT_FORMAT,"report state summary only", NULL}, {"verbose", 'v', POPT_ARG_NONE, ¶ms.verbose, OPT_VERBOSE, "verbosity level", "level"}, POPT_AUTOHELP @@ -94,28 +91,10 @@ int parse_command_line(int argc, char *argv[]) context = poptGetContext("sinfo", argc, (const char **) argv, options, POPT_CONTEXT_POSIXMEHARDER); - poptSetOtherOptionHelp(context, "[-elns]"); - - next_opt = poptGetNextOpt(context); - - while (next_opt > -1) { - const char *opt_arg = NULL; - curr_opt = next_opt; - next_opt = poptGetNextOpt(context); - - switch (curr_opt) { - case OPT_PARTITION: - if ((opt_arg = poptGetArg(context)) != NULL) { - params.partition = (char *) opt_arg; - } - break; + poptSetOtherOptionHelp(context, "[-elNsv]"); - case OPT_NODE: - if ((opt_arg = poptGetArg(context)) != NULL) { - params.node = (char *) opt_arg; - } - break; - case OPT_NODE_STATE: + while ((curr_opt = poptGetNextOpt(context)) > 0) { + if (curr_opt == OPT_NODE_STATE) { params.state_flag = true; if (_parse_state(temp_state, ¶ms.state) == SLURM_ERROR) { @@ -124,31 +103,13 @@ int parse_command_line(int argc, char *argv[]) argv[0], temp_state); exit(1); } - break; - - default: - break; - } - if ((opt_arg = poptGetArg(context)) != NULL) { - fprintf(stderr, "%s: %s \"%s\"\n", argv[0], - poptStrerror(POPT_ERROR_BADOPT), opt_arg); - exit(1); } - if (curr_opt < 0) { - fprintf(stderr, "%s: \"%s\" %s\n", argv[0], - poptBadOption(context, - POPT_BADOPTION_NOALIAS), - poptStrerror(next_opt)); - - exit(1); - } - } - if (next_opt < -1) { + if (curr_opt < -1) { const char *bad_opt; bad_opt = poptBadOption(context, POPT_BADOPTION_NOALIAS); fprintf(stderr, "bad argument %s: %s\n", bad_opt, - poptStrerror(next_opt)); + poptStrerror(curr_opt)); fprintf(stderr, "Try \"%s --help\" for more information\n", argv[0]); exit(1); @@ -201,18 +162,22 @@ static int _parse_state(char *str, enum node_states *states) /* print the parameters specified */ void print_options( void ) { + char *node_state; + + if (params.state_flag) + node_state = node_state_string(params.state); + else + node_state = "N/A"; + printf("-----------------------------\n"); - printf("partition(%s) = %s\n", - (params.partition_flag ? "true" : "false"), - params.partition); - printf("node(%s) = %s\n", (params.node_flag ? "true" : "false"), - params.node); - printf("state(%s) = %s\n", (params.state_flag ? "true" : "false"), - node_state_string(params.state)); - printf("summarize = %s\n", params.summarize ? "true" : "false"); - printf("exact = %d\n", params.exact_match); - printf("verbose = %d\n", params.verbose); - printf("long output = %s\n", - params.long_output ? "true" : "false"); + printf("exact = %d\n", params.exact_match); + printf("long format = %s\n", params.long_output ? "true" : "false"); + printf("nodes = %s\n", params.nodes ? params.nodes : "N/A"); + printf("Node format = %s\n", params.node_flag ? "true" : "false"); + printf("partition = %s\n", params.partition ? + params.partition: "N/A"); + printf("state = %s\n", node_state); + printf("summarize = %s\n", params.summarize ? "true" : "false"); + printf("verbose = %d\n", params.verbose); printf("-----------------------------\n\n"); } diff --git a/src/sinfo/sinfo.c b/src/sinfo/sinfo.c index 3dd2f29c8efe19259898806e2ca6f41853ea985c..dd920c4290958623e91856d787190d8e16b355a1 100644 --- a/src/sinfo/sinfo.c +++ b/src/sinfo/sinfo.c @@ -28,49 +28,47 @@ #include "src/common/hostlist.h" #include "src/common/list.h" -#define NODE_SIZE_CPUS 4 -#define NODE_SIZE_CPUS_LONG 4 -#define NODE_SIZE_DISK 8 -#define NODE_SIZE_DISK_LONG 8 -#define NODE_SIZE_FEATURES 0 -#define NODE_SIZE_MEM 6 -#define NODE_SIZE_MEM_LONG 6 -#define NODE_SIZE_NAME 15 -#define NODE_SIZE_PART 10 +#define NODE_SIZE_PART 9 #define NODE_SIZE_STATE 6 #define NODE_SIZE_STATE_LONG 11 +#define NODE_SIZE_NODES 5 +#define NODE_SIZE_CPUS 4 +#define NODE_SIZE_MEM 6 +#define NODE_SIZE_DISK 8 #define NODE_SIZE_WEIGHT 6 +#define NODE_SIZE_FEATURES 8 +#define NODE_SIZE_NAME 9 -#define PART_SIZE_CPUS 4 -#define PART_SIZE_CPUS_LONG 6 -#define PART_SIZE_DISK 8 -#define PART_SIZE_DISK_LONG 15 -#define PART_SIZE_MEM 6 -#define PART_SIZE_MEM_LONG 11 #define PART_SIZE_NODES 0 #define PART_SIZE_NUM 5 -#define PART_SIZE_PART 10 +#define PART_SIZE_PART 9 #define PART_SIZE_STATE 6 #define PART_SIZE_STATE_LONG 11 +#define PART_SIZE_AVAIL 5 +#define PART_SIZE_TIME 8 +#define PART_SIZE_JOB_SIZE 8 +#define PART_SIZE_ROOT_ONLY 4 +#define PART_SIZE_SHARE 5 +#define PART_SIZE_GROUPS 20 /******************** * Global Variables * ********************/ static char *command_name; struct sinfo_parameters params = - { partition_flag:false, partition:NULL, state_flag:false, - node_flag:false, node:NULL, summarize:false, long_output:false, + { partition:NULL, state_flag:false, + node_flag:false, nodes:NULL, summarize:false, long_output:false, line_wrap:false, verbose:false, iterate:0, exact_match:false }; static int node_sz_cpus, node_sz_name, node_sz_mem, node_sz_state; static int node_sz_disk, node_sz_part, node_sz_weight, node_sz_features; +static int node_sz_nodes; static int part_sz_num, part_sz_nodes, part_sz_part, part_sz_state; -static int part_sz_cpus, part_sz_disk, part_sz_mem; -static const char equal_string[] = - "================================================================================\n"; -static const char dash_line[] = - "------------------------------------------------------------------------\n"; - +static int part_sz_avail, part_sz_time, part_sz_job_nodes; +static int part_sz_root, part_sz_share, part_size_groups; +static const char dash_line_20[] = "--------------------"; +static const char dash_line_40[] = "----------------------------------------"; + /************ * Funtions * ************/ @@ -81,31 +79,37 @@ static int _query_server(partition_info_msg_t ** part_pptr, /* Node Functions */ static void _display_all_nodes(node_info_msg_t * node_msg, int node_rec_cnt); static void _display_node_info_header(void); -static void _display_nodes_list(List nodes); -static void _display_nodes_list_long(List nodes); +static void _display_node_info(List nodes); static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt); +static bool _exact_node_match(node_info_t *node1, node_info_t *node2); static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt); -static char *_node_name_string_from_list(List nodes, char *buffer); -static void _swap_char(char *from, char *to); +static void _node_cpus_string_from_list(List nodes, char *buffer); +static void _node_mem_string_from_list(List nodes, char *buffer); +static void _node_disk_string_from_list(List nodes, char *buffer); +static void _node_weight_string_from_list(List nodes, char *buffer); +static char *_node_name_string_from_list(List nodes, char *buffer, + int *node_count); +static void _swap_char(char **from, char **to); static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node); /* Partition Functions */ -static void _display_all_partition_info_long(List partitions); static void _display_all_partition_summary(partition_info_msg_t * part_ptr, node_info_msg_t * node_ptr, int node_rec_cnt); -static void _display_partition_info_long(struct partition_summary - *partition); static void _display_partition_node_info(struct partition_summary - *partition, bool print_name); + *partition); +static void _display_all_partition_info(List partitions); +static void _print_summary_header(void); +static void _display_partition_node_summary(struct partition_summary + *partition); static void _display_partition_summaries(List partitions); /* Misc Display functions */ -static int _build_min_max_string(char *buffer, int max, int min); +static int _build_min_max_string(char *buffer, int max, int min, bool range); static void _print_date(void); static int _print_int(int number, int width, bool right); static int _print_str(char *number, int width, bool right); -static void _set_node_field_sizes(void); +static void _set_node_field_sizes(List nodes); static void _set_part_field_sizes(void); /* Display partition functions */ @@ -115,7 +119,7 @@ static struct node_state_summary *_find_node_state_summary( static List _setup_partition_summary(partition_info_msg_t * part_ptr, node_info_msg_t * node_ptr, int node_rec_cnt); -static void _print_partition_header(bool no_name); +static void _print_partition_header(void); int main(int argc, char *argv[]) @@ -140,9 +144,8 @@ int main(int argc, char *argv[]) _filter_nodes(node_msg, &node_rec_cnt); - if (params.node_flag) + if (params.node_flag && (!params.summarize)) _display_all_nodes(node_msg, node_rec_cnt); - else _display_all_partition_summary(partition_msg, node_msg, node_rec_cnt); @@ -216,19 +219,20 @@ static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt) int i, new_rec_cnt = 0; hostlist_t hosts = NULL; - if ((params.node == NULL) && - (params.partition == NULL) && - (!params.state_flag)) { + if (((params.nodes == NULL) && + (params.partition == NULL) && + (!params.state_flag)) || + params.summarize) { /* Nothing to filter out */ *node_rec_cnt = node_msg->record_count; return; } - if (params.node) - hosts = hostlist_create(params.node); + if (params.nodes) + hosts = hostlist_create(params.nodes); for (i = 0; i < node_msg->record_count; i++) { - if (params.node && hostlist_find + if (params.nodes && hostlist_find (hosts, node_msg->node_array[i].name) == -1) continue; if (params.partition && strcmp @@ -251,25 +255,27 @@ static void _filter_nodes(node_info_msg_t *node_msg, int *node_rec_cnt) *node_rec_cnt = new_rec_cnt; } -static void _swap_char(char *from, char *to) +static void _swap_char(char **from, char **to) { char *tmp; - tmp = to; - to = from; - from = tmp; + tmp = *to; + *to = *from; + *from = tmp; } /* Swap *char values, just overwrite the numbers in moving node info */ static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node) { - _swap_char(from_node->name, to_node->name); - _swap_char(from_node->features, to_node->features); - _swap_char(from_node->partition, to_node->partition); - to_node->node_state = from_node->node_state; - to_node->cpus = from_node->cpus; - to_node->real_memory = from_node->real_memory; - to_node->tmp_disk = from_node->tmp_disk; - to_node->weight = from_node->weight; + if (from_node != to_node) { + _swap_char(&from_node->name, &to_node->name); + _swap_char(&from_node->features, &to_node->features); + _swap_char(&from_node->partition, &to_node->partition); + to_node->node_state = from_node->node_state; + to_node->cpus = from_node->cpus; + to_node->real_memory = from_node->real_memory; + to_node->tmp_disk = from_node->tmp_disk; + to_node->weight = from_node->weight; + } } @@ -279,75 +285,88 @@ static void _swap_node_rec(node_info_t *from_node, node_info_t *to_node) static void _display_all_nodes(node_info_msg_t * node_msg, int node_rec_cnt) { - _set_node_field_sizes(); - _display_node_info_header(); - - if (params.long_output == true) { - List nodes = list_create(NULL); - int i; - - for (i = 0; i < node_rec_cnt; i++) - list_append(nodes, &node_msg->node_array[i]); + List nodes = _group_node_list(node_msg, node_rec_cnt); + ListIterator i = list_iterator_create(nodes); + List current; - _display_nodes_list_long(nodes); - list_destroy(nodes); - } else { - List nodes = _group_node_list(node_msg, node_rec_cnt); - ListIterator i = list_iterator_create(nodes); - List current; + _set_node_field_sizes(nodes); + _display_node_info_header(); - while ((current = list_next(i)) != NULL) { - _display_nodes_list(current); - list_destroy(current); - } - list_iterator_destroy(i); - list_destroy(nodes); + while ((current = list_next(i)) != NULL) { + _display_node_info(current); + list_destroy(current); } + list_iterator_destroy(i); + list_destroy(nodes); } -static void _set_node_field_sizes(void) +static void _set_node_field_sizes(List nodes) { + int node_cnt, len; + char node_names[64]; + List current; + ListIterator i = list_iterator_create(nodes); + node_sz_features = NODE_SIZE_FEATURES; - node_sz_name = NODE_SIZE_NAME; node_sz_part = NODE_SIZE_PART; node_sz_weight = NODE_SIZE_WEIGHT; - if (params.long_output) { - node_sz_cpus = NODE_SIZE_CPUS_LONG; - node_sz_disk = NODE_SIZE_DISK_LONG; - node_sz_mem = NODE_SIZE_MEM_LONG; + node_sz_cpus = NODE_SIZE_CPUS; + node_sz_disk = NODE_SIZE_DISK; + node_sz_mem = NODE_SIZE_MEM; + node_sz_nodes = NODE_SIZE_NODES; + if (params.long_output) node_sz_state = NODE_SIZE_STATE_LONG; - } else { - node_sz_cpus = NODE_SIZE_CPUS; - node_sz_disk = NODE_SIZE_DISK; - node_sz_mem = NODE_SIZE_MEM; + else node_sz_state = NODE_SIZE_STATE; + + node_sz_name = NODE_SIZE_NAME; + while ((current = list_next(i)) != NULL) { + _node_name_string_from_list(current, node_names, &node_cnt); + len = strlen(node_names); + if (len > node_sz_name) + node_sz_name = len; } + list_iterator_destroy(i); } static void _display_node_info_header() { - _print_str("NODES", node_sz_name, false); - printf(" "); - _print_str("STATE", node_sz_state, false); - printf(" "); - _print_str("CPUS", node_sz_cpus, true); - printf(" "); - _print_str("MEMORY", node_sz_mem, true); + _print_str("NODE_LIST", node_sz_name, false); printf(" "); - _print_str("TMP_DISK", node_sz_disk, true); - printf(" "); - _print_str("WEIGHT", node_sz_weight, true); + _print_str("NODES", node_sz_nodes, false); printf(" "); _print_str("PARTITION", node_sz_part, false); printf(" "); - _print_str("FEATURES", node_sz_features, false); - printf("\n"); - printf(dash_line); + _print_str("STATE", node_sz_state, false); + + if (params.long_output) { + printf(" "); + _print_str("CPUS", node_sz_cpus, true); + printf(" "); + _print_str("MEMORY", node_sz_mem, true); + printf(" "); + _print_str("TMP_DISK", node_sz_disk, true); + printf(" "); + _print_str("WEIGHT", node_sz_weight, true); + printf(" "); + _print_str("FEATURES", node_sz_features, false); + } + printf("\n%s%s\n", dash_line_40, dash_line_40); + } -static void _display_node_info(node_info_t * node, char *name) +static void _display_node_info(List nodes) { - _print_str(name, node_sz_name, false); + char node_names[64]; + int node_cnt; + node_info_t *node = list_peek(nodes); + + _node_name_string_from_list(nodes, node_names, &node_cnt); + _print_str(node_names, node_sz_name, false); + printf(" "); + _print_int(node_cnt, node_sz_nodes, true); + printf(" "); + _print_str(node->partition, node_sz_part, false); printf(" "); if (params.long_output) _print_str(node_state_string(node->node_state), @@ -355,49 +374,36 @@ static void _display_node_info(node_info_t * node, char *name) else _print_str(node_state_string_compact(node->node_state), node_sz_state, false); - printf(" "); - _print_int(node->cpus, node_sz_cpus, true); - printf(" "); - _print_int(node->real_memory, node_sz_mem, true); - printf(" "); - _print_int(node->tmp_disk, node_sz_disk, true); - printf(" "); - _print_int(node->weight, node_sz_weight, true); - printf(" "); - _print_str(node->partition, node_sz_part, false); - printf(" "); - _print_str(node->features, node_sz_features, false); - printf("\n"); -} - -static void _display_nodes_list(List nodes) -{ - /*int console_width = atoi( getenv( "COLUMNS" ) ); */ - char node_names[32]; - node_info_t *curr = list_peek(nodes); - _node_name_string_from_list(nodes, node_names); - _display_node_info(curr, node_names); -} + if (params.long_output) { + int tmp_feature_size; + char str_buf[64]; -static void _display_nodes_list_long(List nodes) -{ - /*int console_width = atoi( getenv( "COLUMNS" ) ); */ - int count = 0; - ListIterator i = list_iterator_create(nodes); - node_info_t *curr = NULL; + printf(" "); + _node_cpus_string_from_list(nodes, str_buf); + _print_str(str_buf, node_sz_cpus, true); + printf(" "); + _node_mem_string_from_list(nodes, str_buf); + _print_str(str_buf, node_sz_mem, true); + printf(" "); + _node_disk_string_from_list(nodes, str_buf); + _print_str(str_buf, node_sz_disk, true); + printf(" "); + _node_weight_string_from_list(nodes, str_buf); + _print_str(str_buf, node_sz_weight, true); - while ((curr = list_next(i)) != NULL) { - if (params.partition != NULL - && strcmp(params.partition, curr->partition)) - continue; - _display_node_info(curr, curr->name); - count++; + printf(" "); + tmp_feature_size = node_sz_features; + if (node->features && + (strlen(node->features) > tmp_feature_size)) + tmp_feature_size = 0; + _print_str(node->features, tmp_feature_size, false); } - printf("-- %8d NODES LISTED --\n\n", count); + printf("\n"); } + /* group similar nodes together, return a list of lists containing nodes * with similar configurations */ static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt) @@ -413,36 +419,18 @@ static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt) list_i = list_iterator_create(node_lists); while ((curr_list = list_next(list_i)) != NULL) { node_info_t *curr = list_peek(curr_list); - bool feature_test; - bool part_test; - - if (curr->features != NULL - && nodes[i].features != NULL) - feature_test = - strcmp(nodes[i].features, - curr->features) ? false : true; - else if (curr->features == nodes[i].features) - feature_test = true; - else - feature_test = false; - if (curr->partition != NULL - && nodes[i].partition != NULL) - part_test = - strcmp(nodes[i].partition, - curr->partition) ? false : true; - else if (curr->partition == nodes[i].partition) - part_test = true; - else - part_test = false; - - if (feature_test && part_test && - nodes[i].node_state == curr->node_state && - nodes[i].cpus == curr->cpus && - nodes[i].real_memory == curr->real_memory && - nodes[i].tmp_disk == curr->tmp_disk) { - list_append(curr_list, &(nodes[i])); - break; - } + + if ((curr->partition != NULL) && + (nodes[i].partition != NULL) && + (strcmp(nodes[i].partition, + curr->partition) != 0)) + continue; + + if (!_exact_node_match(curr, &nodes[i])) + continue; + + list_append(curr_list, &(nodes[i])); + break; } list_iterator_destroy(list_i); @@ -456,6 +444,28 @@ static List _group_node_list(node_info_msg_t * msg, int node_rec_cnt) return node_lists; } +/* Return true if all of the nodes' configurations match */ +static bool _exact_node_match(node_info_t *node1, node_info_t *node2) +{ + if (node1->node_state != node2->node_state) + return false; + else if ((!params.exact_match) || (!params.long_output)) + return true; + + if (node1->features && node2->features && + strcmp(node1->features, node2->features)) + return false; + else if (node1->features != node2->features) + return false; + + if ((node1->cpus != node2->cpus) || + (node1->real_memory != node2->real_memory) || + (node1->tmp_disk != node2->tmp_disk)) + return false; + else + return true; +} + /***************************************************************************** * DISPLAY PARTITION INFO FUNCTIONS *****************************************************************************/ @@ -478,6 +488,9 @@ static struct partition_summary *_find_partition_summary(List l, char *name) return current; } +/* Return a pointer to the node in the supplied list that contains + * the same configuration (just node_state at present). If none + * found then return NULL */ static struct node_state_summary * _find_node_state_summary(List l, node_info_t *ninfo) { @@ -485,13 +498,8 @@ _find_node_state_summary(List l, node_info_t *ninfo) struct node_state_summary *current; while ((current = list_next(i)) != NULL) { - if (ninfo->node_state != current->state) - continue; - if (params.exact_match == 0) - break; - if ((ninfo->cpus == current->cpu_min) && - (ninfo->real_memory == current->ram_min) && - (ninfo->tmp_disk == current->disk_min)) + if ((params.summarize) || + (ninfo->node_state == current->state)) break; } @@ -499,9 +507,12 @@ _find_node_state_summary(List l, node_info_t *ninfo) return current; } +/* Construct a list of partitions containing the configuration + * of that partition along with configuration about the nodes + * in that partition */ static List _setup_partition_summary(partition_info_msg_t * part_ptr, - node_info_msg_t * node_ptr, int node_rec_cnt) + node_info_msg_t * node_ptr, int node_rec_cnt) { int i = 0; List partitions = list_create(NULL); @@ -524,7 +535,8 @@ _setup_partition_summary(partition_info_msg_t * part_ptr, if (ninfo->partition == NULL) { if (params.verbose) - printf("Node %s is not in any partition\n\n", + fprintf(stderr, + "Node %s is not in any partition\n\n", ninfo->name); continue; } @@ -532,28 +544,15 @@ _setup_partition_summary(partition_info_msg_t * part_ptr, ninfo->partition); if (part_sum == NULL) { /* This should never happen */ - printf - ("Couldn't find partition %s, notify system administators\n", - ninfo->partition); + fprintf(stderr, "Couldn't find partition %s", + ninfo->partition); + fprintf(stderr,"Please notify system administators\n"); continue; } - if ((node_sum = - _find_node_state_summary(part_sum->states, ninfo))) { - node_sum->state = - (enum node_states) ninfo->node_state; - node_sum->cpu_max = - MAX(ninfo->cpus, node_sum->cpu_max); - node_sum->cpu_min = - MIN(ninfo->cpus, node_sum->cpu_min); - node_sum->ram_max = - MAX(ninfo->real_memory, node_sum->ram_max); - node_sum->ram_min = - MIN(ninfo->real_memory, node_sum->ram_min); - node_sum->disk_max = - MAX(ninfo->tmp_disk, node_sum->disk_max); - node_sum->disk_min = - MIN(ninfo->tmp_disk, node_sum->disk_min); + if ((node_sum = _find_node_state_summary(part_sum->states, + ninfo))) { + node_sum->state = (enum node_states) ninfo->node_state; hostlist_push(node_sum->nodes, ninfo->name); node_sum->node_count++; } else { @@ -561,12 +560,6 @@ _setup_partition_summary(partition_info_msg_t * part_ptr, malloc(sizeof(struct node_state_summary)); node_sum->state = (enum node_states) ninfo->node_state; - node_sum->cpu_max = ninfo->cpus; - node_sum->cpu_min = ninfo->cpus; - node_sum->ram_max = ninfo->real_memory; - node_sum->ram_min = ninfo->real_memory; - node_sum->disk_max = ninfo->tmp_disk; - node_sum->disk_min = ninfo->tmp_disk; node_sum->node_count = 1; node_sum->nodes = hostlist_create(ninfo->name); list_append(part_sum->states, node_sum); @@ -583,10 +576,10 @@ _display_all_partition_summary(partition_info_msg_t * part_ptr, List partitions = _setup_partition_summary(part_ptr, node_ptr, node_rec_cnt); _set_part_field_sizes(); - if (params.long_output) - _display_all_partition_info_long(partitions); - else + if (params.summarize) _display_partition_summaries(partitions); + else + _display_all_partition_info(partitions); list_destroy(partitions); } @@ -595,94 +588,177 @@ static void _set_part_field_sizes(void) part_sz_part = PART_SIZE_PART; part_sz_num = PART_SIZE_NUM; part_sz_nodes = PART_SIZE_NODES; - if (params.long_output) { - part_sz_cpus = PART_SIZE_CPUS_LONG; - part_sz_disk = PART_SIZE_DISK_LONG; - part_sz_mem = PART_SIZE_MEM_LONG; + if (params.long_output) part_sz_state = PART_SIZE_STATE_LONG; - } else { - part_sz_cpus = PART_SIZE_CPUS; - part_sz_disk = PART_SIZE_DISK; - part_sz_mem = PART_SIZE_MEM; + else part_sz_state = PART_SIZE_STATE; - } + part_sz_avail = PART_SIZE_AVAIL; + part_sz_time = PART_SIZE_TIME; + part_sz_job_nodes = PART_SIZE_JOB_SIZE; + part_sz_root = PART_SIZE_ROOT_ONLY; + part_sz_share = PART_SIZE_SHARE; + part_size_groups = PART_SIZE_GROUPS; } /* Formating for partiton display headers... */ -static void _print_partition_header(bool no_name) +static void _print_summary_header(void) { - if (no_name == true) - printf("\t"); - else { - _print_str("PARTITION", part_sz_part, false); - printf(" "); - } + _print_str("PARTITION", part_sz_part, false); + printf(" "); + _print_str("AVAIL", part_sz_avail, false); + printf(" "); _print_str("NODES", part_sz_num, true); printf(" "); - _print_str("STATE", part_sz_state, false); + _print_str("NODE_LIST", part_sz_nodes, false); + printf("\n%s%s\n", dash_line_40, dash_line_20); +} + +static void +_display_partition_node_summary(struct partition_summary *partition) +{ + int line_cnt = 0; + char name_buf[64], part_name[64]; + + ListIterator node_i = list_iterator_create(partition->states); + struct node_state_summary *state_sum = NULL; + + strcpy(part_name, partition->info->name); + if (partition->info->default_part) + strcat(part_name, "*"); + + while ((state_sum = list_next(node_i)) != NULL) { + line_cnt++; + hostlist_ranged_string(state_sum->nodes, 64, name_buf); + _print_str(part_name, part_sz_part, false); + printf(" "); + _print_str(partition->info->state_up ? "UP" : "DOWN", + part_sz_avail, false); + printf(" "); + _print_int(state_sum->node_count, part_sz_num, true); + printf(" "); + _print_str(name_buf, part_sz_nodes, false); + printf("\n"); + } + list_iterator_destroy(node_i); + + if (line_cnt == 0) { + _print_str(part_name, part_sz_part, false); + printf(" "); + _print_str(partition->info->state_up ? "UP" : "DOWN", + part_sz_avail, false); + printf(" "); + _print_int(0, part_sz_num, true); + printf("\n"); + } +} + +static void _display_partition_summaries(List partitions) +{ + struct partition_summary *partition; + ListIterator part_i = list_iterator_create(partitions); + + _print_summary_header(); + while ((partition = list_next(part_i)) != NULL) { + if (params.partition == NULL + || strcmp(partition->info->name, + params.partition) == 0) + _display_partition_node_summary(partition); + } + list_iterator_destroy(part_i); +} + + +/* Formating for partiton display headers... */ +static void _print_partition_header(void) +{ + _print_str("PARTITION", part_sz_part, false); printf(" "); - _print_str("CPUS", part_sz_cpus, true); + _print_str("AVAIL", part_sz_avail, false); printf(" "); - _print_str("MEMORY", part_sz_mem, true); + _print_str("NODES", part_sz_num, true); printf(" "); - _print_str("TMP_DISK", part_sz_disk, true); + _print_str("STATE", part_sz_state, false); + if (params.long_output) { + printf(" "); + _print_str("MAX_TIME", part_sz_time, true); + printf(" "); + _print_str("JOB_SIZE", part_sz_job_nodes, true); + printf(" "); + _print_str("ROOT", part_sz_root, false); + printf(" "); + _print_str("SHARE", part_sz_share, false); + printf(" "); + _print_str("GROUPS", part_size_groups, false); + } printf(" "); - _print_str("NODES", part_sz_nodes, false); - printf("\n"); - if (no_name == true) - printf("\t%s", dash_line); + _print_str("NODE_LIST", part_sz_nodes, false); + if (params.long_output) + printf("\n%s%s%s\n", dash_line_40, dash_line_40, dash_line_20); else - printf("%s", dash_line); + printf("\n%s%s\n", dash_line_40, dash_line_40); } -static void _display_partition_summaries(List partitions) +static void _display_all_partition_info(List partitions) { struct partition_summary *partition; ListIterator part_i = list_iterator_create(partitions); - _print_partition_header(false); + _print_partition_header(); while ((partition = list_next(part_i)) != NULL) { if (params.partition == NULL || strcmp(partition->info->name, params.partition) == 0) - _display_partition_node_info(partition, true); + _display_partition_node_info(partition); } list_iterator_destroy(part_i); } static void -_display_partition_node_info(struct partition_summary *partition, - bool print_name) +_display_partition_node_info(struct partition_summary *partition) { char *no_name = ""; - char cpu_buf[64]; - char ram_buf[64]; - char disk_buf[64]; - char name_buf[64]; + char name_buf[64], part_name[64], part_time[20], part_job_size[30]; + char part_root[10], part_share[10], *part_groups; int line_cnt = 0; - ListIterator node_i = list_iterator_create(partition->states); struct node_state_summary *state_sum = NULL; - char *part_name = partition->info->name; + char *part_state = partition->info->state_up ? "UP" : "DOWN"; + + strcpy(part_name, partition->info->name); + if (partition->info->default_part) + strcat(part_name, "*"); + if (partition->info->max_time == -1) + strcpy(part_time, "NONE"); + else + sprintf(part_time, "%d", partition->info->max_time); + (void) _build_min_max_string(part_job_size, + partition->info->min_nodes, + partition->info->max_nodes, true); + if (partition->info->root_only) + strcpy(part_root, "YES"); + else + strcpy(part_root, "NO"); + if (partition->info->shared == 2) + strcpy(part_share, "FORCE"); + else if(partition->info->shared) + strcpy(part_share, "YES"); + else + strcpy(part_share, "NO"); + if (partition->info->allow_groups) + part_groups = partition->info->allow_groups; + else + part_groups = "ALL"; while ((state_sum = list_next(node_i)) != NULL) { line_cnt++; - _build_min_max_string(ram_buf, state_sum->ram_min, - state_sum->ram_max); - _build_min_max_string(disk_buf, state_sum->disk_min, - state_sum->disk_max); - _build_min_max_string(cpu_buf, state_sum->cpu_min, - state_sum->cpu_max); hostlist_ranged_string(state_sum->nodes, 64, name_buf); - if (print_name == true) { - _print_str(part_name, part_sz_part, false); - printf(" "); - } else - printf("\t"); - + _print_str(part_name, part_sz_part, false); + printf(" "); + _print_str(part_state, part_sz_avail, false); + printf(" "); _print_int(state_sum->node_count, part_sz_num, true); printf(" "); if (params.long_output) @@ -691,90 +767,62 @@ _display_partition_node_info(struct partition_summary *partition, else _print_str(node_state_string_compact(state_sum->state), part_sz_state, false); - printf(" "); - _print_str(cpu_buf, part_sz_cpus, true); - printf(" "); - _print_str(ram_buf, part_sz_mem, true); - printf(" "); - _print_str(disk_buf, part_sz_disk, true); + if (params.long_output) { + printf(" "); + _print_str(part_time, part_sz_time, true); + printf(" "); + _print_str(part_job_size, part_sz_job_nodes, true); + printf(" "); + _print_str(part_root, part_sz_root, false); + printf(" "); + _print_str(part_share, part_sz_share, false); + printf(" "); + _print_str(part_groups, part_size_groups, false); + } printf(" "); _print_str(name_buf, part_sz_nodes, false); printf("\n"); - part_name = no_name; + strcpy(part_name, ""); + strcpy(part_time, ""); + strcpy(part_job_size, ""); + strcpy(part_root, ""); + strcpy(part_share, ""); + part_state = no_name; + part_groups = no_name; } list_iterator_destroy(node_i); if (line_cnt == 0) { - if (print_name == true) { - _print_str(part_name, part_sz_part, false); - printf(" "); - } else - printf("\t"); - _print_int(0, part_sz_num, true); + _print_str(part_name, part_sz_part, false); printf(" "); - _print_str("N/A", part_sz_state, false); - printf(" "); - _print_str("0", part_sz_cpus, true); + _print_str(part_state, part_sz_avail, false); printf(" "); - _print_str("0", part_sz_mem, true); + _print_int(0, part_sz_num, true); printf(" "); - _print_str("0", part_sz_disk, true); + _print_str("N/A", part_sz_state, false); + if (params.long_output) { + printf(" "); + _print_str(part_time, part_sz_time, true); + printf(" "); + _print_str(part_job_size, part_sz_job_nodes, true); + printf(" "); + _print_str(part_root, part_sz_root, false); + printf(" "); + _print_str(part_share, part_sz_share, false); + printf(" "); + _print_str(part_groups, part_size_groups, false); + } printf(" "); _print_str("", part_sz_nodes, false); printf("\n"); } } -static void _display_all_partition_info_long(List partitions) -{ - struct partition_summary *partition; - ListIterator part_i = list_iterator_create(partitions); - - printf("PARTITION INFORMATION\n"); - while ((partition = list_next(part_i)) != NULL) { - if (params.partition == NULL - || strcmp(partition->info->name, - params.partition) == 0) - _display_partition_info_long(partition); - printf("\n"); - } - printf("%s", equal_string); - list_iterator_destroy(part_i); -} - -void _display_partition_info_long(struct partition_summary *partition) -{ - partition_info_t *part = partition->info; - - printf("%s", equal_string); - printf("%s\n", part->name); - printf("\tcurrent state = %s\n", - part->state_up ? "UP" : "DOWN"); - printf("\tdefault partition = %s\n", - part->default_part ? "YES" : "NO"); - printf("\ttotal nodes = %d\n", part->total_nodes); - printf("\ttotal cpus = %d\n", part->total_cpus); - if (part->max_time == -1) - printf("\tmax jobtime = NONE\n"); - else - printf("\tmax jobtime = %d\n", part->max_time); - printf("\tmax nodes/job = %d\n", part->max_nodes); - printf("\troot only = %s\n", - part->root_only ? "YES" : "NO"); - printf("\tshare nodes = %s\n", - part->shared == 2 ? "ALWAYS" : part->shared ? "YES" : "NO"); - - printf("\n"); - _print_partition_header(true); - _display_partition_node_info(partition, false); - -} - -static int _build_min_max_string(char *buffer, int min, int max) +static int _build_min_max_string(char *buffer, int min, int max, bool range) { if (max == min) return sprintf(buffer, "%d", max); - else if (params.long_output) + else if (range) return sprintf(buffer, "%d-%d", min, max); else return sprintf(buffer, "%d+", min); @@ -827,20 +875,140 @@ static void _print_date(void) * prefix[001-100] type format. * IN nodes - list of node_info_t* to analyze * OUT buffer - a char buffer to store the string in. + * OUT node_count - count of nodes found * RET on success return buffer, NULL on failure */ - -static char *_node_name_string_from_list(List nodes, char *buffer) +static char *_node_name_string_from_list(List nodes, char *buffer, + int *node_count) { node_info_t *curr_node = NULL; ListIterator i = list_iterator_create(nodes); hostlist_t list = hostlist_create(NULL); - while ((curr_node = list_next(i)) != NULL) + *node_count = 0; + while ((curr_node = list_next(i)) != NULL) { hostlist_push(list, curr_node->name); + (*node_count)++; + } list_iterator_destroy(i); hostlist_ranged_string(list, 32, buffer); hostlist_destroy(list); return buffer; } + +/* _node_cpus_string_from_list - analyzes a list of node_info_t* and + * fills in a buffer with CPU count, "123+" if a range. + * IN nodes - list of node_info_t* to analyze + * OUT buffer - a char buffer to store the string in. + */ +static void _node_cpus_string_from_list(List nodes, char *buffer) +{ + node_info_t *curr_node = NULL; + int min_cpus=0, max_cpus=0; + bool first = true; + ListIterator i = list_iterator_create(nodes); + + while ((curr_node = list_next(i)) != NULL) { + if (first) { + first = false; + min_cpus = max_cpus = curr_node->cpus; + } + else if (min_cpus > curr_node->cpus) + min_cpus = curr_node->cpus; + else if (max_cpus < curr_node->cpus) + max_cpus = curr_node->cpus; + } + list_iterator_destroy(i); + if (first) + strcpy(buffer, ""); + else + _build_min_max_string(buffer, min_cpus, max_cpus, false); +} + +/* _node_mem_string_from_list - analyzes a list of node_info_t* and + * fills in a buffer with real memory size, "123+" if a range. + * IN nodes - list of node_info_t* to analyze + * OUT buffer - a char buffer to store the string in. + */ +static void _node_mem_string_from_list(List nodes, char *buffer) +{ + node_info_t *curr_node = NULL; + int min_mem=0, max_mem=0; + bool first = true; + ListIterator i = list_iterator_create(nodes); + + while ((curr_node = list_next(i)) != NULL) { + if (first) { + first = false; + min_mem = max_mem = curr_node->real_memory; + } + else if (min_mem > curr_node->real_memory) + min_mem = curr_node->real_memory; + else if (max_mem < curr_node->real_memory) + max_mem = curr_node->real_memory; + } + list_iterator_destroy(i); + if (first) + strcpy(buffer, ""); + else + _build_min_max_string(buffer, min_mem, max_mem, false); +} + +/* _node_disk_string_from_list - analyzes a list of node_info_t* and + * fills in a buffer with temporary disk size, "123+" if a range. + * IN nodes - list of node_info_t* to analyze + * OUT buffer - a char buffer to store the string in. + */ +static void _node_disk_string_from_list(List nodes, char *buffer) +{ + node_info_t *curr_node = NULL; + int min_disk=0, max_disk=0; + bool first = true; + ListIterator i = list_iterator_create(nodes); + + while ((curr_node = list_next(i)) != NULL) { + if (first) { + first = false; + min_disk = max_disk = curr_node->tmp_disk; + } + else if (min_disk > curr_node->tmp_disk) + min_disk = curr_node->tmp_disk; + else if (max_disk < curr_node->tmp_disk) + max_disk = curr_node->tmp_disk; + } + list_iterator_destroy(i); + if (first) + strcpy(buffer, ""); + else + _build_min_max_string(buffer, min_disk, max_disk, false); +} + +/* _node_weight_string_from_list - analyzes a list of node_info_t* and + * fills in a buffer with their weights, "123+" if a range. + * IN nodes - list of node_info_t* to analyze + * OUT buffer - a char buffer to store the string in. + */ +static void _node_weight_string_from_list(List nodes, char *buffer) +{ + node_info_t *curr_node = NULL; + int min_weight=0, max_weight=0; + bool first = true; + ListIterator i = list_iterator_create(nodes); + + while ((curr_node = list_next(i)) != NULL) { + if (first) { + first = false; + min_weight = max_weight = curr_node->weight; + } + else if (min_weight > curr_node->weight) + min_weight = curr_node->weight; + else if (min_weight < curr_node->weight) + max_weight = curr_node->weight; + } + list_iterator_destroy(i); + if (first) + strcpy(buffer, ""); + else + _build_min_max_string(buffer, min_weight, max_weight, false); +} diff --git a/src/sinfo/sinfo.h b/src/sinfo/sinfo.h index a94992ae8bf56bb447d91abde192bfe882ad1753..33da21faf05b859302b787d6caa7230152acb69c 100644 --- a/src/sinfo/sinfo.h +++ b/src/sinfo/sinfo.h @@ -57,12 +57,11 @@ #define MIN(x,y) (((x)<(y))?(x):(y)) struct sinfo_parameters { - bool partition_flag; char* partition; bool state_flag; enum node_states state; bool node_flag; - char* node; + char* nodes; bool summarize; bool long_output; bool line_wrap; @@ -75,12 +74,6 @@ struct node_state_summary { hostlist_t nodes; enum node_states state; uint32_t node_count; - uint32_t cpu_min; - uint32_t cpu_max; - uint32_t ram_min; - uint32_t ram_max; - uint32_t disk_min; - uint32_t disk_max; }; struct partition_summary {