Annotation of embedaddon/bmon/src/group.c, revision 1.1.1.2
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:
1.1.1.2 ! misho 264: group_new_hdr(DEFAULT_GROUP, "Interfaces",
1.1 misho 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>