File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / node.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:19:56 2012 UTC (12 years, 7 months ago) by misho
Branches: bmon, MAIN
CVS tags: v2_1_0p0, v2_1_0, HEAD
bmon

    1: /*
    2:  * node.c            node handling
    3:  *
    4:  * Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch>
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a
    7:  * copy of this software and associated documentation files (the "Software"),
    8:  * to deal in the Software without restriction, including without limitation
    9:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   10:  * and/or sell copies of the Software, and to permit persons to whom the
   11:  * Software is furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included
   14:  * in all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   17:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   21:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   22:  * DEALINGS IN THE SOFTWARE.
   23:  */
   24: 
   25: #include <bmon/bmon.h>
   26: #include <bmon/node.h>
   27: #include <bmon/item.h>
   28: #include <bmon/utils.h>
   29: 
   30: static node_t *nodes;
   31: static size_t nodes_size;
   32: static size_t nnodes;
   33: static const char * node_name;
   34: static node_t *local_node;
   35: static node_t *current_node;
   36: 
   37: 
   38: node_t * lookup_node(const char *name, int creat)
   39: {
   40: 	int i;
   41: 
   42: 	if (NULL == nodes) {
   43: 		nodes_size = 32;
   44: 		nodes = xcalloc(nodes_size, sizeof(node_t));
   45: 	}
   46: 
   47: 	for (i = 0; i < nodes_size; i++)
   48: 		if (nodes[i].n_name && !strcmp(name, nodes[i].n_name))
   49: 			return &nodes[i];
   50: 
   51: 	if (creat) {
   52: 		for (i = 0; i < nodes_size; i++)
   53: 			if (NULL == nodes[i].n_name)
   54: 				break;
   55: 
   56: 		while (i >= nodes_size) {
   57: 			int oldsize = nodes_size;
   58: 			nodes_size += 32;
   59: 			nodes = xrealloc(nodes, nodes_size * sizeof(node_t));
   60: 			memset((uint8_t *) nodes + oldsize, 0, (nodes_size - oldsize) * sizeof(node_t));
   61: 		}
   62: 
   63: 		nodes[i].n_name = strdup(name);
   64: 		nodes[i].n_index = i;
   65: 		nnodes++;
   66: 		return &nodes[i];
   67: 	}
   68: 
   69: 	return NULL;
   70: }
   71: 
   72: void foreach_node(void (*cb)(node_t *, void *), void *arg)
   73: {
   74: 	int i;
   75: 
   76: 	for (i = 0; i < nnodes; i++)
   77: 		cb(&nodes[i], arg);
   78: }
   79: 
   80: void foreach_item(node_t *n, void (*cb)(item_t *, void *), void *arg)
   81: {
   82: 	int i;
   83: 
   84: 	for (i = 0; i < n->n_nitems; i++)
   85: 		if (n->n_items[i].i_name[0])
   86: 			cb(&n->n_items[i], arg);
   87: }
   88: 
   89: 
   90: void foreach_node_item(void (*cb)(node_t *, item_t *, void *), void *arg)
   91: {
   92: 	int i, m;
   93: 
   94: 	for (i = 0; i < nnodes; i++) {
   95: 		node_t *n = &nodes[i];
   96: 		
   97: 		for (m = 0; m < n->n_nitems; m++)
   98: 			if (n->n_items[m].i_name[0])
   99: 				cb(n, &n->n_items[m], arg);
  100: 	}
  101: }
  102: 
  103: 
  104: static void __reset_item(node_t *n, item_t *i, void *arg)
  105: {
  106: 	reset_item(i);
  107: }
  108: 
  109: void reset_nodes(void)
  110: {
  111: 	foreach_node_item(__reset_item, NULL);
  112: }
  113: 
  114: static void __remove_unused_item(node_t *n, item_t *i, void *arg)
  115: {
  116: 	remove_unused_items(i);
  117: }
  118: 
  119: void remove_unused_node_items(void)
  120: {
  121: 	foreach_node_item(__remove_unused_item, NULL);
  122: }
  123: 
  124: 
  125: 
  126: node_t * get_local_node(void)
  127: {
  128: 	if (NULL == local_node)
  129: 		local_node = lookup_node(node_name, 1);
  130: 
  131: 	return local_node;
  132: }
  133: 
  134: int get_nnodes(void)
  135: {
  136: 	return nnodes;
  137: }
  138: 
  139: static void get_node_info(void)
  140: {
  141: 	struct utsname uts;
  142: 	
  143: 	if (uname(&uts) < 0)
  144: 		quit("utsname failed: %s\n", strerror(errno));
  145: 	
  146: 	node_name = strdup(uts.nodename);
  147: }
  148: 
  149: void calc_node_rate(node_t *node)
  150: {
  151: 	int i;
  152: 
  153: 	node->n_rx_maj_total = 0;
  154: 	node->n_tx_maj_total = 0;
  155: 	node->n_rx_min_total = 0;
  156: 	node->n_tx_min_total = 0;
  157: 
  158: 	for (i = 0; i < node->n_nitems; i++) {
  159: 		item_t *it = &node->n_items[i];
  160: 		if (it->i_name[0] &&
  161: 		    it->i_level == 0 &&
  162: 		    !(it->i_flags & ITEM_FLAG_EXCLUDE)) {
  163: 			stat_attr_t *maj = lookup_attr(it, it->i_major_attr);
  164: 			stat_attr_t *min = lookup_attr(it, it->i_minor_attr);
  165: 
  166: 			if (maj) {
  167: 				node->n_rx_maj_total += attr_get_rx_rate(maj);
  168: 				node->n_tx_maj_total += attr_get_tx_rate(maj);
  169: 			}
  170: 
  171: 			if (min) {
  172: 				node->n_rx_min_total += attr_get_rx_rate(min);
  173: 				node->n_tx_min_total += attr_get_tx_rate(min);
  174: 			}
  175: 			
  176: 		}
  177: 	}
  178: }
  179: 
  180: void calc_node_rates(void)
  181: {
  182: 	int i;
  183: 
  184: 	for (i = 0; i < nnodes; i++)
  185: 		calc_node_rate(&nodes[i]);
  186: }
  187: 
  188: node_t * get_current_node(void)
  189: {
  190: 	return current_node;
  191: }
  192: 
  193: int first_node(void)
  194: {
  195: 	int i;
  196: 
  197: 	if (nnodes <= 0)
  198: 		return EMPTY_LIST;
  199: 	
  200: 	for (i = 0; i < nnodes; i++) {
  201: 		if (nodes[i].n_name) {
  202: 			current_node = &nodes[i];
  203: 			return 0;
  204: 		}
  205: 	}
  206: 	
  207: 	return EMPTY_LIST;
  208: }
  209: 
  210: int last_node(void)
  211: {
  212: 	int i;
  213: 	
  214: 	if (nnodes <= 0)
  215: 		return EMPTY_LIST;
  216: 	
  217: 	for (i = (nnodes - 1); i >= 0; i--) {
  218: 		if (nodes[i].n_name) {
  219: 			current_node = &nodes[i];
  220: 			return 0;
  221: 		}
  222: 	}
  223: 	
  224: 	return EMPTY_LIST;
  225: }
  226: 	
  227: 
  228: int prev_node(void)
  229: {
  230: 	if (nnodes <= 0)
  231: 		return EMPTY_LIST;
  232: 	
  233: 	if (current_node == NULL)
  234: 		return first_node();
  235: 	else {
  236: 		int i;
  237: 		for (i = (current_node->n_index - 1); i >= 0; i--) {
  238: 			if (nodes[i].n_name) {
  239: 				current_node = &nodes[i];
  240: 				return 0;
  241: 			}
  242: 		}
  243: 		return END_OF_LIST;
  244: 	}
  245: 	
  246: 	return EMPTY_LIST;
  247: }
  248: 
  249: int next_node(void)
  250: {
  251: 	if (nnodes <= 0)
  252: 		return EMPTY_LIST;
  253: 	
  254: 	if (current_node == NULL)
  255: 		return first_node();
  256: 	else {
  257: 		int i;
  258: 		for (i = (current_node->n_index + 1); i < nnodes; i++) {
  259: 			if (nodes[i].n_name) {
  260: 				current_node = &nodes[i];
  261: 				return 0;
  262: 			}
  263: 		}
  264: 		return END_OF_LIST;
  265: 	}
  266: 	
  267: 	return EMPTY_LIST;
  268: }
  269: 
  270: item_t * get_current_item(void)
  271: {
  272: 	if (current_node) {
  273: 		if (current_node->n_selected < current_node->n_nitems &&
  274: 		    current_node->n_selected >= 0) {
  275: 			item_t *i = &(current_node->n_items[current_node->n_selected]);
  276: 
  277: 			if (i->i_name[0])
  278: 				return i;
  279: 		}
  280: 	}
  281: 	return NULL;
  282: }
  283: 
  284: int first_item(void)
  285: {
  286: 	int i;
  287: 	
  288: 	if (current_node == NULL)
  289: 		return EMPTY_LIST;
  290: 	
  291: 	if (current_node->n_nitems <= 0)
  292: 		return EMPTY_LIST;
  293: 	
  294: 	for (i = 0; i < current_node->n_nitems; i++) {
  295: 		if (current_node->n_items[i].i_name[0]) {
  296: 			current_node->n_selected = i;
  297: 			return 0;
  298: 		}
  299: 	}
  300: 	
  301: 	return EMPTY_LIST;
  302: }
  303: 
  304: int last_item(void)
  305: {
  306: 	int i;
  307: 	
  308: 	if (current_node == NULL)
  309: 		return EMPTY_LIST;
  310: 
  311: 	if (current_node->n_nitems <= 0)
  312: 		return EMPTY_LIST;
  313: 
  314: 	for (i = (current_node->n_nitems - 1); i >= 0; i--) {
  315: 		if (current_node->n_items[i].i_name[0]) {
  316: 			current_node->n_selected = i;
  317: 			return 0;
  318: 		}
  319: 	}
  320: 
  321: 	return EMPTY_LIST;
  322: }
  323: 
  324: int goto_item(int num)
  325: {
  326: 	if (current_node == NULL)
  327: 		return EMPTY_LIST;
  328: 
  329: 	if (current_node->n_nitems <= 0)
  330: 		return EMPTY_LIST;
  331: 
  332: 	if (num < current_node->n_nitems && num >= 0)
  333: 		if (current_node->n_items[num].i_name[0])
  334: 			current_node->n_selected = num;
  335: 
  336: 	return 0;
  337: }
  338: 
  339: int next_item(void)
  340: {
  341: 	if (current_node == NULL)
  342: 		return EMPTY_LIST;
  343: 
  344: 	if (current_node->n_nitems <= 0)
  345: 		return EMPTY_LIST;
  346: 
  347: 	if (current_node->n_selected < 0 ||
  348: 		current_node->n_selected >= current_node->n_nitems)
  349: 		return last_item();
  350: 	else {
  351: 		int i;
  352: 		node_t *cn = current_node;
  353: 
  354: 		for (i = (cn->n_selected + 1); i < cn->n_nitems; i++) {
  355: 			if (!cn->n_items[i].i_name[0])
  356: 				continue;
  357: 
  358: 			if (cn->n_items[i].i_flags & ITEM_FLAG_IS_CHILD) {
  359: 				item_t *fi = get_item(cn, cn->n_items[i].i_link);
  360: 
  361: 				if (fi->i_flags & ITEM_FLAG_FOLDED)
  362: 					continue;
  363: 			}
  364: 
  365: 			cn->n_selected = i;
  366: 			return 0;
  367: 		}
  368: 
  369: 		return END_OF_LIST;
  370: 	}
  371: 
  372: 	return EMPTY_LIST;
  373: }
  374: 
  375: int prev_item(void)
  376: {
  377: 	if (current_node == NULL)
  378: 		return EMPTY_LIST;
  379: 
  380: 	if (current_node->n_nitems <= 0)
  381: 		return EMPTY_LIST;
  382: 
  383: 	if (current_node->n_selected < 0 ||
  384: 		current_node->n_selected >= current_node->n_nitems)
  385: 		return first_item();
  386: 	else {
  387: 		int i;
  388: 		node_t *cn = current_node;
  389: 
  390: 		for (i = (cn->n_selected - 1); i >= 0; i--) {
  391: 			if (!cn->n_items[i].i_name[0])
  392: 				continue;
  393: 
  394: 			if (cn->n_items[i].i_flags & ITEM_FLAG_IS_CHILD) {
  395: 				item_t *fi = get_item(cn, cn->n_items[i].i_link);
  396: 
  397: 				if (fi->i_flags & ITEM_FLAG_FOLDED)
  398: 					continue;
  399: 			}
  400: 			
  401: 			cn->n_selected = i;
  402: 			return 0;
  403: 		}
  404: 
  405: 		return END_OF_LIST;
  406: 	}
  407: 
  408: 	return EMPTY_LIST;
  409: }
  410: 
  411: static void __init node_init(void)
  412: {
  413: 	get_node_info();
  414: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>