1 /*
2 * Copyright (c) 1995-2002 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This library is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
12 * License for more details.
13 */
14
15 #include "pmapi.h"
16 #include "impl.h"
17
18 static int *
19 _subtract(int *list, int *list_len, int *arg, int arg_len)
20 {
21 int *new;
22 int len = *list_len;
23 int new_len = 0;
24 int i, j;
25
26 if (list == NULL)
27 /* noop */
28 return NULL;
29
30 new = (int *)malloc(len * sizeof(int));
31 if (new == NULL)
32 return NULL;
33
34 for (i=0; i < len; i++) {
35 for (j=0; j < arg_len; j++)
36 if (list[i] == arg[j])
37 break;
38 if (j == arg_len)
39 /* this instance survived */
40 new[new_len++] = list[i];
41 }
42 free(list);
43 *list_len = new_len;
44 return new;
45 }
46
47 static int *
48 _union(int *list, int *list_len, int *arg, int arg_len)
49 {
50 int *new;
51 int len = *list_len;
52 int new_len = *list_len;
53 int i, j;
54
55 if (list == NULL) {
56 list = (int *)malloc(arg_len * sizeof(int));
57 memcpy((void *)list, (void *)arg, arg_len * sizeof(int));
58 *list_len = arg_len;
59 return list;
60 }
61
62 new = (int *)realloc((void *)list, (len + arg_len) * sizeof(int));
63 if (new == NULL)
64 return NULL;
65
66 for (i=0; i < arg_len; i++) {
67 for (j=0; j < new_len; j++) {
68 if (arg[i] == new[j])
69 break;
70 }
71 if (j == new_len)
72 /* instance is not already in the list */
73 new[new_len++] = arg[i];
74 }
75 *list_len = new_len;
76 return new;
77 }
78
79 static void
80 _setGlobalState(__pmContext *ctxp, int state)
81 {
82 __pmInDomProfile *p, *p_end;
83
84 /* free everything and set the global state */
85 if (ctxp->c_instprof->profile) {
86 for (p=ctxp->c_instprof->profile, p_end = p + ctxp->c_instprof->profile_len;
87 p < p_end; p++) {
88 if (p->instances)
89 free(p->instances);
90 p->instances_len = 0;
91 }
92
93 free(ctxp->c_instprof->profile);
94 ctxp->c_instprof->profile = NULL;
95 ctxp->c_instprof->profile_len = 0;
96 }
97
98 ctxp->c_instprof->state = state;
99 ctxp->c_sent = 0;
100 }
101
102 static __pmInDomProfile *
103 _newprof(pmInDom indom, __pmContext *ctxp)
104 {
105 __pmInDomProfile *p;
106
107 if (ctxp->c_instprof->profile == NULL) {
108 /* create a new profile for this inDom in the default state */
109 p = ctxp->c_instprof->profile = (__pmInDomProfile *)malloc(
110 sizeof(__pmInDomProfile));
111 if (p == NULL)
112 /* fail, no changes */
113 return NULL;
114 ctxp->c_instprof->profile_len = 1;
115 }
116 else {
117 /* append a new profile to the end of the list */
118 ctxp->c_instprof->profile_len++;
119 p = (__pmInDomProfile *)realloc((void *)ctxp->c_instprof->profile,
120 ctxp->c_instprof->profile_len * sizeof(__pmInDomProfile));
121 if (p == NULL)
122 /* fail, no changes */
123 return NULL;
124 ctxp->c_instprof->profile = p;
125 p = ctxp->c_instprof->profile + ctxp->c_instprof->profile_len - 1;
126 }
127
128 /* initialise a new profile entry : default = include all instances */
129 p->indom = indom;
130 p->instances = NULL;
131 p->instances_len = 0;
132 p->state = PM_PROFILE_INCLUDE;
133 return p;
134 }
135
136 __pmInDomProfile *
137 __pmFindProfile(pmInDom indom, const __pmProfile *prof)
138 {
139 __pmInDomProfile *p, *p_end;
140
141 if (prof != NULL && prof->profile_len > 0)
142 /* search for the profile entry for this instance domain */
143 for (p=prof->profile, p_end=p+prof->profile_len; p < p_end; p++) {
144 if (p->indom == indom)
145 /* found : an entry for this instance domain already exists */
146 return p;
147 }
148
149 /* not found */
150 return NULL;
151 }
152
153 int
154 __pmInProfile(pmInDom indom, const __pmProfile *prof, int inst)
155 {
156 __pmInDomProfile *p;
157 int *in, *in_end;
158
159 if (prof == NULL)
160 /* default if no profile for any instance domains */
161 return 1;
162
163 if ((p = __pmFindProfile(indom, prof)) == NULL)
164 /* no profile for this indom => use global default */
165 return (prof->state == PM_PROFILE_INCLUDE) ? 1 : 0;
166
167 for (in=p->instances, in_end=in+p->instances_len; in < in_end; in++)
168 if (*in == inst)
169 /* present in the list => inverse of default for this indom */
170 return (p->state == PM_PROFILE_INCLUDE) ? 0 : 1;
171
172 /* not in the list => use default for this indom */
173 return (p->state == PM_PROFILE_INCLUDE) ? 1 : 0;
174 }
175
176 void
177 __pmFreeProfile(__pmProfile *prof)
178 {
179 __pmInDomProfile *p, *p_end;
180
181 if (prof != NULL) {
182 if (prof->profile != NULL) {
183 for (p=prof->profile, p_end = p+prof->profile_len; p < p_end; p++) {
184 if (p->instances)
185 free(p->instances);
186 }
187 if (prof->profile_len)
188 free(prof->profile);
189 }
190 free(prof);
191 }
192 }
193
194 int
195 pmAddProfile(pmInDom indom, int instlist_len, int instlist[])
196 {
197 int sts;
198 __pmContext *ctxp;
199 __pmInDomProfile *prof;
200
201 if (indom == PM_INDOM_NULL && instlist != NULL)
202 /* semantic disconnect! */
203 return PM_ERR_PROFILESPEC;
204
205 if ((sts = pmWhichContext()) < 0)
206 return sts;
207
208 ctxp = __pmHandleToPtr(sts);
209 if (indom == PM_INDOM_NULL && (instlist == NULL || instlist_len == 0)) {
210 _setGlobalState(ctxp, PM_PROFILE_INCLUDE);
211 goto SUCCESS;
212 }
213
214 if ((prof = __pmFindProfile(indom, ctxp->c_instprof)) == NULL) {
215 if ((prof = _newprof(indom, ctxp)) == NULL) {
216 /* fail */
217 return -oserror();
218 }
219 else {
220 /* starting state: exclude all except the supplied list */
221 prof->state = PM_PROFILE_EXCLUDE;
222 }
223 }
224
225 /* include all instances? */
226 if (instlist_len == 0 || instlist == NULL) {
227 /* include all instances in this domain */
228 if (prof->instances)
229 free(prof->instances);
230 prof->instances = NULL;
231 prof->instances_len = 0;
232 prof->state = PM_PROFILE_INCLUDE;
233 goto SUCCESS;
234 }
235
236 switch (prof->state) {
237 case PM_PROFILE_INCLUDE:
238 /*
239 * prof->instances is an exclusion list (all else included)
240 * => traverse and remove the specified instances (if present)
241 */
242 prof->instances = _subtract(
243 prof->instances, &prof->instances_len,
244 instlist, instlist_len);
245 break;
246
247 case PM_PROFILE_EXCLUDE:
248 /*
249 * prof->instances is an inclusion list (all else excluded)
250 * => traverse and add the specified instances (if not already present)
251 */
252 prof->instances = _union(
253 prof->instances, &prof->instances_len,
254 instlist, instlist_len);
255 break;
256 }
257
258 SUCCESS:
259 ctxp->c_sent = 0;
260 #ifdef PCP_DEBUG
261 if (pmDebug & DBG_TRACE_PROFILE) {
262 fprintf(stderr, "pmAddProfile() indom: %s\n", pmInDomStr(indom));
263 __pmDumpProfile(stderr, indom, ctxp->c_instprof);
264 }
265 #endif
266 return 0;
267 }
268
269 int
270 pmDelProfile(pmInDom indom, int instlist_len, int instlist[])
271 {
272 int sts;
273 __pmContext *ctxp;
274 __pmInDomProfile *prof;
275
|
Event const: |
After this line, the value of "instlist" is equal to 0. |
|
Event new_values: |
Noticing condition "instlist != NULL". |
| Also see events: |
[dead_error_condition][dead_error_line] |
276 if (indom == PM_INDOM_NULL && instlist != NULL)
277 /* semantic disconnect! */
278 return PM_ERR_PROFILESPEC;
279
280 if ((sts = pmWhichContext()) < 0)
281 return sts;
282
283 ctxp = __pmHandleToPtr(sts);
|
Event dead_error_condition: |
On this path, the condition "instlist == NULL" cannot be false. |
|
Event dead_error_line: |
Execution cannot reach this expression "instlist_len == 0" inside statement "if (indom == 4294967295U &&...". |
| Also see events: |
[const][new_values] |
284 if (indom == PM_INDOM_NULL && (instlist == NULL || instlist_len == 0)) {
285 _setGlobalState(ctxp, PM_PROFILE_EXCLUDE);
286 goto SUCCESS;
287 }
288
289 if ((prof = __pmFindProfile(indom, ctxp->c_instprof)) == NULL) {
290 if ((prof = _newprof(indom, ctxp)) == NULL) {
291 /* fail */
292 return -oserror();
293 }
294 else {
295 /* starting state: include all except the supplied list */
296 prof->state = PM_PROFILE_EXCLUDE;
297 }
298 }
299
300 /* include all instances? */
301 if (instlist_len == 0 || instlist == NULL) {
302 /* include all instances in this domain */
303 if (prof->instances)
304 free(prof->instances);
305 prof->instances = NULL;
306 prof->instances_len = 0;
307 prof->state = PM_PROFILE_EXCLUDE;
308 goto SUCCESS;
309 }
310
311 switch (prof->state) {
312 case PM_PROFILE_INCLUDE:
313 /*
314 * prof->instances is an exclusion list (all else included)
315 * => traverse and add the specified instances (if not already present)
316 */
317 prof->instances = _union(
318 prof->instances, &prof->instances_len,
319 instlist, instlist_len);
320 break;
321
322 case PM_PROFILE_EXCLUDE:
323 /*
324 * prof->instances is an inclusion list (all else excluded)
325 * => traverse and remove the specified instances (if present)
326 */
327 prof->instances = _subtract(
328 prof->instances, &prof->instances_len,
329 instlist, instlist_len);
330 break;
331 }
332
333 SUCCESS:
334 ctxp->c_sent = 0;
335 #ifdef PCP_DEBUG
336 if (pmDebug & DBG_TRACE_PROFILE) {
337 fprintf(stderr, "pmDelProfile() indom: %s\n", pmInDomStr(indom));
338 __pmDumpProfile(stderr, indom, ctxp->c_instprof);
339 }
340 #endif
341 return 0;
342 }
343
344 void
345 __pmDumpProfile(FILE *f, int indom, const __pmProfile *pp)
346 {
347 int j;
348 int k;
349 __pmInDomProfile *prof;
350
351 fprintf(f, "Dump Instance Profile state=%s, %d profiles",
352 pp->state == PM_PROFILE_INCLUDE ? "INCLUDE" : "EXCLUDE",
353 pp->profile_len);
354 if (indom != PM_INDOM_NULL)
355 fprintf(f, ", dump restricted to indom=%d [%s]",
356 indom, pmInDomStr(indom));
357 fprintf(f, "\n");
358
359 for (prof=pp->profile, j=0; j < pp->profile_len; j++, prof++) {
360 if (indom != PM_INDOM_NULL && indom != prof->indom)
361 continue;
362 fprintf(f, "\tProfile [%d] indom=%d [%s] state=%s %d instances\n",
363 j, prof->indom, pmInDomStr(prof->indom),
364 (prof->state == PM_PROFILE_INCLUDE) ? "INCLUDE" : "EXCLUDE",
365 prof->instances_len);
366
367 if (prof->instances_len) {
368 fprintf(f, "\t\tInstances:");
369 for (k=0; k < prof->instances_len; k++)
370 fprintf(f, " [%d]", prof->instances[k]);
371 fprintf(f, "\n");
372 }
373 }
374 }