1*10946SSangeeta.Misra@Sun.COM /*
2*10946SSangeeta.Misra@Sun.COM * CDDL HEADER START
3*10946SSangeeta.Misra@Sun.COM *
4*10946SSangeeta.Misra@Sun.COM * The contents of this file are subject to the terms of the
5*10946SSangeeta.Misra@Sun.COM * Common Development and Distribution License (the "License").
6*10946SSangeeta.Misra@Sun.COM * You may not use this file except in compliance with the License.
7*10946SSangeeta.Misra@Sun.COM *
8*10946SSangeeta.Misra@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10946SSangeeta.Misra@Sun.COM * or http://www.opensolaris.org/os/licensing.
10*10946SSangeeta.Misra@Sun.COM * See the License for the specific language governing permissions
11*10946SSangeeta.Misra@Sun.COM * and limitations under the License.
12*10946SSangeeta.Misra@Sun.COM *
13*10946SSangeeta.Misra@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
14*10946SSangeeta.Misra@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10946SSangeeta.Misra@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
16*10946SSangeeta.Misra@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
17*10946SSangeeta.Misra@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
18*10946SSangeeta.Misra@Sun.COM *
19*10946SSangeeta.Misra@Sun.COM * CDDL HEADER END
20*10946SSangeeta.Misra@Sun.COM */
21*10946SSangeeta.Misra@Sun.COM
22*10946SSangeeta.Misra@Sun.COM /*
23*10946SSangeeta.Misra@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24*10946SSangeeta.Misra@Sun.COM * Use is subject to license terms.
25*10946SSangeeta.Misra@Sun.COM */
26*10946SSangeeta.Misra@Sun.COM
27*10946SSangeeta.Misra@Sun.COM #include <stdio.h>
28*10946SSangeeta.Misra@Sun.COM #include <unistd.h>
29*10946SSangeeta.Misra@Sun.COM #include <stdlib.h>
30*10946SSangeeta.Misra@Sun.COM #include <strings.h>
31*10946SSangeeta.Misra@Sun.COM #include <sys/types.h>
32*10946SSangeeta.Misra@Sun.COM #include <sys/socket.h>
33*10946SSangeeta.Misra@Sun.COM #include <sys/sysmacros.h>
34*10946SSangeeta.Misra@Sun.COM #include <sys/note.h>
35*10946SSangeeta.Misra@Sun.COM #include <fcntl.h>
36*10946SSangeeta.Misra@Sun.COM #include <errno.h>
37*10946SSangeeta.Misra@Sun.COM #include <assert.h>
38*10946SSangeeta.Misra@Sun.COM #include <libgen.h>
39*10946SSangeeta.Misra@Sun.COM #include <kstat.h>
40*10946SSangeeta.Misra@Sun.COM #include <ofmt.h>
41*10946SSangeeta.Misra@Sun.COM #include <libilb.h>
42*10946SSangeeta.Misra@Sun.COM #include "ilbadm.h"
43*10946SSangeeta.Misra@Sun.COM
44*10946SSangeeta.Misra@Sun.COM #define ILBST_TIMESTAMP_HEADER 0x01 /* a timestamp w. every header */
45*10946SSangeeta.Misra@Sun.COM #define ILBST_DELTA_INTERVAL 0x02 /* delta over specified interval */
46*10946SSangeeta.Misra@Sun.COM #define ILBST_ABS_NUMBERS 0x04 /* print absolute numbers, no d's */
47*10946SSangeeta.Misra@Sun.COM #define ILBST_ITEMIZE 0x08 /* itemize */
48*10946SSangeeta.Misra@Sun.COM #define ILBST_VERBOSE 0x10 /* verbose error info */
49*10946SSangeeta.Misra@Sun.COM
50*10946SSangeeta.Misra@Sun.COM #define ILBST_OLD_VALUES 0x20 /* for internal processing */
51*10946SSangeeta.Misra@Sun.COM #define ILBST_RULES_CHANGED 0x40
52*10946SSangeeta.Misra@Sun.COM
53*10946SSangeeta.Misra@Sun.COM typedef struct {
54*10946SSangeeta.Misra@Sun.COM char is_name[KSTAT_STRLEN];
55*10946SSangeeta.Misra@Sun.COM uint64_t is_value;
56*10946SSangeeta.Misra@Sun.COM } ilbst_stat_t;
57*10946SSangeeta.Misra@Sun.COM
58*10946SSangeeta.Misra@Sun.COM static ilbst_stat_t rulestats[] = {
59*10946SSangeeta.Misra@Sun.COM {"num_servers", 0},
60*10946SSangeeta.Misra@Sun.COM {"bytes_not_processed", 0},
61*10946SSangeeta.Misra@Sun.COM {"pkt_not_processed", 0},
62*10946SSangeeta.Misra@Sun.COM {"bytes_dropped", 0},
63*10946SSangeeta.Misra@Sun.COM {"pkt_dropped", 0},
64*10946SSangeeta.Misra@Sun.COM {"nomem_bytes_dropped", 0},
65*10946SSangeeta.Misra@Sun.COM {"nomem_pkt_dropped", 0},
66*10946SSangeeta.Misra@Sun.COM {"noport_bytes_dropped", 0},
67*10946SSangeeta.Misra@Sun.COM {"noport_pkt_dropped", 0},
68*10946SSangeeta.Misra@Sun.COM {"icmp_echo_processed", 0},
69*10946SSangeeta.Misra@Sun.COM {"icmp_dropped", 0},
70*10946SSangeeta.Misra@Sun.COM {"icmp_too_big_processed", 0},
71*10946SSangeeta.Misra@Sun.COM {"icmp_too_big_dropped", 0}
72*10946SSangeeta.Misra@Sun.COM };
73*10946SSangeeta.Misra@Sun.COM
74*10946SSangeeta.Misra@Sun.COM /* indices into array above, to avoid searching */
75*10946SSangeeta.Misra@Sun.COM #define RLSTA_NUM_SRV 0
76*10946SSangeeta.Misra@Sun.COM #define RLSTA_BYTES_U 1
77*10946SSangeeta.Misra@Sun.COM #define RLSTA_PKT_U 2
78*10946SSangeeta.Misra@Sun.COM #define RLSTA_BYTES_D 3
79*10946SSangeeta.Misra@Sun.COM #define RLSTA_PKT_D 4
80*10946SSangeeta.Misra@Sun.COM #define RLSTA_NOMEMBYTES_D 5
81*10946SSangeeta.Misra@Sun.COM #define RLSTA_NOMEMPKT_D 6
82*10946SSangeeta.Misra@Sun.COM #define RLSTA_NOPORTBYTES_D 7
83*10946SSangeeta.Misra@Sun.COM #define RLSTA_NOPORTPKT_D 8
84*10946SSangeeta.Misra@Sun.COM #define RLSTA_ICMP_P 9
85*10946SSangeeta.Misra@Sun.COM #define RLSTA_ICMP_D 10
86*10946SSangeeta.Misra@Sun.COM #define RLSTA_ICMP2BIG_P 11
87*10946SSangeeta.Misra@Sun.COM #define RLSTA_ICMP2BIG_D 12
88*10946SSangeeta.Misra@Sun.COM
89*10946SSangeeta.Misra@Sun.COM static ilbst_stat_t servstats[] = {
90*10946SSangeeta.Misra@Sun.COM {"bytes_processed", 0},
91*10946SSangeeta.Misra@Sun.COM {"pkt_processed", 0}
92*10946SSangeeta.Misra@Sun.COM };
93*10946SSangeeta.Misra@Sun.COM /* indices into array above, to avoid searching */
94*10946SSangeeta.Misra@Sun.COM #define SRVST_BYTES_P 0
95*10946SSangeeta.Misra@Sun.COM #define SRVST_PKT_P 1
96*10946SSangeeta.Misra@Sun.COM
97*10946SSangeeta.Misra@Sun.COM /* values used for of_* commands as id */
98*10946SSangeeta.Misra@Sun.COM #define ILBST_PKT_P 0
99*10946SSangeeta.Misra@Sun.COM #define ILBST_BYTES_P 1
100*10946SSangeeta.Misra@Sun.COM #define ILBST_PKT_U 2
101*10946SSangeeta.Misra@Sun.COM #define ILBST_BYTES_U 3
102*10946SSangeeta.Misra@Sun.COM #define ILBST_PKT_D 4
103*10946SSangeeta.Misra@Sun.COM #define ILBST_BYTES_D 5
104*10946SSangeeta.Misra@Sun.COM #define ILBST_ICMP_P 6
105*10946SSangeeta.Misra@Sun.COM #define ILBST_ICMP_D 7
106*10946SSangeeta.Misra@Sun.COM #define ILBST_ICMP2BIG_P 8
107*10946SSangeeta.Misra@Sun.COM #define ILBST_ICMP2BIG_D 9
108*10946SSangeeta.Misra@Sun.COM #define ILBST_NOMEMP_D 10
109*10946SSangeeta.Misra@Sun.COM #define ILBST_NOPORTP_D 11
110*10946SSangeeta.Misra@Sun.COM #define ILBST_NOMEMB_D 12
111*10946SSangeeta.Misra@Sun.COM #define ILBST_NOPORTB_D 13
112*10946SSangeeta.Misra@Sun.COM
113*10946SSangeeta.Misra@Sun.COM #define ILBST_ITEMIZE_SNAME 97
114*10946SSangeeta.Misra@Sun.COM #define ILBST_ITEMIZE_RNAME 98
115*10946SSangeeta.Misra@Sun.COM #define ILBST_TIMESTAMP 99
116*10946SSangeeta.Misra@Sun.COM
117*10946SSangeeta.Misra@Sun.COM /* approx field widths */
118*10946SSangeeta.Misra@Sun.COM #define ILBST_PKTCTR_W 8
119*10946SSangeeta.Misra@Sun.COM #define ILBST_BYTECTR_W 10
120*10946SSangeeta.Misra@Sun.COM #define ILBST_TIME_W 15
121*10946SSangeeta.Misra@Sun.COM
122*10946SSangeeta.Misra@Sun.COM static boolean_t of_rule_stats(ofmt_arg_t *, char *, uint_t);
123*10946SSangeeta.Misra@Sun.COM static boolean_t of_server_stats(ofmt_arg_t *, char *, uint_t);
124*10946SSangeeta.Misra@Sun.COM static boolean_t of_itemize_stats(ofmt_arg_t *, char *, uint_t);
125*10946SSangeeta.Misra@Sun.COM static boolean_t of_timestamp(ofmt_arg_t *, char *, uint_t);
126*10946SSangeeta.Misra@Sun.COM
127*10946SSangeeta.Misra@Sun.COM static ofmt_field_t stat_itemize_fields[] = {
128*10946SSangeeta.Misra@Sun.COM {"RULENAME", ILB_NAMESZ, ILBST_ITEMIZE_RNAME, of_itemize_stats},
129*10946SSangeeta.Misra@Sun.COM {"SERVERNAME", ILB_NAMESZ, ILBST_ITEMIZE_SNAME, of_itemize_stats},
130*10946SSangeeta.Misra@Sun.COM {"PKT_P", ILBST_PKTCTR_W, ILBST_PKT_P, of_itemize_stats},
131*10946SSangeeta.Misra@Sun.COM {"BYTES_P", ILBST_BYTECTR_W, ILBST_BYTES_P, of_itemize_stats},
132*10946SSangeeta.Misra@Sun.COM {"TIME", ILBST_TIME_W, ILBST_TIMESTAMP, of_timestamp},
133*10946SSangeeta.Misra@Sun.COM {NULL, 0, 0, NULL}
134*10946SSangeeta.Misra@Sun.COM };
135*10946SSangeeta.Misra@Sun.COM static ofmt_field_t stat_stdfields[] = {
136*10946SSangeeta.Misra@Sun.COM {"PKT_P", ILBST_PKTCTR_W, ILBST_PKT_P, of_server_stats},
137*10946SSangeeta.Misra@Sun.COM {"BYTES_P", ILBST_BYTECTR_W, ILBST_BYTES_P, of_server_stats},
138*10946SSangeeta.Misra@Sun.COM {"PKT_U", ILBST_PKTCTR_W, ILBST_PKT_U, of_rule_stats},
139*10946SSangeeta.Misra@Sun.COM {"BYTES_U", ILBST_BYTECTR_W, ILBST_BYTES_U, of_rule_stats},
140*10946SSangeeta.Misra@Sun.COM {"PKT_D", ILBST_PKTCTR_W, ILBST_PKT_D, of_rule_stats},
141*10946SSangeeta.Misra@Sun.COM {"BYTES_D", ILBST_BYTECTR_W, ILBST_BYTES_D, of_rule_stats},
142*10946SSangeeta.Misra@Sun.COM {"ICMP_P", ILBST_PKTCTR_W, ILBST_ICMP_P, of_rule_stats},
143*10946SSangeeta.Misra@Sun.COM {"ICMP_D", ILBST_PKTCTR_W, ILBST_ICMP_D, of_rule_stats},
144*10946SSangeeta.Misra@Sun.COM {"ICMP2BIG_P", 11, ILBST_ICMP2BIG_P, of_rule_stats},
145*10946SSangeeta.Misra@Sun.COM {"ICMP2BIG_D", 11, ILBST_ICMP2BIG_D, of_rule_stats},
146*10946SSangeeta.Misra@Sun.COM {"NOMEMP_D", ILBST_PKTCTR_W, ILBST_NOMEMP_D, of_rule_stats},
147*10946SSangeeta.Misra@Sun.COM {"NOPORTP_D", ILBST_PKTCTR_W, ILBST_NOPORTP_D, of_rule_stats},
148*10946SSangeeta.Misra@Sun.COM {"NOMEMB_D", ILBST_PKTCTR_W, ILBST_NOMEMB_D, of_rule_stats},
149*10946SSangeeta.Misra@Sun.COM {"NOPORTB_D", ILBST_PKTCTR_W, ILBST_NOPORTB_D, of_rule_stats},
150*10946SSangeeta.Misra@Sun.COM {"TIME", ILBST_TIME_W, ILBST_TIMESTAMP, of_timestamp},
151*10946SSangeeta.Misra@Sun.COM {NULL, 0, 0, NULL}
152*10946SSangeeta.Misra@Sun.COM };
153*10946SSangeeta.Misra@Sun.COM
154*10946SSangeeta.Misra@Sun.COM static char stat_stdhdrs[] = "PKT_P,BYTES_P,PKT_U,BYTES_U,PKT_D,BYTES_D";
155*10946SSangeeta.Misra@Sun.COM static char stat_stdv_hdrs[] = "PKT_P,BYTES_P,PKT_U,BYTES_U,PKT_D,BYTES_D,"
156*10946SSangeeta.Misra@Sun.COM "ICMP_P,ICMP_D,ICMP2BIG_P,ICMP2BIG_D,NOMEMP_D,NOPORTP_D";
157*10946SSangeeta.Misra@Sun.COM static char stat_itemize_rule_hdrs[] = "SERVERNAME,PKT_P,BYTES_P";
158*10946SSangeeta.Misra@Sun.COM static char stat_itemize_server_hdrs[] = "RULENAME,PKT_P,BYTES_P";
159*10946SSangeeta.Misra@Sun.COM
160*10946SSangeeta.Misra@Sun.COM #define RSTAT_SZ (sizeof (rulestats)/sizeof (rulestats[0]))
161*10946SSangeeta.Misra@Sun.COM #define SSTAT_SZ (sizeof (servstats)/sizeof (servstats[0]))
162*10946SSangeeta.Misra@Sun.COM
163*10946SSangeeta.Misra@Sun.COM typedef struct {
164*10946SSangeeta.Misra@Sun.COM char isd_servername[KSTAT_STRLEN]; /* serverID */
165*10946SSangeeta.Misra@Sun.COM ilbst_stat_t isd_serverstats[SSTAT_SZ];
166*10946SSangeeta.Misra@Sun.COM hrtime_t isd_crtime; /* save for comparison purpose */
167*10946SSangeeta.Misra@Sun.COM } ilbst_srv_desc_t;
168*10946SSangeeta.Misra@Sun.COM
169*10946SSangeeta.Misra@Sun.COM /*
170*10946SSangeeta.Misra@Sun.COM * this data structure stores statistics for a rule - both an old set
171*10946SSangeeta.Misra@Sun.COM * and a current/new set. we use pointers to the actual stores and switch
172*10946SSangeeta.Misra@Sun.COM * the pointers for every round. old_is_old in ilbst_arg_t indicates
173*10946SSangeeta.Misra@Sun.COM * which pointer points to the "old" data struct (ie, if true, _o pointer
174*10946SSangeeta.Misra@Sun.COM * points to old)
175*10946SSangeeta.Misra@Sun.COM */
176*10946SSangeeta.Misra@Sun.COM typedef struct {
177*10946SSangeeta.Misra@Sun.COM char ird_rulename[KSTAT_STRLEN];
178*10946SSangeeta.Misra@Sun.COM int ird_num_servers;
179*10946SSangeeta.Misra@Sun.COM int ird_num_servers_o;
180*10946SSangeeta.Misra@Sun.COM int ird_srv_ind;
181*10946SSangeeta.Misra@Sun.COM hrtime_t ird_crtime; /* save for comparison */
182*10946SSangeeta.Misra@Sun.COM hrtime_t ird_crtime_o; /* save for comparison */
183*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *ird_srvlist;
184*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *ird_srvlist_o;
185*10946SSangeeta.Misra@Sun.COM ilbst_stat_t ird_rstats[RSTAT_SZ];
186*10946SSangeeta.Misra@Sun.COM ilbst_stat_t ird_rstats_o[RSTAT_SZ];
187*10946SSangeeta.Misra@Sun.COM ilbst_stat_t *ird_rulestats;
188*10946SSangeeta.Misra@Sun.COM ilbst_stat_t *ird_rulestats_o;
189*10946SSangeeta.Misra@Sun.COM } ilbst_rule_desc_t;
190*10946SSangeeta.Misra@Sun.COM
191*10946SSangeeta.Misra@Sun.COM /*
192*10946SSangeeta.Misra@Sun.COM * overall "container" for information pertaining to statistics, and
193*10946SSangeeta.Misra@Sun.COM * how to display them.
194*10946SSangeeta.Misra@Sun.COM */
195*10946SSangeeta.Misra@Sun.COM typedef struct {
196*10946SSangeeta.Misra@Sun.COM int ilbst_flags;
197*10946SSangeeta.Misra@Sun.COM /* fields representing user input */
198*10946SSangeeta.Misra@Sun.COM char *ilbst_rulename; /* optional */
199*10946SSangeeta.Misra@Sun.COM char *ilbst_server; /* optional */
200*10946SSangeeta.Misra@Sun.COM int ilbst_interval;
201*10946SSangeeta.Misra@Sun.COM int ilbst_count;
202*10946SSangeeta.Misra@Sun.COM /* "internal" fields for data and data presentation */
203*10946SSangeeta.Misra@Sun.COM ofmt_handle_t ilbst_oh;
204*10946SSangeeta.Misra@Sun.COM boolean_t ilbst_old_is_old;
205*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *ilbst_rlist;
206*10946SSangeeta.Misra@Sun.COM int ilbst_rcount; /* current list count */
207*10946SSangeeta.Misra@Sun.COM int ilbst_rcount_prev; /* prev (different) count */
208*10946SSangeeta.Misra@Sun.COM int ilbst_rlist_sz; /* number of alloc'ed rules */
209*10946SSangeeta.Misra@Sun.COM int ilbst_rule_index; /* for itemizes display */
210*10946SSangeeta.Misra@Sun.COM } ilbst_arg_t;
211*10946SSangeeta.Misra@Sun.COM
212*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
213*10946SSangeeta.Misra@Sun.COM static boolean_t
of_timestamp(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)214*10946SSangeeta.Misra@Sun.COM of_timestamp(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
215*10946SSangeeta.Misra@Sun.COM {
216*10946SSangeeta.Misra@Sun.COM time_t now;
217*10946SSangeeta.Misra@Sun.COM struct tm *now_tm;
218*10946SSangeeta.Misra@Sun.COM
219*10946SSangeeta.Misra@Sun.COM now = time(NULL);
220*10946SSangeeta.Misra@Sun.COM now_tm = localtime(&now);
221*10946SSangeeta.Misra@Sun.COM
222*10946SSangeeta.Misra@Sun.COM (void) strftime(buf, bufsize, "%F:%H.%M.%S", now_tm);
223*10946SSangeeta.Misra@Sun.COM return (B_TRUE);
224*10946SSangeeta.Misra@Sun.COM }
225*10946SSangeeta.Misra@Sun.COM
226*10946SSangeeta.Misra@Sun.COM static boolean_t
i_sum_per_rule_processed(ilbst_rule_desc_t * rp,uint64_t * resp,int index,int flags)227*10946SSangeeta.Misra@Sun.COM i_sum_per_rule_processed(ilbst_rule_desc_t *rp, uint64_t *resp, int index,
228*10946SSangeeta.Misra@Sun.COM int flags)
229*10946SSangeeta.Misra@Sun.COM {
230*10946SSangeeta.Misra@Sun.COM int i, num_servers;
231*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *srv, *o_srv, *n_srv;
232*10946SSangeeta.Misra@Sun.COM uint64_t res = 0;
233*10946SSangeeta.Misra@Sun.COM boolean_t valid = B_TRUE;
234*10946SSangeeta.Misra@Sun.COM boolean_t old = flags & ILBST_OLD_VALUES;
235*10946SSangeeta.Misra@Sun.COM boolean_t check_valid;
236*10946SSangeeta.Misra@Sun.COM
237*10946SSangeeta.Misra@Sun.COM /* if we do abs. numbers, we never look at the _o fields */
238*10946SSangeeta.Misra@Sun.COM assert((old && (flags & ILBST_ABS_NUMBERS)) == B_FALSE);
239*10946SSangeeta.Misra@Sun.COM
240*10946SSangeeta.Misra@Sun.COM /* we only check for validity under certain conditions */
241*10946SSangeeta.Misra@Sun.COM check_valid = !(old || (flags & ILBST_ABS_NUMBERS));
242*10946SSangeeta.Misra@Sun.COM
243*10946SSangeeta.Misra@Sun.COM if (check_valid && rp->ird_num_servers != rp->ird_num_servers_o)
244*10946SSangeeta.Misra@Sun.COM valid = B_FALSE;
245*10946SSangeeta.Misra@Sun.COM
246*10946SSangeeta.Misra@Sun.COM num_servers = old ? rp->ird_num_servers_o : rp->ird_num_servers;
247*10946SSangeeta.Misra@Sun.COM
248*10946SSangeeta.Misra@Sun.COM for (i = 0; i < num_servers; i++) {
249*10946SSangeeta.Misra@Sun.COM n_srv = &rp->ird_srvlist[i];
250*10946SSangeeta.Misra@Sun.COM o_srv = &rp->ird_srvlist_o[i];
251*10946SSangeeta.Misra@Sun.COM
252*10946SSangeeta.Misra@Sun.COM if (old)
253*10946SSangeeta.Misra@Sun.COM srv = o_srv;
254*10946SSangeeta.Misra@Sun.COM else
255*10946SSangeeta.Misra@Sun.COM srv = n_srv;
256*10946SSangeeta.Misra@Sun.COM
257*10946SSangeeta.Misra@Sun.COM res += srv->isd_serverstats[index].is_value;
258*10946SSangeeta.Misra@Sun.COM /*
259*10946SSangeeta.Misra@Sun.COM * if creation times don't match, comparison is wrong; if
260*10946SSangeeta.Misra@Sun.COM * if we already know something is invalid, we don't
261*10946SSangeeta.Misra@Sun.COM * need to compare again.
262*10946SSangeeta.Misra@Sun.COM */
263*10946SSangeeta.Misra@Sun.COM if (check_valid && valid == B_TRUE &&
264*10946SSangeeta.Misra@Sun.COM o_srv->isd_crtime != n_srv->isd_crtime) {
265*10946SSangeeta.Misra@Sun.COM valid = B_FALSE;
266*10946SSangeeta.Misra@Sun.COM break;
267*10946SSangeeta.Misra@Sun.COM }
268*10946SSangeeta.Misra@Sun.COM }
269*10946SSangeeta.Misra@Sun.COM /*
270*10946SSangeeta.Misra@Sun.COM * save the result even though it may be imprecise - let the
271*10946SSangeeta.Misra@Sun.COM * caller decide what to do
272*10946SSangeeta.Misra@Sun.COM */
273*10946SSangeeta.Misra@Sun.COM *resp = res;
274*10946SSangeeta.Misra@Sun.COM
275*10946SSangeeta.Misra@Sun.COM return (valid);
276*10946SSangeeta.Misra@Sun.COM }
277*10946SSangeeta.Misra@Sun.COM
278*10946SSangeeta.Misra@Sun.COM typedef boolean_t (*sumfunc_t)(ilbst_rule_desc_t *, uint64_t *, int);
279*10946SSangeeta.Misra@Sun.COM
280*10946SSangeeta.Misra@Sun.COM static boolean_t
i_sum_per_rule_pkt_p(ilbst_rule_desc_t * rp,uint64_t * resp,int flags)281*10946SSangeeta.Misra@Sun.COM i_sum_per_rule_pkt_p(ilbst_rule_desc_t *rp, uint64_t *resp, int flags)
282*10946SSangeeta.Misra@Sun.COM {
283*10946SSangeeta.Misra@Sun.COM return (i_sum_per_rule_processed(rp, resp, SRVST_PKT_P, flags));
284*10946SSangeeta.Misra@Sun.COM }
285*10946SSangeeta.Misra@Sun.COM
286*10946SSangeeta.Misra@Sun.COM static boolean_t
i_sum_per_rule_bytes_p(ilbst_rule_desc_t * rp,uint64_t * resp,int flags)287*10946SSangeeta.Misra@Sun.COM i_sum_per_rule_bytes_p(ilbst_rule_desc_t *rp, uint64_t *resp, int flags)
288*10946SSangeeta.Misra@Sun.COM {
289*10946SSangeeta.Misra@Sun.COM return (i_sum_per_rule_processed(rp, resp, SRVST_BYTES_P, flags));
290*10946SSangeeta.Misra@Sun.COM }
291*10946SSangeeta.Misra@Sun.COM
292*10946SSangeeta.Misra@Sun.COM static boolean_t
of_server_stats(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)293*10946SSangeeta.Misra@Sun.COM of_server_stats(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
294*10946SSangeeta.Misra@Sun.COM {
295*10946SSangeeta.Misra@Sun.COM ilbst_arg_t *sta = (ilbst_arg_t *)of_arg->ofmt_cbarg;
296*10946SSangeeta.Misra@Sun.COM uint64_t count = 0, val;
297*10946SSangeeta.Misra@Sun.COM int i;
298*10946SSangeeta.Misra@Sun.COM boolean_t valid = B_TRUE;
299*10946SSangeeta.Misra@Sun.COM sumfunc_t sumfunc;
300*10946SSangeeta.Misra@Sun.COM
301*10946SSangeeta.Misra@Sun.COM switch (of_arg->ofmt_id) {
302*10946SSangeeta.Misra@Sun.COM case ILBST_PKT_P: sumfunc = i_sum_per_rule_pkt_p;
303*10946SSangeeta.Misra@Sun.COM break;
304*10946SSangeeta.Misra@Sun.COM case ILBST_BYTES_P: sumfunc = i_sum_per_rule_bytes_p;
305*10946SSangeeta.Misra@Sun.COM break;
306*10946SSangeeta.Misra@Sun.COM }
307*10946SSangeeta.Misra@Sun.COM
308*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rcount; i++) {
309*10946SSangeeta.Misra@Sun.COM valid = sumfunc(&sta->ilbst_rlist[i], &val, sta->ilbst_flags);
310*10946SSangeeta.Misra@Sun.COM if (!valid)
311*10946SSangeeta.Misra@Sun.COM return (valid);
312*10946SSangeeta.Misra@Sun.COM count += val;
313*10946SSangeeta.Misra@Sun.COM }
314*10946SSangeeta.Misra@Sun.COM
315*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ABS_NUMBERS) != 0)
316*10946SSangeeta.Misra@Sun.COM goto out;
317*10946SSangeeta.Misra@Sun.COM
318*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rcount; i++) {
319*10946SSangeeta.Misra@Sun.COM (void) sumfunc(&sta->ilbst_rlist[i], &val,
320*10946SSangeeta.Misra@Sun.COM sta->ilbst_flags | ILBST_OLD_VALUES);
321*10946SSangeeta.Misra@Sun.COM count -= val;
322*10946SSangeeta.Misra@Sun.COM }
323*10946SSangeeta.Misra@Sun.COM
324*10946SSangeeta.Misra@Sun.COM out:
325*10946SSangeeta.Misra@Sun.COM /*
326*10946SSangeeta.Misra@Sun.COM * normally, we print "change per second", which we calculate
327*10946SSangeeta.Misra@Sun.COM * here. otherwise, we print "change over interval"
328*10946SSangeeta.Misra@Sun.COM */
329*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & (ILBST_DELTA_INTERVAL|ILBST_ABS_NUMBERS)) == 0)
330*10946SSangeeta.Misra@Sun.COM count /= sta->ilbst_interval;
331*10946SSangeeta.Misra@Sun.COM
332*10946SSangeeta.Misra@Sun.COM (void) snprintf(buf, bufsize, "%llu", count);
333*10946SSangeeta.Misra@Sun.COM return (B_TRUE);
334*10946SSangeeta.Misra@Sun.COM }
335*10946SSangeeta.Misra@Sun.COM
336*10946SSangeeta.Misra@Sun.COM /*
337*10946SSangeeta.Misra@Sun.COM * this function is called when user wants itemized stats of every
338*10946SSangeeta.Misra@Sun.COM * server for a named rule, or vice vera.
339*10946SSangeeta.Misra@Sun.COM * i_do_print sets sta->rule_index and the proper ird_srv_ind so
340*10946SSangeeta.Misra@Sun.COM * we don't have to differentiate between these two cases here.
341*10946SSangeeta.Misra@Sun.COM */
342*10946SSangeeta.Misra@Sun.COM static boolean_t
of_itemize_stats(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)343*10946SSangeeta.Misra@Sun.COM of_itemize_stats(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
344*10946SSangeeta.Misra@Sun.COM {
345*10946SSangeeta.Misra@Sun.COM ilbst_arg_t *sta = (ilbst_arg_t *)of_arg->ofmt_cbarg;
346*10946SSangeeta.Misra@Sun.COM int stat_ind;
347*10946SSangeeta.Misra@Sun.COM uint64_t count;
348*10946SSangeeta.Misra@Sun.COM int rule_index = sta->ilbst_rule_index;
349*10946SSangeeta.Misra@Sun.COM int srv_ind = sta->ilbst_rlist[rule_index].ird_srv_ind;
350*10946SSangeeta.Misra@Sun.COM boolean_t ret = B_TRUE;
351*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *srv, *osrv;
352*10946SSangeeta.Misra@Sun.COM
353*10946SSangeeta.Misra@Sun.COM srv = &sta->ilbst_rlist[rule_index].ird_srvlist[srv_ind];
354*10946SSangeeta.Misra@Sun.COM
355*10946SSangeeta.Misra@Sun.COM switch (of_arg->ofmt_id) {
356*10946SSangeeta.Misra@Sun.COM case ILBST_PKT_P: stat_ind = SRVST_PKT_P;
357*10946SSangeeta.Misra@Sun.COM break;
358*10946SSangeeta.Misra@Sun.COM case ILBST_BYTES_P: stat_ind = SRVST_BYTES_P;
359*10946SSangeeta.Misra@Sun.COM break;
360*10946SSangeeta.Misra@Sun.COM case ILBST_ITEMIZE_RNAME:
361*10946SSangeeta.Misra@Sun.COM (void) snprintf(buf, bufsize, "%s",
362*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist[rule_index].ird_rulename);
363*10946SSangeeta.Misra@Sun.COM return (B_TRUE);
364*10946SSangeeta.Misra@Sun.COM /* not reached */
365*10946SSangeeta.Misra@Sun.COM break;
366*10946SSangeeta.Misra@Sun.COM case ILBST_ITEMIZE_SNAME:
367*10946SSangeeta.Misra@Sun.COM (void) snprintf(buf, bufsize, "%s", srv->isd_servername);
368*10946SSangeeta.Misra@Sun.COM return (B_TRUE);
369*10946SSangeeta.Misra@Sun.COM /* not reached */
370*10946SSangeeta.Misra@Sun.COM break;
371*10946SSangeeta.Misra@Sun.COM }
372*10946SSangeeta.Misra@Sun.COM
373*10946SSangeeta.Misra@Sun.COM count = srv->isd_serverstats[stat_ind].is_value;
374*10946SSangeeta.Misra@Sun.COM
375*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ABS_NUMBERS) != 0)
376*10946SSangeeta.Misra@Sun.COM goto out;
377*10946SSangeeta.Misra@Sun.COM
378*10946SSangeeta.Misra@Sun.COM osrv = &sta->ilbst_rlist[rule_index].ird_srvlist_o[srv_ind];
379*10946SSangeeta.Misra@Sun.COM if (srv->isd_crtime != osrv->isd_crtime)
380*10946SSangeeta.Misra@Sun.COM ret = B_FALSE;
381*10946SSangeeta.Misra@Sun.COM
382*10946SSangeeta.Misra@Sun.COM count -= osrv->isd_serverstats[stat_ind].is_value;
383*10946SSangeeta.Misra@Sun.COM out:
384*10946SSangeeta.Misra@Sun.COM /*
385*10946SSangeeta.Misra@Sun.COM * normally, we print "change per second", which we calculate
386*10946SSangeeta.Misra@Sun.COM * here. otherwise, we print "change over interval" or absolute
387*10946SSangeeta.Misra@Sun.COM * values.
388*10946SSangeeta.Misra@Sun.COM */
389*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & (ILBST_DELTA_INTERVAL|ILBST_ABS_NUMBERS)) == 0)
390*10946SSangeeta.Misra@Sun.COM count /= sta->ilbst_interval;
391*10946SSangeeta.Misra@Sun.COM
392*10946SSangeeta.Misra@Sun.COM (void) snprintf(buf, bufsize, "%llu", count);
393*10946SSangeeta.Misra@Sun.COM return (ret);
394*10946SSangeeta.Misra@Sun.COM
395*10946SSangeeta.Misra@Sun.COM }
396*10946SSangeeta.Misra@Sun.COM
397*10946SSangeeta.Misra@Sun.COM static boolean_t
of_rule_stats(ofmt_arg_t * of_arg,char * buf,uint_t bufsize)398*10946SSangeeta.Misra@Sun.COM of_rule_stats(ofmt_arg_t *of_arg, char *buf, uint_t bufsize)
399*10946SSangeeta.Misra@Sun.COM {
400*10946SSangeeta.Misra@Sun.COM ilbst_arg_t *sta = (ilbst_arg_t *)of_arg->ofmt_cbarg;
401*10946SSangeeta.Misra@Sun.COM int i, ind;
402*10946SSangeeta.Misra@Sun.COM uint64_t count = 0;
403*10946SSangeeta.Misra@Sun.COM
404*10946SSangeeta.Misra@Sun.COM switch (of_arg->ofmt_id) {
405*10946SSangeeta.Misra@Sun.COM case ILBST_PKT_U: ind = RLSTA_PKT_U;
406*10946SSangeeta.Misra@Sun.COM break;
407*10946SSangeeta.Misra@Sun.COM case ILBST_BYTES_U: ind = RLSTA_BYTES_U;
408*10946SSangeeta.Misra@Sun.COM break;
409*10946SSangeeta.Misra@Sun.COM case ILBST_PKT_D: ind = RLSTA_PKT_D;
410*10946SSangeeta.Misra@Sun.COM break;
411*10946SSangeeta.Misra@Sun.COM case ILBST_BYTES_D: ind = RLSTA_BYTES_D;
412*10946SSangeeta.Misra@Sun.COM break;
413*10946SSangeeta.Misra@Sun.COM case ILBST_ICMP_P: ind = RLSTA_ICMP_P;
414*10946SSangeeta.Misra@Sun.COM break;
415*10946SSangeeta.Misra@Sun.COM case ILBST_ICMP_D: ind = RLSTA_ICMP_D;
416*10946SSangeeta.Misra@Sun.COM break;
417*10946SSangeeta.Misra@Sun.COM case ILBST_ICMP2BIG_P: ind = RLSTA_ICMP2BIG_P;
418*10946SSangeeta.Misra@Sun.COM break;
419*10946SSangeeta.Misra@Sun.COM case ILBST_ICMP2BIG_D: ind = RLSTA_ICMP2BIG_D;
420*10946SSangeeta.Misra@Sun.COM break;
421*10946SSangeeta.Misra@Sun.COM case ILBST_NOMEMP_D: ind = RLSTA_NOMEMPKT_D;
422*10946SSangeeta.Misra@Sun.COM break;
423*10946SSangeeta.Misra@Sun.COM case ILBST_NOPORTP_D: ind = RLSTA_NOPORTPKT_D;
424*10946SSangeeta.Misra@Sun.COM break;
425*10946SSangeeta.Misra@Sun.COM case ILBST_NOMEMB_D: ind = RLSTA_NOMEMBYTES_D;
426*10946SSangeeta.Misra@Sun.COM break;
427*10946SSangeeta.Misra@Sun.COM case ILBST_NOPORTB_D: ind = RLSTA_NOPORTBYTES_D;
428*10946SSangeeta.Misra@Sun.COM break;
429*10946SSangeeta.Misra@Sun.COM }
430*10946SSangeeta.Misra@Sun.COM
431*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rcount; i++)
432*10946SSangeeta.Misra@Sun.COM count += sta->ilbst_rlist[i].ird_rulestats[ind].is_value;
433*10946SSangeeta.Misra@Sun.COM
434*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ABS_NUMBERS) != 0)
435*10946SSangeeta.Misra@Sun.COM goto out;
436*10946SSangeeta.Misra@Sun.COM
437*10946SSangeeta.Misra@Sun.COM /*
438*10946SSangeeta.Misra@Sun.COM * the purist approach: if we can't say 100% that what we
439*10946SSangeeta.Misra@Sun.COM * calculate is correct, don't.
440*10946SSangeeta.Misra@Sun.COM */
441*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_flags & ILBST_RULES_CHANGED)
442*10946SSangeeta.Misra@Sun.COM return (B_FALSE);
443*10946SSangeeta.Misra@Sun.COM
444*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rcount; i++) {
445*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rlist[i].ird_crtime_o != 0 &&
446*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist[i].ird_crtime !=
447*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist[i].ird_crtime_o)
448*10946SSangeeta.Misra@Sun.COM return (B_FALSE);
449*10946SSangeeta.Misra@Sun.COM
450*10946SSangeeta.Misra@Sun.COM count -= sta->ilbst_rlist[i].ird_rulestats_o[ind].is_value;
451*10946SSangeeta.Misra@Sun.COM }
452*10946SSangeeta.Misra@Sun.COM out:
453*10946SSangeeta.Misra@Sun.COM /*
454*10946SSangeeta.Misra@Sun.COM * normally, we print "change per second", which we calculate
455*10946SSangeeta.Misra@Sun.COM * here. otherwise, we print "change over interval"
456*10946SSangeeta.Misra@Sun.COM */
457*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & (ILBST_DELTA_INTERVAL|ILBST_ABS_NUMBERS)) == 0)
458*10946SSangeeta.Misra@Sun.COM count /= sta->ilbst_interval;
459*10946SSangeeta.Misra@Sun.COM
460*10946SSangeeta.Misra@Sun.COM (void) snprintf(buf, bufsize, "%llu", count);
461*10946SSangeeta.Misra@Sun.COM return (B_TRUE);
462*10946SSangeeta.Misra@Sun.COM }
463*10946SSangeeta.Misra@Sun.COM
464*10946SSangeeta.Misra@Sun.COM /*
465*10946SSangeeta.Misra@Sun.COM * Get the number of kstat instances. Note that when rules are being
466*10946SSangeeta.Misra@Sun.COM * drained the number of kstats instances may be different than the
467*10946SSangeeta.Misra@Sun.COM * kstat counter num_rules (ilb:0:global:num_rules").
468*10946SSangeeta.Misra@Sun.COM *
469*10946SSangeeta.Misra@Sun.COM * Also there can be multiple instances of a rule in the following
470*10946SSangeeta.Misra@Sun.COM * scenario:
471*10946SSangeeta.Misra@Sun.COM *
472*10946SSangeeta.Misra@Sun.COM * A rule named rule A has been deleted but remains in kstats because
473*10946SSangeeta.Misra@Sun.COM * its undergoing connection draining. During this time, the user adds
474*10946SSangeeta.Misra@Sun.COM * a new rule with the same name(rule A). In this case, there would
475*10946SSangeeta.Misra@Sun.COM * be two kstats instances for rule A. Currently ilbadm's aggregate
476*10946SSangeeta.Misra@Sun.COM * results will include data from both instances of rule A. In,
477*10946SSangeeta.Misra@Sun.COM * future we should have ilbadm stats only consider the latest instance
478*10946SSangeeta.Misra@Sun.COM * of the rule (ie only consider the the instance that corresponds
479*10946SSangeeta.Misra@Sun.COM * to the rule that was just added).
480*10946SSangeeta.Misra@Sun.COM *
481*10946SSangeeta.Misra@Sun.COM */
482*10946SSangeeta.Misra@Sun.COM static int
i_get_num_kinstances(kstat_ctl_t * kctl)483*10946SSangeeta.Misra@Sun.COM i_get_num_kinstances(kstat_ctl_t *kctl)
484*10946SSangeeta.Misra@Sun.COM {
485*10946SSangeeta.Misra@Sun.COM kstat_t *kp;
486*10946SSangeeta.Misra@Sun.COM int num_instances = 0; /* nothing found, 0 rules */
487*10946SSangeeta.Misra@Sun.COM
488*10946SSangeeta.Misra@Sun.COM for (kp = kctl->kc_chain; kp != NULL; kp = kp->ks_next) {
489*10946SSangeeta.Misra@Sun.COM if (strncmp("rulestat", kp->ks_class, 8) == 0 &&
490*10946SSangeeta.Misra@Sun.COM strncmp("ilb", kp->ks_module, 3) == 0) {
491*10946SSangeeta.Misra@Sun.COM num_instances++;
492*10946SSangeeta.Misra@Sun.COM }
493*10946SSangeeta.Misra@Sun.COM }
494*10946SSangeeta.Misra@Sun.COM
495*10946SSangeeta.Misra@Sun.COM return (num_instances);
496*10946SSangeeta.Misra@Sun.COM }
497*10946SSangeeta.Misra@Sun.COM
498*10946SSangeeta.Misra@Sun.COM
499*10946SSangeeta.Misra@Sun.COM /*
500*10946SSangeeta.Misra@Sun.COM * since server stat's classname is made up of <rulename>-sstat,
501*10946SSangeeta.Misra@Sun.COM * we walk the rule list to construct the comparison
502*10946SSangeeta.Misra@Sun.COM * Return: pointer to rule whose name matches the class
503*10946SSangeeta.Misra@Sun.COM * NULL if no match
504*10946SSangeeta.Misra@Sun.COM */
505*10946SSangeeta.Misra@Sun.COM static ilbst_rule_desc_t *
match_2_rnames(char * class,ilbst_rule_desc_t * rlist,int rcount)506*10946SSangeeta.Misra@Sun.COM match_2_rnames(char *class, ilbst_rule_desc_t *rlist, int rcount)
507*10946SSangeeta.Misra@Sun.COM {
508*10946SSangeeta.Misra@Sun.COM int i;
509*10946SSangeeta.Misra@Sun.COM char classname[KSTAT_STRLEN];
510*10946SSangeeta.Misra@Sun.COM
511*10946SSangeeta.Misra@Sun.COM for (i = 0; i < rcount; i++) {
512*10946SSangeeta.Misra@Sun.COM (void) snprintf(classname, sizeof (classname), "%s-sstat",
513*10946SSangeeta.Misra@Sun.COM rlist[i].ird_rulename);
514*10946SSangeeta.Misra@Sun.COM if (strncmp(classname, class, sizeof (classname)) == 0)
515*10946SSangeeta.Misra@Sun.COM return (&rlist[i]);
516*10946SSangeeta.Misra@Sun.COM }
517*10946SSangeeta.Misra@Sun.COM return (NULL);
518*10946SSangeeta.Misra@Sun.COM }
519*10946SSangeeta.Misra@Sun.COM
520*10946SSangeeta.Misra@Sun.COM static int
i_stat_index(kstat_named_t * knp,ilbst_stat_t * stats,int count)521*10946SSangeeta.Misra@Sun.COM i_stat_index(kstat_named_t *knp, ilbst_stat_t *stats, int count)
522*10946SSangeeta.Misra@Sun.COM {
523*10946SSangeeta.Misra@Sun.COM int i;
524*10946SSangeeta.Misra@Sun.COM
525*10946SSangeeta.Misra@Sun.COM for (i = 0; i < count; i++) {
526*10946SSangeeta.Misra@Sun.COM if (strcasecmp(stats[i].is_name, knp->name) == 0)
527*10946SSangeeta.Misra@Sun.COM return (i);
528*10946SSangeeta.Misra@Sun.COM }
529*10946SSangeeta.Misra@Sun.COM
530*10946SSangeeta.Misra@Sun.COM return (-1);
531*10946SSangeeta.Misra@Sun.COM }
532*10946SSangeeta.Misra@Sun.COM
533*10946SSangeeta.Misra@Sun.COM static void
i_copy_sstats(ilbst_srv_desc_t * sp,kstat_t * kp)534*10946SSangeeta.Misra@Sun.COM i_copy_sstats(ilbst_srv_desc_t *sp, kstat_t *kp)
535*10946SSangeeta.Misra@Sun.COM {
536*10946SSangeeta.Misra@Sun.COM kstat_named_t *knp;
537*10946SSangeeta.Misra@Sun.COM int i, ind;
538*10946SSangeeta.Misra@Sun.COM
539*10946SSangeeta.Misra@Sun.COM knp = KSTAT_NAMED_PTR(kp);
540*10946SSangeeta.Misra@Sun.COM for (i = 0; i < kp->ks_ndata; i++, knp++) {
541*10946SSangeeta.Misra@Sun.COM ind = i_stat_index(knp, servstats, SSTAT_SZ);
542*10946SSangeeta.Misra@Sun.COM if (ind == -1)
543*10946SSangeeta.Misra@Sun.COM continue;
544*10946SSangeeta.Misra@Sun.COM (void) strlcpy(sp->isd_serverstats[ind].is_name, knp->name,
545*10946SSangeeta.Misra@Sun.COM sizeof (sp->isd_serverstats[ind].is_name));
546*10946SSangeeta.Misra@Sun.COM sp->isd_serverstats[ind].is_value = knp->value.ui64;
547*10946SSangeeta.Misra@Sun.COM sp->isd_crtime = kp->ks_crtime;
548*10946SSangeeta.Misra@Sun.COM }
549*10946SSangeeta.Misra@Sun.COM }
550*10946SSangeeta.Misra@Sun.COM
551*10946SSangeeta.Misra@Sun.COM
552*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_get_server_descs(ilbst_arg_t * sta,kstat_ctl_t * kctl)553*10946SSangeeta.Misra@Sun.COM i_get_server_descs(ilbst_arg_t *sta, kstat_ctl_t *kctl)
554*10946SSangeeta.Misra@Sun.COM {
555*10946SSangeeta.Misra@Sun.COM ilbadm_status_t rc = ILBADM_OK;
556*10946SSangeeta.Misra@Sun.COM kstat_t *kp;
557*10946SSangeeta.Misra@Sun.COM int i = -1;
558*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rp;
559*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rlist = sta->ilbst_rlist;
560*10946SSangeeta.Misra@Sun.COM int rcount = sta->ilbst_rcount;
561*10946SSangeeta.Misra@Sun.COM
562*10946SSangeeta.Misra@Sun.COM /*
563*10946SSangeeta.Misra@Sun.COM * find all "server" kstats, or the one specified in
564*10946SSangeeta.Misra@Sun.COM * sta->server
565*10946SSangeeta.Misra@Sun.COM */
566*10946SSangeeta.Misra@Sun.COM for (kp = kctl->kc_chain; kp != NULL; kp = kp->ks_next) {
567*10946SSangeeta.Misra@Sun.COM if (strncmp("ilb", kp->ks_module, 3) != 0)
568*10946SSangeeta.Misra@Sun.COM continue;
569*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_server != NULL &&
570*10946SSangeeta.Misra@Sun.COM strcasecmp(sta->ilbst_server, kp->ks_name) != 0)
571*10946SSangeeta.Misra@Sun.COM continue;
572*10946SSangeeta.Misra@Sun.COM rp = match_2_rnames(kp->ks_class, rlist, rcount);
573*10946SSangeeta.Misra@Sun.COM if (rp == NULL)
574*10946SSangeeta.Misra@Sun.COM continue;
575*10946SSangeeta.Misra@Sun.COM
576*10946SSangeeta.Misra@Sun.COM (void) kstat_read(kctl, kp, NULL);
577*10946SSangeeta.Misra@Sun.COM i = rp->ird_srv_ind++;
578*10946SSangeeta.Misra@Sun.COM
579*10946SSangeeta.Misra@Sun.COM rc = ILBADM_OK;
580*10946SSangeeta.Misra@Sun.COM /*
581*10946SSangeeta.Misra@Sun.COM * This means that a server is added after we check last
582*10946SSangeeta.Misra@Sun.COM * time... Just make the array bigger.
583*10946SSangeeta.Misra@Sun.COM */
584*10946SSangeeta.Misra@Sun.COM if (i+1 > rp->ird_num_servers) {
585*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *srvlist;
586*10946SSangeeta.Misra@Sun.COM
587*10946SSangeeta.Misra@Sun.COM if ((srvlist = realloc(rp->ird_srvlist, (i+1) *
588*10946SSangeeta.Misra@Sun.COM sizeof (*srvlist))) == NULL) {
589*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
590*10946SSangeeta.Misra@Sun.COM break;
591*10946SSangeeta.Misra@Sun.COM }
592*10946SSangeeta.Misra@Sun.COM rp->ird_srvlist = srvlist;
593*10946SSangeeta.Misra@Sun.COM rp->ird_num_servers = i;
594*10946SSangeeta.Misra@Sun.COM }
595*10946SSangeeta.Misra@Sun.COM
596*10946SSangeeta.Misra@Sun.COM (void) strlcpy(rp->ird_srvlist[i].isd_servername, kp->ks_name,
597*10946SSangeeta.Misra@Sun.COM sizeof (rp->ird_srvlist[i].isd_servername));
598*10946SSangeeta.Misra@Sun.COM i_copy_sstats(&rp->ird_srvlist[i], kp);
599*10946SSangeeta.Misra@Sun.COM }
600*10946SSangeeta.Misra@Sun.COM
601*10946SSangeeta.Misra@Sun.COM for (i = 0; i < rcount; i++)
602*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srv_ind = 0;
603*10946SSangeeta.Misra@Sun.COM
604*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_server != NULL && i == -1)
605*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOSERVER;
606*10946SSangeeta.Misra@Sun.COM return (rc);
607*10946SSangeeta.Misra@Sun.COM }
608*10946SSangeeta.Misra@Sun.COM
609*10946SSangeeta.Misra@Sun.COM static void
i_copy_rstats(ilbst_rule_desc_t * rp,kstat_t * kp)610*10946SSangeeta.Misra@Sun.COM i_copy_rstats(ilbst_rule_desc_t *rp, kstat_t *kp)
611*10946SSangeeta.Misra@Sun.COM {
612*10946SSangeeta.Misra@Sun.COM kstat_named_t *knp;
613*10946SSangeeta.Misra@Sun.COM int i, ind;
614*10946SSangeeta.Misra@Sun.COM
615*10946SSangeeta.Misra@Sun.COM knp = KSTAT_NAMED_PTR(kp);
616*10946SSangeeta.Misra@Sun.COM for (i = 0; i < kp->ks_ndata; i++, knp++) {
617*10946SSangeeta.Misra@Sun.COM ind = i_stat_index(knp, rulestats, RSTAT_SZ);
618*10946SSangeeta.Misra@Sun.COM if (ind == -1)
619*10946SSangeeta.Misra@Sun.COM continue;
620*10946SSangeeta.Misra@Sun.COM
621*10946SSangeeta.Misra@Sun.COM (void) strlcpy(rp->ird_rulestats[ind].is_name, knp->name,
622*10946SSangeeta.Misra@Sun.COM sizeof (rp->ird_rulestats[ind].is_name));
623*10946SSangeeta.Misra@Sun.COM rp->ird_rulestats[ind].is_value = knp->value.ui64;
624*10946SSangeeta.Misra@Sun.COM }
625*10946SSangeeta.Misra@Sun.COM }
626*10946SSangeeta.Misra@Sun.COM
627*10946SSangeeta.Misra@Sun.COM static void
i_set_rlstats_ptr(ilbst_rule_desc_t * rp,boolean_t old_is_old)628*10946SSangeeta.Misra@Sun.COM i_set_rlstats_ptr(ilbst_rule_desc_t *rp, boolean_t old_is_old)
629*10946SSangeeta.Misra@Sun.COM {
630*10946SSangeeta.Misra@Sun.COM if (old_is_old) {
631*10946SSangeeta.Misra@Sun.COM rp->ird_rulestats = rp->ird_rstats;
632*10946SSangeeta.Misra@Sun.COM rp->ird_rulestats_o = rp->ird_rstats_o;
633*10946SSangeeta.Misra@Sun.COM } else {
634*10946SSangeeta.Misra@Sun.COM rp->ird_rulestats = rp->ird_rstats_o;
635*10946SSangeeta.Misra@Sun.COM rp->ird_rulestats_o = rp->ird_rstats;
636*10946SSangeeta.Misra@Sun.COM }
637*10946SSangeeta.Misra@Sun.COM }
638*10946SSangeeta.Misra@Sun.COM /*
639*10946SSangeeta.Misra@Sun.COM * this function walks the array of rules and switches pointer to old
640*10946SSangeeta.Misra@Sun.COM * and new stats as well as serverlists.
641*10946SSangeeta.Misra@Sun.COM */
642*10946SSangeeta.Misra@Sun.COM static void
i_swap_rl_pointers(ilbst_arg_t * sta,int rcount)643*10946SSangeeta.Misra@Sun.COM i_swap_rl_pointers(ilbst_arg_t *sta, int rcount)
644*10946SSangeeta.Misra@Sun.COM {
645*10946SSangeeta.Misra@Sun.COM int i, tmp_num;
646*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rlist = sta->ilbst_rlist;
647*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *tmp_srv;
648*10946SSangeeta.Misra@Sun.COM
649*10946SSangeeta.Misra@Sun.COM for (i = 0; i < rcount; i++) {
650*10946SSangeeta.Misra@Sun.COM /* swap srvlist pointers */
651*10946SSangeeta.Misra@Sun.COM tmp_srv = rlist[i].ird_srvlist;
652*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srvlist = rlist[i].ird_srvlist_o;
653*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srvlist_o = tmp_srv;
654*10946SSangeeta.Misra@Sun.COM
655*10946SSangeeta.Misra@Sun.COM /*
656*10946SSangeeta.Misra@Sun.COM * swap server counts - we need the old one to
657*10946SSangeeta.Misra@Sun.COM * save reallocation calls
658*10946SSangeeta.Misra@Sun.COM */
659*10946SSangeeta.Misra@Sun.COM tmp_num = rlist[i].ird_num_servers_o;
660*10946SSangeeta.Misra@Sun.COM rlist[i].ird_num_servers_o = rlist[i].ird_num_servers;
661*10946SSangeeta.Misra@Sun.COM rlist[i].ird_num_servers = tmp_num;
662*10946SSangeeta.Misra@Sun.COM
663*10946SSangeeta.Misra@Sun.COM /* preserve creation time */
664*10946SSangeeta.Misra@Sun.COM rlist[i].ird_crtime_o = rlist[i].ird_crtime;
665*10946SSangeeta.Misra@Sun.COM
666*10946SSangeeta.Misra@Sun.COM i_set_rlstats_ptr(&rlist[i], sta->ilbst_old_is_old);
667*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srv_ind = 0;
668*10946SSangeeta.Misra@Sun.COM }
669*10946SSangeeta.Misra@Sun.COM }
670*10946SSangeeta.Misra@Sun.COM
671*10946SSangeeta.Misra@Sun.COM static void
i_init_rulelist(ilbst_arg_t * sta,int rcount)672*10946SSangeeta.Misra@Sun.COM i_init_rulelist(ilbst_arg_t *sta, int rcount)
673*10946SSangeeta.Misra@Sun.COM {
674*10946SSangeeta.Misra@Sun.COM int i;
675*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rlist = sta->ilbst_rlist;
676*10946SSangeeta.Misra@Sun.COM
677*10946SSangeeta.Misra@Sun.COM for (i = 0; i < rcount; i++) {
678*10946SSangeeta.Misra@Sun.COM rlist[i].ird_rulestats = rlist[i].ird_rstats;
679*10946SSangeeta.Misra@Sun.COM rlist[i].ird_rulestats_o = rlist[i].ird_rstats_o;
680*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srv_ind = 0;
681*10946SSangeeta.Misra@Sun.COM }
682*10946SSangeeta.Misra@Sun.COM }
683*10946SSangeeta.Misra@Sun.COM
684*10946SSangeeta.Misra@Sun.COM
685*10946SSangeeta.Misra@Sun.COM /*
686*10946SSangeeta.Misra@Sun.COM * this function searches for kstats describing individual rules and
687*10946SSangeeta.Misra@Sun.COM * saves name, # of servers, and the kstat_t * describing them (this is
688*10946SSangeeta.Misra@Sun.COM * for sta->rulename == NULL);
689*10946SSangeeta.Misra@Sun.COM * if sta->rulename != NULL, it names the rule we're looking for
690*10946SSangeeta.Misra@Sun.COM * and this function will fill in the other data (like the all_rules case)
691*10946SSangeeta.Misra@Sun.COM * Returns: ILBADM_ENORULE named rule not found
692*10946SSangeeta.Misra@Sun.COM * ILBADM_ENOMEM no mem. available
693*10946SSangeeta.Misra@Sun.COM */
694*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_get_rule_descs(ilbst_arg_t * sta,kstat_ctl_t * kctl)695*10946SSangeeta.Misra@Sun.COM i_get_rule_descs(ilbst_arg_t *sta, kstat_ctl_t *kctl)
696*10946SSangeeta.Misra@Sun.COM {
697*10946SSangeeta.Misra@Sun.COM ilbadm_status_t rc = ILBADM_OK;
698*10946SSangeeta.Misra@Sun.COM kstat_t *kp;
699*10946SSangeeta.Misra@Sun.COM kstat_named_t *knp;
700*10946SSangeeta.Misra@Sun.COM int i;
701*10946SSangeeta.Misra@Sun.COM int num_servers;
702*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rlist = sta->ilbst_rlist;
703*10946SSangeeta.Misra@Sun.COM int rcount = sta->ilbst_rcount;
704*10946SSangeeta.Misra@Sun.COM
705*10946SSangeeta.Misra@Sun.COM /*
706*10946SSangeeta.Misra@Sun.COM * find all "rule" kstats, or the one specified in
707*10946SSangeeta.Misra@Sun.COM * sta->ilbst_rulename.
708*10946SSangeeta.Misra@Sun.COM */
709*10946SSangeeta.Misra@Sun.COM for (i = 0, kp = kctl->kc_chain; i < rcount && kp != NULL;
710*10946SSangeeta.Misra@Sun.COM kp = kp->ks_next) {
711*10946SSangeeta.Misra@Sun.COM if (strncmp("rulestat", kp->ks_class, 8) != 0 ||
712*10946SSangeeta.Misra@Sun.COM strncmp("ilb", kp->ks_module, 3) != 0)
713*10946SSangeeta.Misra@Sun.COM continue;
714*10946SSangeeta.Misra@Sun.COM
715*10946SSangeeta.Misra@Sun.COM (void) kstat_read(kctl, kp, NULL);
716*10946SSangeeta.Misra@Sun.COM
717*10946SSangeeta.Misra@Sun.COM knp = kstat_data_lookup(kp, "num_servers");
718*10946SSangeeta.Misra@Sun.COM if (knp == NULL) {
719*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("kstat_data_lookup() failed: %s"),
720*10946SSangeeta.Misra@Sun.COM strerror(errno));
721*10946SSangeeta.Misra@Sun.COM rc = ILBADM_LIBERR;
722*10946SSangeeta.Misra@Sun.COM break;
723*10946SSangeeta.Misra@Sun.COM }
724*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename != NULL) {
725*10946SSangeeta.Misra@Sun.COM if (strcasecmp(kp->ks_name, sta->ilbst_rulename)
726*10946SSangeeta.Misra@Sun.COM != 0)
727*10946SSangeeta.Misra@Sun.COM continue;
728*10946SSangeeta.Misra@Sun.COM }
729*10946SSangeeta.Misra@Sun.COM (void) strlcpy(rlist[i].ird_rulename, kp->ks_name,
730*10946SSangeeta.Misra@Sun.COM sizeof (rlist[i].ird_rulename));
731*10946SSangeeta.Misra@Sun.COM
732*10946SSangeeta.Misra@Sun.COM /* only alloc the space we need, set counter here ... */
733*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_server != NULL)
734*10946SSangeeta.Misra@Sun.COM num_servers = 1;
735*10946SSangeeta.Misra@Sun.COM else
736*10946SSangeeta.Misra@Sun.COM num_servers = (int)knp->value.ui64;
737*10946SSangeeta.Misra@Sun.COM
738*10946SSangeeta.Misra@Sun.COM /* ... furthermore, only reallocate if necessary */
739*10946SSangeeta.Misra@Sun.COM if (num_servers != rlist[i].ird_num_servers) {
740*10946SSangeeta.Misra@Sun.COM ilbst_srv_desc_t *srvlist;
741*10946SSangeeta.Misra@Sun.COM
742*10946SSangeeta.Misra@Sun.COM rlist[i].ird_num_servers = num_servers;
743*10946SSangeeta.Misra@Sun.COM
744*10946SSangeeta.Misra@Sun.COM if (rlist[i].ird_srvlist == NULL)
745*10946SSangeeta.Misra@Sun.COM srvlist = calloc(num_servers,
746*10946SSangeeta.Misra@Sun.COM sizeof (*srvlist));
747*10946SSangeeta.Misra@Sun.COM else
748*10946SSangeeta.Misra@Sun.COM srvlist = realloc(rlist[i].ird_srvlist,
749*10946SSangeeta.Misra@Sun.COM sizeof (*srvlist) * num_servers);
750*10946SSangeeta.Misra@Sun.COM if (srvlist == NULL) {
751*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
752*10946SSangeeta.Misra@Sun.COM break;
753*10946SSangeeta.Misra@Sun.COM }
754*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srvlist = srvlist;
755*10946SSangeeta.Misra@Sun.COM }
756*10946SSangeeta.Misra@Sun.COM rlist[i].ird_srv_ind = 0;
757*10946SSangeeta.Misra@Sun.COM rlist[i].ird_crtime = kp->ks_crtime;
758*10946SSangeeta.Misra@Sun.COM
759*10946SSangeeta.Misra@Sun.COM i_copy_rstats(&rlist[i], kp);
760*10946SSangeeta.Misra@Sun.COM i++;
761*10946SSangeeta.Misra@Sun.COM
762*10946SSangeeta.Misra@Sun.COM /* if we know we're done, return */
763*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename != NULL || i == rcount) {
764*10946SSangeeta.Misra@Sun.COM rc = ILBADM_OK;
765*10946SSangeeta.Misra@Sun.COM break;
766*10946SSangeeta.Misra@Sun.COM }
767*10946SSangeeta.Misra@Sun.COM }
768*10946SSangeeta.Misra@Sun.COM
769*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename != NULL && i == 0)
770*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENORULE;
771*10946SSangeeta.Misra@Sun.COM return (rc);
772*10946SSangeeta.Misra@Sun.COM }
773*10946SSangeeta.Misra@Sun.COM
774*10946SSangeeta.Misra@Sun.COM static void
i_do_print(ilbst_arg_t * sta)775*10946SSangeeta.Misra@Sun.COM i_do_print(ilbst_arg_t *sta)
776*10946SSangeeta.Misra@Sun.COM {
777*10946SSangeeta.Misra@Sun.COM int i;
778*10946SSangeeta.Misra@Sun.COM
779*10946SSangeeta.Misra@Sun.COM /* non-itemized display can go right ahead */
780*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ITEMIZE) == 0) {
781*10946SSangeeta.Misra@Sun.COM ofmt_print(sta->ilbst_oh, sta);
782*10946SSangeeta.Misra@Sun.COM return;
783*10946SSangeeta.Misra@Sun.COM }
784*10946SSangeeta.Misra@Sun.COM
785*10946SSangeeta.Misra@Sun.COM /*
786*10946SSangeeta.Misra@Sun.COM * rulename is given, list a line per server
787*10946SSangeeta.Misra@Sun.COM * here's how we do it:
788*10946SSangeeta.Misra@Sun.COM * the _ITEMIZE flag indicates to the print function (called
789*10946SSangeeta.Misra@Sun.COM * from ofmt_print()) to look at server [ird_srv_ind] only.
790*10946SSangeeta.Misra@Sun.COM */
791*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename != NULL) {
792*10946SSangeeta.Misra@Sun.COM sta->ilbst_rule_index = 0;
793*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rlist->ird_num_servers; i++) {
794*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist->ird_srv_ind = i;
795*10946SSangeeta.Misra@Sun.COM ofmt_print(sta->ilbst_oh, sta);
796*10946SSangeeta.Misra@Sun.COM }
797*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist->ird_srv_ind = 0;
798*10946SSangeeta.Misra@Sun.COM return;
799*10946SSangeeta.Misra@Sun.COM }
800*10946SSangeeta.Misra@Sun.COM
801*10946SSangeeta.Misra@Sun.COM /* list one line for every rule for a given server */
802*10946SSangeeta.Misra@Sun.COM for (i = 0; i < sta->ilbst_rcount; i++) {
803*10946SSangeeta.Misra@Sun.COM /*
804*10946SSangeeta.Misra@Sun.COM * if a rule doesn't contain a given server, there's no
805*10946SSangeeta.Misra@Sun.COM * need to print it. Luckily, we can check that
806*10946SSangeeta.Misra@Sun.COM * fairly easily
807*10946SSangeeta.Misra@Sun.COM */
808*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rlist[i].ird_srvlist[0].isd_servername[0] ==
809*10946SSangeeta.Misra@Sun.COM '\0')
810*10946SSangeeta.Misra@Sun.COM continue;
811*10946SSangeeta.Misra@Sun.COM
812*10946SSangeeta.Misra@Sun.COM sta->ilbst_rule_index = i;
813*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist[i].ird_srv_ind = 0;
814*10946SSangeeta.Misra@Sun.COM ofmt_print(sta->ilbst_oh, sta);
815*10946SSangeeta.Misra@Sun.COM }
816*10946SSangeeta.Misra@Sun.COM sta->ilbst_rule_index = 0;
817*10946SSangeeta.Misra@Sun.COM }
818*10946SSangeeta.Misra@Sun.COM
819*10946SSangeeta.Misra@Sun.COM static ilbadm_status_t
i_do_show_stats(ilbst_arg_t * sta)820*10946SSangeeta.Misra@Sun.COM i_do_show_stats(ilbst_arg_t *sta)
821*10946SSangeeta.Misra@Sun.COM {
822*10946SSangeeta.Misra@Sun.COM kstat_ctl_t *kctl;
823*10946SSangeeta.Misra@Sun.COM kid_t nkid;
824*10946SSangeeta.Misra@Sun.COM int rcount = 1, i;
825*10946SSangeeta.Misra@Sun.COM ilbadm_status_t rc = ILBADM_OK;
826*10946SSangeeta.Misra@Sun.COM ilbst_rule_desc_t *rlist, *rp;
827*10946SSangeeta.Misra@Sun.COM boolean_t pseudo_abs = B_FALSE; /* for first pass */
828*10946SSangeeta.Misra@Sun.COM
829*10946SSangeeta.Misra@Sun.COM if ((kctl = kstat_open()) == NULL) {
830*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("kstat_open() failed: %s"), strerror(errno));
831*10946SSangeeta.Misra@Sun.COM return (ILBADM_LIBERR);
832*10946SSangeeta.Misra@Sun.COM }
833*10946SSangeeta.Misra@Sun.COM
834*10946SSangeeta.Misra@Sun.COM
835*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename == NULL)
836*10946SSangeeta.Misra@Sun.COM rcount = i_get_num_kinstances(kctl);
837*10946SSangeeta.Misra@Sun.COM
838*10946SSangeeta.Misra@Sun.COM rlist = calloc(sizeof (*rlist), rcount);
839*10946SSangeeta.Misra@Sun.COM if (rlist == NULL) {
840*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
841*10946SSangeeta.Misra@Sun.COM goto out;
842*10946SSangeeta.Misra@Sun.COM }
843*10946SSangeeta.Misra@Sun.COM
844*10946SSangeeta.Misra@Sun.COM sta->ilbst_old_is_old = B_TRUE;
845*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist = rlist;
846*10946SSangeeta.Misra@Sun.COM sta->ilbst_rcount = sta->ilbst_rcount_prev = rcount;
847*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist_sz = rcount;
848*10946SSangeeta.Misra@Sun.COM
849*10946SSangeeta.Misra@Sun.COM /*
850*10946SSangeeta.Misra@Sun.COM * in the first pass, we always print absolute numbers. We
851*10946SSangeeta.Misra@Sun.COM * need to remember whether we wanted abs. numbers for
852*10946SSangeeta.Misra@Sun.COM * other samples as well
853*10946SSangeeta.Misra@Sun.COM */
854*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ABS_NUMBERS) == 0) {
855*10946SSangeeta.Misra@Sun.COM sta->ilbst_flags |= ILBST_ABS_NUMBERS;
856*10946SSangeeta.Misra@Sun.COM pseudo_abs = B_TRUE;
857*10946SSangeeta.Misra@Sun.COM }
858*10946SSangeeta.Misra@Sun.COM
859*10946SSangeeta.Misra@Sun.COM i_init_rulelist(sta, rcount);
860*10946SSangeeta.Misra@Sun.COM do {
861*10946SSangeeta.Misra@Sun.COM rc = i_get_rule_descs(sta, kctl);
862*10946SSangeeta.Misra@Sun.COM if (rc != ILBADM_OK)
863*10946SSangeeta.Misra@Sun.COM goto out;
864*10946SSangeeta.Misra@Sun.COM
865*10946SSangeeta.Misra@Sun.COM rc = i_get_server_descs(sta, kctl);
866*10946SSangeeta.Misra@Sun.COM if (rc != ILBADM_OK)
867*10946SSangeeta.Misra@Sun.COM goto out;
868*10946SSangeeta.Misra@Sun.COM
869*10946SSangeeta.Misra@Sun.COM i_do_print(sta);
870*10946SSangeeta.Misra@Sun.COM
871*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_count == -1 || --(sta->ilbst_count) > 0)
872*10946SSangeeta.Misra@Sun.COM (void) sleep(sta->ilbst_interval);
873*10946SSangeeta.Misra@Sun.COM else
874*10946SSangeeta.Misra@Sun.COM break;
875*10946SSangeeta.Misra@Sun.COM
876*10946SSangeeta.Misra@Sun.COM nkid = kstat_chain_update(kctl);
877*10946SSangeeta.Misra@Sun.COM sta->ilbst_flags &= ~ILBST_RULES_CHANGED;
878*10946SSangeeta.Misra@Sun.COM /*
879*10946SSangeeta.Misra@Sun.COM * we only need to continue with most of the rest of this if
880*10946SSangeeta.Misra@Sun.COM * the kstat chain id has changed
881*10946SSangeeta.Misra@Sun.COM */
882*10946SSangeeta.Misra@Sun.COM if (nkid == 0)
883*10946SSangeeta.Misra@Sun.COM goto swap_old_new;
884*10946SSangeeta.Misra@Sun.COM if (nkid == -1) {
885*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("kstat_chain_update() failed: %s"),
886*10946SSangeeta.Misra@Sun.COM strerror(errno));
887*10946SSangeeta.Misra@Sun.COM rc = ILBADM_LIBERR;
888*10946SSangeeta.Misra@Sun.COM break;
889*10946SSangeeta.Misra@Sun.COM }
890*10946SSangeeta.Misra@Sun.COM
891*10946SSangeeta.Misra@Sun.COM /*
892*10946SSangeeta.Misra@Sun.COM * find out whether the number of rules has changed.
893*10946SSangeeta.Misra@Sun.COM * if so, adjust rcount and _o; if number has increased,
894*10946SSangeeta.Misra@Sun.COM * expand array to hold all rules.
895*10946SSangeeta.Misra@Sun.COM * we only shrink if rlist_sz is larger than both rcount and
896*10946SSangeeta.Misra@Sun.COM * rcount_prev;
897*10946SSangeeta.Misra@Sun.COM */
898*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rulename == NULL)
899*10946SSangeeta.Misra@Sun.COM rcount = i_get_num_kinstances(kctl);
900*10946SSangeeta.Misra@Sun.COM if (rcount != sta->ilbst_rcount) {
901*10946SSangeeta.Misra@Sun.COM sta->ilbst_flags |= ILBST_RULES_CHANGED;
902*10946SSangeeta.Misra@Sun.COM sta->ilbst_rcount_prev = sta->ilbst_rcount;
903*10946SSangeeta.Misra@Sun.COM sta->ilbst_rcount = rcount;
904*10946SSangeeta.Misra@Sun.COM
905*10946SSangeeta.Misra@Sun.COM if (rcount > sta->ilbst_rcount_prev) {
906*10946SSangeeta.Misra@Sun.COM rlist = realloc(sta->ilbst_rlist,
907*10946SSangeeta.Misra@Sun.COM sizeof (*sta->ilbst_rlist) * rcount);
908*10946SSangeeta.Misra@Sun.COM if (rlist == NULL) {
909*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
910*10946SSangeeta.Misra@Sun.COM break;
911*10946SSangeeta.Misra@Sun.COM }
912*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist = rlist;
913*10946SSangeeta.Misra@Sun.COM /* realloc doesn't zero out memory */
914*10946SSangeeta.Misra@Sun.COM for (i = sta->ilbst_rcount_prev;
915*10946SSangeeta.Misra@Sun.COM i < rcount; i++) {
916*10946SSangeeta.Misra@Sun.COM rp = &sta->ilbst_rlist[i];
917*10946SSangeeta.Misra@Sun.COM bzero(rp, sizeof (*rp));
918*10946SSangeeta.Misra@Sun.COM i_set_rlstats_ptr(rp,
919*10946SSangeeta.Misra@Sun.COM sta->ilbst_old_is_old);
920*10946SSangeeta.Misra@Sun.COM }
921*10946SSangeeta.Misra@Sun.COM /*
922*10946SSangeeta.Misra@Sun.COM * even if rlist_sz was > rcount, it's now
923*10946SSangeeta.Misra@Sun.COM * shrunk to rcount
924*10946SSangeeta.Misra@Sun.COM */
925*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist_sz = sta->ilbst_rcount;
926*10946SSangeeta.Misra@Sun.COM }
927*10946SSangeeta.Misra@Sun.COM }
928*10946SSangeeta.Misra@Sun.COM
929*10946SSangeeta.Misra@Sun.COM /*
930*10946SSangeeta.Misra@Sun.COM * we may need to shrink the allocated slots down to the
931*10946SSangeeta.Misra@Sun.COM * actually required number - we need to make sure we
932*10946SSangeeta.Misra@Sun.COM * don't delete old or new stats.
933*10946SSangeeta.Misra@Sun.COM */
934*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rlist_sz > MAX(sta->ilbst_rcount,
935*10946SSangeeta.Misra@Sun.COM sta->ilbst_rcount_prev)) {
936*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist_sz =
937*10946SSangeeta.Misra@Sun.COM MAX(sta->ilbst_rcount, sta->ilbst_rcount_prev);
938*10946SSangeeta.Misra@Sun.COM rlist = realloc(sta->ilbst_rlist,
939*10946SSangeeta.Misra@Sun.COM sizeof (*sta->ilbst_rlist) * sta->ilbst_rlist_sz);
940*10946SSangeeta.Misra@Sun.COM if (rlist == NULL) {
941*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
942*10946SSangeeta.Misra@Sun.COM break;
943*10946SSangeeta.Misra@Sun.COM }
944*10946SSangeeta.Misra@Sun.COM sta->ilbst_rlist = rlist;
945*10946SSangeeta.Misra@Sun.COM }
946*10946SSangeeta.Misra@Sun.COM
947*10946SSangeeta.Misra@Sun.COM /*
948*10946SSangeeta.Misra@Sun.COM * move pointers around so what used to point to "old"
949*10946SSangeeta.Misra@Sun.COM * stats now points to new, and vice versa
950*10946SSangeeta.Misra@Sun.COM * if we're printing absolute numbers, this rigmarole is
951*10946SSangeeta.Misra@Sun.COM * not necessary.
952*10946SSangeeta.Misra@Sun.COM */
953*10946SSangeeta.Misra@Sun.COM swap_old_new:
954*10946SSangeeta.Misra@Sun.COM if (pseudo_abs)
955*10946SSangeeta.Misra@Sun.COM sta->ilbst_flags &= ~ILBST_ABS_NUMBERS;
956*10946SSangeeta.Misra@Sun.COM
957*10946SSangeeta.Misra@Sun.COM if ((sta->ilbst_flags & ILBST_ABS_NUMBERS) == 0) {
958*10946SSangeeta.Misra@Sun.COM sta->ilbst_old_is_old = !sta->ilbst_old_is_old;
959*10946SSangeeta.Misra@Sun.COM i_swap_rl_pointers(sta, rcount);
960*10946SSangeeta.Misra@Sun.COM }
961*10946SSangeeta.Misra@Sun.COM _NOTE(CONSTCOND)
962*10946SSangeeta.Misra@Sun.COM } while (B_TRUE);
963*10946SSangeeta.Misra@Sun.COM
964*10946SSangeeta.Misra@Sun.COM out:
965*10946SSangeeta.Misra@Sun.COM (void) kstat_close(kctl);
966*10946SSangeeta.Misra@Sun.COM if ((rc != ILBADM_OK) && (rc != ILBADM_LIBERR))
967*10946SSangeeta.Misra@Sun.COM ilbadm_err(ilbadm_errstr(rc));
968*10946SSangeeta.Misra@Sun.COM
969*10946SSangeeta.Misra@Sun.COM if (sta->ilbst_rlist != NULL)
970*10946SSangeeta.Misra@Sun.COM free(sta->ilbst_rlist);
971*10946SSangeeta.Misra@Sun.COM
972*10946SSangeeta.Misra@Sun.COM return (rc);
973*10946SSangeeta.Misra@Sun.COM }
974*10946SSangeeta.Misra@Sun.COM
975*10946SSangeeta.Misra@Sun.COM /*
976*10946SSangeeta.Misra@Sun.COM * read ilb's kernel statistics and (periodically) display
977*10946SSangeeta.Misra@Sun.COM * them.
978*10946SSangeeta.Misra@Sun.COM */
979*10946SSangeeta.Misra@Sun.COM /* ARGSUSED */
980*10946SSangeeta.Misra@Sun.COM ilbadm_status_t
ilbadm_show_stats(int argc,char * argv[])981*10946SSangeeta.Misra@Sun.COM ilbadm_show_stats(int argc, char *argv[])
982*10946SSangeeta.Misra@Sun.COM {
983*10946SSangeeta.Misra@Sun.COM ilbadm_status_t rc;
984*10946SSangeeta.Misra@Sun.COM int c;
985*10946SSangeeta.Misra@Sun.COM ilbst_arg_t sta;
986*10946SSangeeta.Misra@Sun.COM int oflags = 0;
987*10946SSangeeta.Misra@Sun.COM char *fieldnames = stat_stdhdrs;
988*10946SSangeeta.Misra@Sun.COM ofmt_field_t *fields = stat_stdfields;
989*10946SSangeeta.Misra@Sun.COM boolean_t r_opt = B_FALSE, s_opt = B_FALSE, i_opt = B_FALSE;
990*10946SSangeeta.Misra@Sun.COM boolean_t o_opt = B_FALSE, p_opt = B_FALSE, t_opt = B_FALSE;
991*10946SSangeeta.Misra@Sun.COM boolean_t v_opt = B_FALSE, A_opt = B_FALSE, d_opt = B_FALSE;
992*10946SSangeeta.Misra@Sun.COM ofmt_status_t oerr;
993*10946SSangeeta.Misra@Sun.COM ofmt_handle_t oh = NULL;
994*10946SSangeeta.Misra@Sun.COM
995*10946SSangeeta.Misra@Sun.COM bzero(&sta, sizeof (sta));
996*10946SSangeeta.Misra@Sun.COM sta.ilbst_interval = 1;
997*10946SSangeeta.Misra@Sun.COM sta.ilbst_count = 1;
998*10946SSangeeta.Misra@Sun.COM
999*10946SSangeeta.Misra@Sun.COM while ((c = getopt(argc, argv, ":tdAr:s:ivo:p")) != -1) {
1000*10946SSangeeta.Misra@Sun.COM switch ((char)c) {
1001*10946SSangeeta.Misra@Sun.COM case 't': sta.ilbst_flags |= ILBST_TIMESTAMP_HEADER;
1002*10946SSangeeta.Misra@Sun.COM t_opt = B_TRUE;
1003*10946SSangeeta.Misra@Sun.COM break;
1004*10946SSangeeta.Misra@Sun.COM case 'd': sta.ilbst_flags |= ILBST_DELTA_INTERVAL;
1005*10946SSangeeta.Misra@Sun.COM d_opt = B_TRUE;
1006*10946SSangeeta.Misra@Sun.COM break;
1007*10946SSangeeta.Misra@Sun.COM case 'A': sta.ilbst_flags |= ILBST_ABS_NUMBERS;
1008*10946SSangeeta.Misra@Sun.COM A_opt = B_TRUE;
1009*10946SSangeeta.Misra@Sun.COM break;
1010*10946SSangeeta.Misra@Sun.COM case 'r': sta.ilbst_rulename = optarg;
1011*10946SSangeeta.Misra@Sun.COM r_opt = B_TRUE;
1012*10946SSangeeta.Misra@Sun.COM break;
1013*10946SSangeeta.Misra@Sun.COM case 's': sta.ilbst_server = optarg;
1014*10946SSangeeta.Misra@Sun.COM s_opt = B_TRUE;
1015*10946SSangeeta.Misra@Sun.COM break;
1016*10946SSangeeta.Misra@Sun.COM case 'i': sta.ilbst_flags |= ILBST_ITEMIZE;
1017*10946SSangeeta.Misra@Sun.COM i_opt = B_TRUE;
1018*10946SSangeeta.Misra@Sun.COM break;
1019*10946SSangeeta.Misra@Sun.COM case 'o': fieldnames = optarg;
1020*10946SSangeeta.Misra@Sun.COM o_opt = B_TRUE;
1021*10946SSangeeta.Misra@Sun.COM break;
1022*10946SSangeeta.Misra@Sun.COM case 'p': oflags |= OFMT_PARSABLE;
1023*10946SSangeeta.Misra@Sun.COM p_opt = B_TRUE;
1024*10946SSangeeta.Misra@Sun.COM break;
1025*10946SSangeeta.Misra@Sun.COM case 'v': sta.ilbst_flags |= ILBST_VERBOSE;
1026*10946SSangeeta.Misra@Sun.COM v_opt = B_TRUE;
1027*10946SSangeeta.Misra@Sun.COM fieldnames = stat_stdv_hdrs;
1028*10946SSangeeta.Misra@Sun.COM break;
1029*10946SSangeeta.Misra@Sun.COM case ':': ilbadm_err(gettext("missing option-argument"
1030*10946SSangeeta.Misra@Sun.COM " detected for %c"), (char)optopt);
1031*10946SSangeeta.Misra@Sun.COM exit(1);
1032*10946SSangeeta.Misra@Sun.COM /* not reached */
1033*10946SSangeeta.Misra@Sun.COM break;
1034*10946SSangeeta.Misra@Sun.COM case '?': /* fallthrough */
1035*10946SSangeeta.Misra@Sun.COM default:
1036*10946SSangeeta.Misra@Sun.COM unknown_opt(argv, optind-1);
1037*10946SSangeeta.Misra@Sun.COM /* not reached */
1038*10946SSangeeta.Misra@Sun.COM break;
1039*10946SSangeeta.Misra@Sun.COM }
1040*10946SSangeeta.Misra@Sun.COM }
1041*10946SSangeeta.Misra@Sun.COM
1042*10946SSangeeta.Misra@Sun.COM if (s_opt && r_opt) {
1043*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("options -s and -r are mutually exclusive"));
1044*10946SSangeeta.Misra@Sun.COM exit(1);
1045*10946SSangeeta.Misra@Sun.COM }
1046*10946SSangeeta.Misra@Sun.COM
1047*10946SSangeeta.Misra@Sun.COM if (i_opt) {
1048*10946SSangeeta.Misra@Sun.COM if (!(s_opt || r_opt)) {
1049*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("option -i requires"
1050*10946SSangeeta.Misra@Sun.COM " either -r or -s"));
1051*10946SSangeeta.Misra@Sun.COM exit(1);
1052*10946SSangeeta.Misra@Sun.COM }
1053*10946SSangeeta.Misra@Sun.COM if (v_opt) {
1054*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("option -i and -v are mutually"
1055*10946SSangeeta.Misra@Sun.COM " exclusive"));
1056*10946SSangeeta.Misra@Sun.COM exit(1);
1057*10946SSangeeta.Misra@Sun.COM }
1058*10946SSangeeta.Misra@Sun.COM /* only use "std" headers if none are specified */
1059*10946SSangeeta.Misra@Sun.COM if (!o_opt)
1060*10946SSangeeta.Misra@Sun.COM if (r_opt)
1061*10946SSangeeta.Misra@Sun.COM fieldnames = stat_itemize_rule_hdrs;
1062*10946SSangeeta.Misra@Sun.COM else /* must be s_opt */
1063*10946SSangeeta.Misra@Sun.COM fieldnames = stat_itemize_server_hdrs;
1064*10946SSangeeta.Misra@Sun.COM fields = stat_itemize_fields;
1065*10946SSangeeta.Misra@Sun.COM }
1066*10946SSangeeta.Misra@Sun.COM
1067*10946SSangeeta.Misra@Sun.COM if (p_opt) {
1068*10946SSangeeta.Misra@Sun.COM if (!o_opt) {
1069*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("option -p requires -o"));
1070*10946SSangeeta.Misra@Sun.COM exit(1);
1071*10946SSangeeta.Misra@Sun.COM }
1072*10946SSangeeta.Misra@Sun.COM if (v_opt) {
1073*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("option -o and -v are mutually"
1074*10946SSangeeta.Misra@Sun.COM " exclusive"));
1075*10946SSangeeta.Misra@Sun.COM exit(1);
1076*10946SSangeeta.Misra@Sun.COM }
1077*10946SSangeeta.Misra@Sun.COM if (strcasecmp(fieldnames, "all") == 0) {
1078*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("option -p requires"
1079*10946SSangeeta.Misra@Sun.COM " explicit field names"));
1080*10946SSangeeta.Misra@Sun.COM exit(1);
1081*10946SSangeeta.Misra@Sun.COM }
1082*10946SSangeeta.Misra@Sun.COM }
1083*10946SSangeeta.Misra@Sun.COM
1084*10946SSangeeta.Misra@Sun.COM if (t_opt) {
1085*10946SSangeeta.Misra@Sun.COM if (v_opt) {
1086*10946SSangeeta.Misra@Sun.COM fieldnames = "all";
1087*10946SSangeeta.Misra@Sun.COM } else {
1088*10946SSangeeta.Misra@Sun.COM int len = strlen(fieldnames) + 6;
1089*10946SSangeeta.Misra@Sun.COM char *fnames;
1090*10946SSangeeta.Misra@Sun.COM
1091*10946SSangeeta.Misra@Sun.COM fnames = malloc(len);
1092*10946SSangeeta.Misra@Sun.COM if (fnames == NULL) {
1093*10946SSangeeta.Misra@Sun.COM rc = ILBADM_ENOMEM;
1094*10946SSangeeta.Misra@Sun.COM return (rc);
1095*10946SSangeeta.Misra@Sun.COM }
1096*10946SSangeeta.Misra@Sun.COM (void) snprintf(fnames, len, "%s,TIME", fieldnames);
1097*10946SSangeeta.Misra@Sun.COM fieldnames = fnames;
1098*10946SSangeeta.Misra@Sun.COM }
1099*10946SSangeeta.Misra@Sun.COM }
1100*10946SSangeeta.Misra@Sun.COM
1101*10946SSangeeta.Misra@Sun.COM if (A_opt && d_opt) {
1102*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("options -d and -A are mutually exclusive"));
1103*10946SSangeeta.Misra@Sun.COM exit(1);
1104*10946SSangeeta.Misra@Sun.COM }
1105*10946SSangeeta.Misra@Sun.COM
1106*10946SSangeeta.Misra@Sun.COM /* find and parse interval and count arguments if present */
1107*10946SSangeeta.Misra@Sun.COM if (optind < argc) {
1108*10946SSangeeta.Misra@Sun.COM sta.ilbst_interval = atoi(argv[optind]);
1109*10946SSangeeta.Misra@Sun.COM if (sta.ilbst_interval < 1) {
1110*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("illegal interval spec %s"),
1111*10946SSangeeta.Misra@Sun.COM argv[optind]);
1112*10946SSangeeta.Misra@Sun.COM exit(1);
1113*10946SSangeeta.Misra@Sun.COM }
1114*10946SSangeeta.Misra@Sun.COM sta.ilbst_count = -1;
1115*10946SSangeeta.Misra@Sun.COM if (++optind < argc) {
1116*10946SSangeeta.Misra@Sun.COM sta.ilbst_count = atoi(argv[optind]);
1117*10946SSangeeta.Misra@Sun.COM if (sta.ilbst_count < 1) {
1118*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("illegal count spec %s"),
1119*10946SSangeeta.Misra@Sun.COM argv[optind]);
1120*10946SSangeeta.Misra@Sun.COM exit(1);
1121*10946SSangeeta.Misra@Sun.COM }
1122*10946SSangeeta.Misra@Sun.COM }
1123*10946SSangeeta.Misra@Sun.COM }
1124*10946SSangeeta.Misra@Sun.COM
1125*10946SSangeeta.Misra@Sun.COM oerr = ofmt_open(fieldnames, fields, oflags, 80, &oh);
1126*10946SSangeeta.Misra@Sun.COM if (oerr != OFMT_SUCCESS) {
1127*10946SSangeeta.Misra@Sun.COM char e[80];
1128*10946SSangeeta.Misra@Sun.COM
1129*10946SSangeeta.Misra@Sun.COM ilbadm_err(gettext("ofmt_open failed: %s"),
1130*10946SSangeeta.Misra@Sun.COM ofmt_strerror(oh, oerr, e, sizeof (e)));
1131*10946SSangeeta.Misra@Sun.COM return (ILBADM_LIBERR);
1132*10946SSangeeta.Misra@Sun.COM }
1133*10946SSangeeta.Misra@Sun.COM
1134*10946SSangeeta.Misra@Sun.COM sta.ilbst_oh = oh;
1135*10946SSangeeta.Misra@Sun.COM
1136*10946SSangeeta.Misra@Sun.COM rc = i_do_show_stats(&sta);
1137*10946SSangeeta.Misra@Sun.COM
1138*10946SSangeeta.Misra@Sun.COM ofmt_close(oh);
1139*10946SSangeeta.Misra@Sun.COM return (rc);
1140*10946SSangeeta.Misra@Sun.COM }
1141