Annotation of embedaddon/bmon/src/group.c, revision 1.1
1.1 ! misho 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("intf", "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>