File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bmon / src / group.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 14:58:35 2019 UTC (4 years, 8 months ago) by misho
Branches: bmon, MAIN
CVS tags: v4_0p0, HEAD
bmon ver 4.0

    1: /*
    2:  * group.c		Group Management
    3:  *
    4:  * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch>
    5:  * Copyright (c) 2013 Red Hat, Inc.
    6:  *
    7:  * Permission is hereby granted, free of charge, to any person obtaining a
    8:  * copy of this software and associated documentation files (the "Software"),
    9:  * to deal in the Software without restriction, including without limitation
   10:  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   11:  * and/or sell copies of the Software, and to permit persons to whom the
   12:  * Software is furnished to do so, subject to the following conditions:
   13:  *
   14:  * The above copyright notice and this permission notice shall be included
   15:  * in all copies or substantial portions of the Software.
   16:  *
   17:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   18:  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   20:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   22:  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   23:  * DEALINGS IN THE SOFTWARE.
   24:  */
   25: 
   26: #include <bmon/bmon.h>
   27: #include <bmon/element.h>
   28: #include <bmon/group.h>
   29: #include <bmon/utils.h>
   30: 
   31: static LIST_HEAD(titles_list);
   32: static LIST_HEAD(group_list);
   33: static unsigned int ngroups;
   34: static struct element_group *current_group;
   35: 
   36: static void __group_foreach_element(struct element_group *g,
   37: 				    struct list_head *list,
   38: 				    void (*cb)(struct element_group *,
   39: 				    	       struct element *, void *),
   40: 				    void *arg)
   41: {
   42: 	struct element *e, *n;
   43: 
   44: 	list_for_each_entry_safe(e, n, list, e_list) {
   45: 		cb(g, e, arg);
   46: 
   47: 		if (!list_empty(&e->e_childs))
   48: 			__group_foreach_element(g, &e->e_childs, cb, arg);
   49: 	}
   50: }
   51: 
   52: void group_foreach_element(struct element_group *g,
   53: 			   void (*cb)(struct element_group *,
   54: 				      struct element *, void *),
   55: 			   void *arg)
   56: {
   57: 	__group_foreach_element(g, &g->g_elements, cb, arg);
   58: }
   59: 
   60: void group_foreach_recursive(void (*cb)(struct element_group *,
   61: 					struct element *, void *),
   62: 			     void *arg)
   63: {
   64: 	struct element_group *g, *n;
   65: 
   66: 	list_for_each_entry_safe(g, n, &group_list, g_list)
   67: 		__group_foreach_element(g, &g->g_elements, cb, arg);
   68: }
   69: 
   70: void group_foreach(void (*cb)(struct element_group *, void *), void *arg)
   71: {
   72: 	struct element_group *g, *n;
   73: 
   74: 	list_for_each_entry_safe(g, n, &group_list, g_list)
   75: 		cb(g, arg);
   76: }
   77: 
   78: struct element_group *group_select_first(void)
   79: {
   80: 	if (list_empty(&group_list))
   81: 		current_group = NULL;
   82: 	else
   83: 		current_group = list_first_entry(&group_list,
   84: 						 struct element_group, g_list);
   85: 
   86: 	return current_group;
   87: }
   88: 
   89: struct element_group *group_select_last(void)
   90: {
   91: 	if (list_empty(&group_list))
   92: 		current_group = NULL;
   93: 	else
   94: 		current_group = list_entry(group_list.prev,
   95: 					   struct element_group, g_list);
   96: 
   97: 	return current_group;
   98: }
   99: 
  100: struct element_group *group_select_next(void)
  101: {
  102: 	if (!current_group)
  103: 		return group_select_first();
  104: 
  105: 	if (current_group->g_list.next != &group_list)
  106: 		current_group = list_entry(current_group->g_list.next,
  107: 					   struct element_group,
  108: 					   g_list);
  109: 	else
  110: 		return group_select_first();
  111: 
  112: 	return current_group;
  113: }
  114: 
  115: struct element_group *group_select_prev(void)
  116: {
  117: 	if (!current_group)
  118: 		return group_select_last();
  119: 
  120: 	if (current_group->g_list.prev != &group_list)
  121: 		current_group = list_entry(current_group->g_list.prev,
  122: 					   struct element_group,
  123: 					   g_list);
  124: 	else
  125: 		return group_select_last();
  126: 
  127: 	return current_group;
  128: }
  129: 
  130: struct element_group *group_current(void)
  131: {
  132: 	if (current_group == NULL)
  133: 		current_group = group_select_first();
  134: 
  135: 	return current_group;
  136: }
  137: 
  138: struct element_group *group_lookup(const char *name, int flags)
  139: {
  140: 	struct element_group *g;
  141: 	struct group_hdr *hdr;
  142: 
  143: 	list_for_each_entry(g, &group_list, g_list)
  144: 		if (!strcmp(name, g->g_name))
  145: 			return g;
  146: 
  147: 	if (!(flags & GROUP_CREATE))
  148: 		return NULL;
  149: 
  150: 	if (!(hdr = group_lookup_hdr(name))) {
  151: 		fprintf(stderr, "Cannot find title for group \"%s\"\n", name);
  152: 		return NULL;
  153: 	}
  154: 
  155: 	g = xcalloc(1, sizeof(*g));
  156: 
  157: 	init_list_head(&g->g_elements);
  158: 
  159: 	g->g_name = hdr->gh_name;
  160: 	g->g_hdr = hdr;
  161: 
  162: 	list_add_tail(&g->g_list, &group_list);
  163: 	ngroups++;
  164: 
  165: 	return g;
  166: }
  167: 
  168: static void group_free(struct element_group *g)
  169: {
  170: 	struct element *e, *n;
  171: 	struct element_group *next;
  172: 
  173: 	if (current_group == g) {
  174: 		next = group_select_next();
  175: 		if (!next || next == g)
  176: 			current_group = NULL;
  177: 	}
  178: 
  179: 	list_for_each_entry_safe(e, n, &g->g_elements, e_list)
  180: 		element_free(e);
  181: 
  182: 	xfree(g);
  183: }
  184: 
  185: void reset_update_flags(void)
  186: {
  187: 	group_foreach_recursive(&element_reset_update_flag, NULL);
  188: }
  189: 
  190: void free_unused_elements(void)
  191: {
  192: 	group_foreach_recursive(&element_check_if_dead, NULL);
  193: }
  194: 
  195: struct group_hdr *group_lookup_hdr(const char *name)
  196: {
  197: 	struct group_hdr *hdr;
  198: 
  199: 	list_for_each_entry(hdr, &titles_list, gh_list)
  200: 		if (!strcmp(hdr->gh_name, name))
  201: 		    return hdr;
  202: 
  203: 	return NULL;
  204: }
  205: 
  206: int group_new_hdr(const char *name, const char *title,
  207: 		  const char *col1, const char *col2,
  208: 		  const char *col3, const char *col4)
  209: {
  210: 	struct group_hdr *hdr;
  211: 
  212: 	if (group_lookup_hdr(name))
  213: 		return -EEXIST;
  214: 
  215: 	hdr = xcalloc(1, sizeof(*hdr));
  216: 
  217: 	init_list_head(&hdr->gh_list);
  218: 
  219: 	hdr->gh_name = strdup(name);
  220: 	hdr->gh_title = strdup(title);
  221: 
  222: 	hdr->gh_column[0] = strdup(col1);
  223: 	hdr->gh_column[1] = strdup(col2);
  224: 	hdr->gh_column[2] = strdup(col3);
  225: 	hdr->gh_column[3] = strdup(col4);
  226: 
  227: 	list_add_tail(&hdr->gh_list, &titles_list);
  228: 
  229: 	DBG("New group title %s \"%s\"", name, title);
  230: 
  231: 	return 0;
  232: }
  233: 
  234: int group_new_derived_hdr(const char *name, const char *title,
  235: 			  const char *template)
  236: {
  237: 	struct group_hdr *t;
  238: 
  239: 	if (group_lookup_hdr(name))
  240: 		return -EEXIST;
  241: 
  242: 	if (!(t = group_lookup_hdr(template)))
  243: 		return -ENOENT;
  244: 
  245: 	return group_new_hdr(name, title, t->gh_column[0], t->gh_column[1],
  246: 			     t->gh_column[2], t->gh_column[3]);
  247: }
  248: 
  249: static void  group_hdr_free(struct group_hdr *hdr)
  250: {
  251: 	xfree(hdr->gh_name);
  252: 	xfree(hdr->gh_title);
  253: 	xfree(hdr->gh_column[0]);
  254: 	xfree(hdr->gh_column[1]);
  255: 	xfree(hdr->gh_column[2]);
  256: 	xfree(hdr->gh_column[3]);
  257: 	xfree(hdr);
  258: }
  259: 
  260: static void __init group_init(void)
  261: {
  262: 	DBG("init");
  263: 
  264: 	group_new_hdr(DEFAULT_GROUP, "Interfaces",
  265: 		      "RX bps", "pps", "TX bps", "pps");
  266: }
  267: 
  268: static void __exit group_exit(void)
  269: {
  270: 	struct element_group *g, *next;
  271: 	struct group_hdr *hdr, *gnext;
  272: 
  273: 	list_for_each_entry_safe(g, next, &group_list, g_list)
  274: 		group_free(g);
  275: 
  276: 	list_for_each_entry_safe(hdr, gnext, &titles_list, gh_list)
  277: 		group_hdr_free(hdr);
  278: }

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