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>