1    	/*
2    	 * Copyright (c) 1995-2001 Silicon Graphics, Inc.  All Rights Reserved.
3    	 * 
4    	 * This program is free software; you can redistribute it and/or modify it
5    	 * under the terms of the GNU General Public License as published by the
6    	 * Free Software Foundation; either version 2 of the License, or (at your
7    	 * option) any later version.
8    	 * 
9    	 * This program 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 General Public License
12   	 * for more details.
13   	 * 
14   	 * You should have received a copy of the GNU General Public License along
15   	 * with this program; if not, write to the Free Software Foundation, Inc.,
16   	 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17   	 */
18   	
19   	#include "logger.h"
20   	
21   	char *chk_emess[] = {
22   	    "No error",
23   	    "Request for (advisory) ON conflicts with current (mandatory) ON state",
24   	    "Request for (advisory) OFF conflicts with current (mandatory) ON state",
25   	    "Request for (advisory) ON conflicts with current (mandatory) OFF state",
26   	    "Request for (advisory) OFF conflicts with current (mandatory) OFF state",
27   	};
28   	
29   	static void
30   	undo(task_t *tp, optreq_t *rqp, int inst)
31   	{
32   	    int 	j;
33   	    int		k;
34   	
At conditional (1): "rqp->r_numinst >= 1": Taking true branch.
35   	    if (rqp->r_numinst >= 1) {
36   		/* remove instance from list of instance */
At conditional (2): "j < rqp->r_numinst": Taking true branch.
At conditional (4): "j < rqp->r_numinst": Taking true branch.
At conditional (6): "j < rqp->r_numinst": Taking false branch.
37   		for (k =0, j = 0; j < rqp->r_numinst; j++) {
At conditional (3): "rqp->r_instlist[j] != inst": Taking true branch.
At conditional (5): "rqp->r_instlist[j] != inst": Taking true branch.
38   		    if (rqp->r_instlist[j] != inst)
39   			rqp->r_instlist[k++] = rqp->r_instlist[j];
40   		}
41   		rqp->r_numinst = k;
Event check_return: Calling function "__pmOptFetchDel" without checking return value (as is done elsewhere 6 out of 7 times).
Event unchecked_value: No check of the return value of "__pmOptFetchDel(&tp->t_fetch, rqp)".
Also see events: [example_checked][example_checked][example_checked][example_checked][example_checked]
42   		__pmOptFetchDel(&tp->t_fetch, rqp);
43   	
44   		if (rqp->r_numinst == 0) {
45   		    /* no more instances, remove specification */
46   		    if (tp->t_fetch == NULL) {
47   			/* no more specifications, remove task */
48   			task_t	*xtp;
49   			task_t	*ltp = NULL;
50   			for (xtp = tasklist; xtp != NULL; xtp = xtp->t_next) {
51   			    if (xtp == tp) {
52   				if (ltp == NULL)
53   				    tasklist = tp->t_next;
54   				else
55   				    ltp->t_next = tp->t_next;
56   				break;
57   			    }
58   			    ltp = xtp;
59   			}
60   		    }
61   		    __pmHashDel(rqp->r_desc->pmid, (void *)rqp, &pm_hash);
62   		    free(rqp);
63   		}
64   		else
65   		    /* re-insert modified specification */
66   		    __pmOptFetchAdd(&tp->t_fetch, rqp);
67   	    }
68   	    else {
69   		/*
70   		 * TODO ... current specification is for all instances,
71   		 * need to remove this instance from the set ...
72   		 * this requires some enhancement to optFetch
73   		 *
74   		 * pro tem, this metric-instance pair may continue to get
75   		 * logged, even though the logging state is recorded as
76   		 * OFF (this is the worst thing that can happen here)
77   		 */
78   	    }
79   	}
80   	
81   	int
82   	chk_one(task_t *tp, pmID pmid, int inst)
83   	{
84   	    optreq_t	*rqp;
85   	    task_t	*ctp;
86   	
87   	    rqp = findoptreq(pmid, inst);
88   	    if (rqp == NULL)
89   		return 0;
90   	
91   	    ctp = rqp->r_fetch->f_aux;
92   	    if (ctp == NULL)
93   		/*
94   		 * can only happen if same metric+inst appears more than once
95   		 * in the same group ... this can never be a conflict
96   		 */
97   		return 0;
98   	
99   	    if (PMLC_GET_MAND(ctp->t_state)) {
100  		if (PMLC_GET_ON(ctp->t_state)) {
101  		    if (PMLC_GET_MAND(tp->t_state) == 0 && PMLC_GET_MAYBE(tp->t_state) == 0) {
102  			if (PMLC_GET_ON(tp->t_state))
103  			    return -1;
104  			else
105  			    return -2;
106  		    }
107  		}
108  		else {
109  		    if (PMLC_GET_MAND(tp->t_state) == 0 && PMLC_GET_MAYBE(tp->t_state) == 0) {
110  			if (PMLC_GET_ON(tp->t_state))
111  			    return -3;
112  			else
113  			    return -4;
114  		    }
115  		}
116  		/*
117  		 * new mandatory, over-rides the old mandatory
118  		 */
119  		undo(ctp, rqp, inst);
120  	    }
121  	    else {
122  		/*
123  		 * new anything, over-rides the old advisory
124  		 */
125  		undo(ctp, rqp, inst);
126  	    }
127  	
128  	    return 0;
129  	}
130  	
131  	int
132  	chk_all(task_t *tp, pmID pmid)
133  	{
134  	    optreq_t	*rqp;
135  	    task_t	*ctp;
136  	
137  	    rqp = findoptreq(pmid, 0);	/*TODO, not right!*/
138  	    if (rqp == NULL)
139  		return 0;
140  	
141  	    ctp = rqp->r_fetch->f_aux;
142  	
143  	#ifdef PCP_DEBUG
144  	    if (pmDebug & DBG_TRACE_LOG) {
145  		fprintf(stderr, "chk_all: pmid=%s task=" PRINTF_P_PFX "%p state=%s%s%s%s delta=%d.%06d\n",
146  			pmIDStr(pmid), tp,
147  			PMLC_GET_INLOG(tp->t_state) ? " " : "N",
148  			PMLC_GET_AVAIL(tp->t_state) ? " " : "N",
149  			PMLC_GET_MAND(tp->t_state) ? "M" : "A",
150  			PMLC_GET_ON(tp->t_state) ? "Y" : "N",
151  			(int)tp->t_delta.tv_sec, (int)tp->t_delta.tv_usec);
152  		fprintf(stderr, "compared to: optreq task=" PRINTF_P_PFX "%p state=%s%s%s%s delta=%d.%06d\n",
153  			ctp,
154  			PMLC_GET_INLOG(ctp->t_state) ? " " : "N",
155  			PMLC_GET_AVAIL(ctp->t_state) ? " " : "N",
156  			PMLC_GET_MAND(ctp->t_state) ? "M" : "A",
157  			PMLC_GET_ON(ctp->t_state) ? "Y" : "N",
158  			(int)ctp->t_delta.tv_sec, (int)ctp->t_delta.tv_usec);
159  	    }
160  	#endif
161  	    return 0;
162  	}
163