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