15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
215331Samw
225331Samw /*
23*12508Samw@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245331Samw */
255331Samw
265331Samw /*
275331Samw * smbstat: Server Message Block File System statistics
28*12508Samw@Sun.COM *
29*12508Samw@Sun.COM * The statistics this CLI displays come from two sources:
30*12508Samw@Sun.COM *
31*12508Samw@Sun.COM * 1) The kernel module 'smbsrv'.
32*12508Samw@Sun.COM * 2) The SMB workers task queue statistics the task queue manager of Solaris
33*12508Samw@Sun.COM * maintains.
34*12508Samw@Sun.COM *
35*12508Samw@Sun.COM * The flow of the code is the following:
36*12508Samw@Sun.COM *
37*12508Samw@Sun.COM *
38*12508Samw@Sun.COM * +----------------+
39*12508Samw@Sun.COM * | Initialization |
40*12508Samw@Sun.COM * +----------------+
41*12508Samw@Sun.COM * |
42*12508Samw@Sun.COM * |
43*12508Samw@Sun.COM * v
44*12508Samw@Sun.COM * +--------------------------*
45*12508Samw@Sun.COM * | Take a snapshot the data | <--------+
46*12508Samw@Sun.COM * +--------------------------+ |
47*12508Samw@Sun.COM * | |
48*12508Samw@Sun.COM * | |
49*12508Samw@Sun.COM * v |
50*12508Samw@Sun.COM * +----------------------+ |
51*12508Samw@Sun.COM * | Process the snapshot | |
52*12508Samw@Sun.COM * +----------------------+ |
53*12508Samw@Sun.COM * | |
54*12508Samw@Sun.COM * | |
55*12508Samw@Sun.COM * v |
56*12508Samw@Sun.COM * +------------------------------------+ |
57*12508Samw@Sun.COM * | Print the result of the processing | |
58*12508Samw@Sun.COM * +------------------------------------+ |
59*12508Samw@Sun.COM * | |
60*12508Samw@Sun.COM * | |
61*12508Samw@Sun.COM * v |
62*12508Samw@Sun.COM * Yes --------------- |
63*12508Samw@Sun.COM * +------------ < interval == 0 ? > |
64*12508Samw@Sun.COM * | --------------- |
65*12508Samw@Sun.COM * | | |
66*12508Samw@Sun.COM * | | No |
67*12508Samw@Sun.COM * | v |
68*12508Samw@Sun.COM * | +------------------------+ |
69*12508Samw@Sun.COM * | | Sleep for the duration | ----------+
70*12508Samw@Sun.COM * | | of the interval. |
71*12508Samw@Sun.COM * | +------------------------+
72*12508Samw@Sun.COM * |
73*12508Samw@Sun.COM * +---------------------+
74*12508Samw@Sun.COM * |
75*12508Samw@Sun.COM * v
76*12508Samw@Sun.COM *
77*12508Samw@Sun.COM * Exit
78*12508Samw@Sun.COM *
79*12508Samw@Sun.COM * There are two sets of snapshots. One set for the smbsrv module and the other
80*12508Samw@Sun.COM * for the task queue (SMB workers). Each set contains 2 snapshots. One is
81*12508Samw@Sun.COM * labeled 'current' the other one 'previous'. Their role changes after each
82*12508Samw@Sun.COM * snapshot. The 'current' becomes 'previous' and vice versa.
83*12508Samw@Sun.COM * The first snapshot taken is compared against the data gathered since the
84*12508Samw@Sun.COM * smbsrv module was loaded. Subsequent snapshots will be compared against the
85*12508Samw@Sun.COM * previous snapshot.
865331Samw */
87*12508Samw@Sun.COM
885331Samw #include <stdio.h>
895331Samw #include <stdlib.h>
90*12508Samw@Sun.COM #include <unistd.h>
915331Samw #include <kstat.h>
925331Samw #include <stdarg.h>
935331Samw #include <errno.h>
945331Samw #include <inttypes.h>
955331Samw #include <strings.h>
965331Samw #include <utility.h>
975331Samw #include <libintl.h>
985331Samw #include <zone.h>
99*12508Samw@Sun.COM #include <termios.h>
100*12508Samw@Sun.COM #include <stropts.h>
101*12508Samw@Sun.COM #include <math.h>
102*12508Samw@Sun.COM #include <umem.h>
103*12508Samw@Sun.COM #include <locale.h>
1046432Sas200622 #include <smbsrv/smb_kstat.h>
1055331Samw
106*12508Samw@Sun.COM #if !defined(TEXT_DOMAIN)
107*12508Samw@Sun.COM #define TEXT_DOMAIN "SYS_TEST"
108*12508Samw@Sun.COM #endif /* TEXT_DOMAIN */
109*12508Samw@Sun.COM
110*12508Samw@Sun.COM #define SMBSTAT_ID_NO_CPU -1
111*12508Samw@Sun.COM #define SMBSTAT_SNAPSHOT_COUNT 2 /* Must be a power of 2 */
112*12508Samw@Sun.COM #define SMBSTAT_SNAPSHOT_MASK (SMBSTAT_SNAPSHOT_COUNT - 1)
113*12508Samw@Sun.COM
114*12508Samw@Sun.COM #define SMBSTAT_HELP \
115*12508Samw@Sun.COM "Usage: smbstat [-acnrtuz] [interval]\n" \
116*12508Samw@Sun.COM " -c: display counters\n" \
117*12508Samw@Sun.COM " -t: display throughput\n" \
118*12508Samw@Sun.COM " -u: display utilization\n" \
119*12508Samw@Sun.COM " -r: display requests\n" \
120*12508Samw@Sun.COM " -a: all the requests (supported and unsupported)\n" \
121*12508Samw@Sun.COM " -z: skip the requests not received\n" \
122*12508Samw@Sun.COM " -n: display in alphabetic order\n" \
123*12508Samw@Sun.COM " interval: refresh cycle in seconds\n"
124*12508Samw@Sun.COM
125*12508Samw@Sun.COM #define SMBSRV_COUNTERS_BANNER "\n nbt tcp users trees files pipes\n"
126*12508Samw@Sun.COM #define SMBSRV_COUNTERS_FORMAT "%5d %5d %5d %5d %5d %5d\n"
127*12508Samw@Sun.COM
128*12508Samw@Sun.COM #define SMBSRV_THROUGHPUT_BANNER \
129*12508Samw@Sun.COM "\nrbytes/s tbytes/s reqs/s reads/s writes/s\n"
130*12508Samw@Sun.COM #define SMBSRV_THROUGHPUT_FORMAT \
131*12508Samw@Sun.COM "%1.3e %1.3e %1.3e %1.3e %1.3e\n"
132*12508Samw@Sun.COM
133*12508Samw@Sun.COM #define SMBSRV_UTILIZATION_BANNER \
134*12508Samw@Sun.COM "\n wcnt rcnt wtime rtime" \
135*12508Samw@Sun.COM " w%% r%% u%% sat usr%% sys%% idle%%\n"
136*12508Samw@Sun.COM #define SMBSRV_UTILIZATION_FORMAT \
137*12508Samw@Sun.COM "%1.3e %1.3e %1.3e %1.3e %3.0f %3.0f %3.0f %s " \
138*12508Samw@Sun.COM "%3.0f %3.0f %3.0f\n"
139*12508Samw@Sun.COM
140*12508Samw@Sun.COM #define SMBSRV_REQUESTS_BANNER \
141*12508Samw@Sun.COM "\n%30s code %% rbytes/s tbytes/s req/s rt-mean" \
142*12508Samw@Sun.COM " rt-stddev\n"
143*12508Samw@Sun.COM #define SMBSRV_REQUESTS_FORMAT \
144*12508Samw@Sun.COM "%30s %02X %3.0f %1.3e %1.3e %1.3e %1.3e %1.3e\n"
145*12508Samw@Sun.COM
146*12508Samw@Sun.COM typedef enum {
147*12508Samw@Sun.COM CPU_TICKS_IDLE = 0,
148*12508Samw@Sun.COM CPU_TICKS_USER,
149*12508Samw@Sun.COM CPU_TICKS_KERNEL,
150*12508Samw@Sun.COM CPU_TICKS_SENTINEL
151*12508Samw@Sun.COM } cpu_state_idx_t;
152*12508Samw@Sun.COM
153*12508Samw@Sun.COM typedef struct smbstat_cpu_snapshot {
154*12508Samw@Sun.COM processorid_t cs_id;
155*12508Samw@Sun.COM int cs_state;
156*12508Samw@Sun.COM uint64_t cs_ticks[CPU_TICKS_SENTINEL];
157*12508Samw@Sun.COM } smbstat_cpu_snapshot_t;
1585331Samw
159*12508Samw@Sun.COM typedef struct smbstat_srv_snapshot {
160*12508Samw@Sun.COM hrtime_t ss_snaptime;
161*12508Samw@Sun.COM smbsrv_kstats_t ss_data;
162*12508Samw@Sun.COM } smbstat_srv_snapshot_t;
163*12508Samw@Sun.COM
164*12508Samw@Sun.COM typedef struct smbstat_wrk_snapshot {
165*12508Samw@Sun.COM uint64_t ws_maxthreads;
166*12508Samw@Sun.COM uint64_t ws_bnalloc;
167*12508Samw@Sun.COM } smbstat_wrk_snapshot_t;
168*12508Samw@Sun.COM
169*12508Samw@Sun.COM typedef struct smbstat_req_info {
170*12508Samw@Sun.COM char ri_name[KSTAT_STRLEN];
171*12508Samw@Sun.COM int ri_opcode;
172*12508Samw@Sun.COM double ri_pct;
173*12508Samw@Sun.COM double ri_tbs;
174*12508Samw@Sun.COM double ri_rbs;
175*12508Samw@Sun.COM double ri_rqs;
176*12508Samw@Sun.COM double ri_stddev;
177*12508Samw@Sun.COM double ri_mean;
178*12508Samw@Sun.COM } smbstat_req_info_t;
179*12508Samw@Sun.COM
180*12508Samw@Sun.COM typedef struct smbstat_srv_info {
181*12508Samw@Sun.COM double si_hretime;
182*12508Samw@Sun.COM double si_etime;
183*12508Samw@Sun.COM double si_total_nreqs;
184*12508Samw@Sun.COM /*
185*12508Samw@Sun.COM * Counters
186*12508Samw@Sun.COM */
187*12508Samw@Sun.COM uint32_t si_nbt_sess; /* NBT sessions */
188*12508Samw@Sun.COM uint32_t si_tcp_sess; /* TCP sessions */
189*12508Samw@Sun.COM uint32_t si_users; /* Users logged in */
190*12508Samw@Sun.COM uint32_t si_trees; /* Trees connected */
191*12508Samw@Sun.COM uint32_t si_files; /* Open files */
192*12508Samw@Sun.COM uint32_t si_pipes; /* Open pipes */
193*12508Samw@Sun.COM /*
194*12508Samw@Sun.COM * Throughput of the server
195*12508Samw@Sun.COM */
196*12508Samw@Sun.COM double si_tbs; /* Bytes transmitted / second */
197*12508Samw@Sun.COM double si_rbs; /* Bytes received / second */
198*12508Samw@Sun.COM double si_rqs; /* Requests treated / second */
199*12508Samw@Sun.COM double si_rds; /* Reads treated / second */
200*12508Samw@Sun.COM double si_wrs; /* Writes treated / second */
201*12508Samw@Sun.COM /*
202*12508Samw@Sun.COM * Utilization of the server
203*12508Samw@Sun.COM */
204*12508Samw@Sun.COM double si_wpct; /* */
205*12508Samw@Sun.COM double si_rpct; /* */
206*12508Samw@Sun.COM double si_upct; /* Utilization in % */
207*12508Samw@Sun.COM double si_avw; /* Average number of requests waiting */
208*12508Samw@Sun.COM double si_avr; /* Average number of requests running */
209*12508Samw@Sun.COM double si_wserv; /* Average waiting time */
210*12508Samw@Sun.COM double si_rserv; /* Average running time */
211*12508Samw@Sun.COM boolean_t si_sat;
212*12508Samw@Sun.COM double si_ticks[CPU_TICKS_SENTINEL];
213*12508Samw@Sun.COM /*
214*12508Samw@Sun.COM * Latency & Throughput per request
215*12508Samw@Sun.COM */
216*12508Samw@Sun.COM smbstat_req_info_t si_reqs[SMB_COM_NUM];
217*12508Samw@Sun.COM } smbstat_srv_info_t;
218*12508Samw@Sun.COM
2196432Sas200622 static void smbstat_init(void);
2206432Sas200622 static void smbstat_fini(void);
221*12508Samw@Sun.COM static void smbstat_kstat_snapshot(void);
222*12508Samw@Sun.COM static void smbstat_kstat_process(void);
223*12508Samw@Sun.COM static void smbstat_kstat_print(void);
224*12508Samw@Sun.COM
225*12508Samw@Sun.COM static void smbstat_print_counters(void);
226*12508Samw@Sun.COM static void smbstat_print_throughput(void);
227*12508Samw@Sun.COM static void smbstat_print_utilization(void);
228*12508Samw@Sun.COM static void smbstat_print_requests(void);
229*12508Samw@Sun.COM
230*12508Samw@Sun.COM static void smbstat_cpu_init(void);
231*12508Samw@Sun.COM static void smbstat_cpu_fini(void);
232*12508Samw@Sun.COM static smbstat_cpu_snapshot_t *smbstat_cpu_current_snapshot(void);
233*12508Samw@Sun.COM static smbstat_cpu_snapshot_t *smbstat_cpu_previous_snapshot(void);
234*12508Samw@Sun.COM static void smbstat_cpu_snapshot(void);
235*12508Samw@Sun.COM static void smbstat_cpu_process(void);
236*12508Samw@Sun.COM
237*12508Samw@Sun.COM static void smbstat_wrk_init(void);
238*12508Samw@Sun.COM static void smbstat_wrk_fini(void);
239*12508Samw@Sun.COM static void smbstat_wrk_snapshot(void);
240*12508Samw@Sun.COM static void smbstat_wrk_process(void);
241*12508Samw@Sun.COM static smbstat_wrk_snapshot_t *smbstat_wrk_current_snapshot(void);
242*12508Samw@Sun.COM
243*12508Samw@Sun.COM static void smbstat_srv_init(void);
244*12508Samw@Sun.COM static void smbstat_srv_fini(void);
245*12508Samw@Sun.COM static void smbstat_srv_snapshot(void);
246*12508Samw@Sun.COM static void smbstat_srv_process(void);
247*12508Samw@Sun.COM static void smbstat_srv_process_counters(smbstat_srv_snapshot_t *);
248*12508Samw@Sun.COM static void smbstat_srv_process_throughput(smbstat_srv_snapshot_t *,
249*12508Samw@Sun.COM smbstat_srv_snapshot_t *);
250*12508Samw@Sun.COM static void smbstat_srv_process_utilization(smbstat_srv_snapshot_t *,
251*12508Samw@Sun.COM smbstat_srv_snapshot_t *);
252*12508Samw@Sun.COM static void smbstat_srv_process_requests(smbstat_srv_snapshot_t *,
253*12508Samw@Sun.COM smbstat_srv_snapshot_t *);
254*12508Samw@Sun.COM static smbstat_srv_snapshot_t *smbstat_srv_current_snapshot(void);
255*12508Samw@Sun.COM static smbstat_srv_snapshot_t *smbstat_srv_previous_snapshot(void);
256*12508Samw@Sun.COM
257*12508Samw@Sun.COM static void *smbstat_zalloc(size_t);
258*12508Samw@Sun.COM static void smbstat_free(void *, size_t);
2595331Samw static void smbstat_fail(int, char *, ...);
260*12508Samw@Sun.COM static void smbstat_snapshot_inc_idx(void);
261*12508Samw@Sun.COM static void smbstat_usage(FILE *, int);
262*12508Samw@Sun.COM static uint_t smbstat_strtoi(char const *, char *);
263*12508Samw@Sun.COM static double smbstat_hrtime_delta(hrtime_t, hrtime_t);
264*12508Samw@Sun.COM static double smbstat_sub_64(uint64_t, uint64_t);
265*12508Samw@Sun.COM static void smbstat_req_order(void);
266*12508Samw@Sun.COM static double smbstat_zero(double);
267*12508Samw@Sun.COM static void smbstat_termio_init(void);
268*12508Samw@Sun.COM
269*12508Samw@Sun.COM #pragma does_not_return(smbstat_fail, smbstat_usage)
270*12508Samw@Sun.COM
271*12508Samw@Sun.COM static char *smbstat_cpu_states[CPU_TICKS_SENTINEL] = {
272*12508Samw@Sun.COM "cpu_ticks_idle",
273*12508Samw@Sun.COM "cpu_ticks_user",
274*12508Samw@Sun.COM "cpu_ticks_kernel"
275*12508Samw@Sun.COM };
2765331Samw
277*12508Samw@Sun.COM static boolean_t smbstat_opt_a = B_FALSE; /* all */
278*12508Samw@Sun.COM static boolean_t smbstat_opt_c = B_FALSE; /* counters */
279*12508Samw@Sun.COM static boolean_t smbstat_opt_n = B_FALSE; /* by name */
280*12508Samw@Sun.COM static boolean_t smbstat_opt_u = B_FALSE; /* utilization */
281*12508Samw@Sun.COM static boolean_t smbstat_opt_t = B_FALSE; /* throughput */
282*12508Samw@Sun.COM static boolean_t smbstat_opt_r = B_FALSE; /* requests */
283*12508Samw@Sun.COM static boolean_t smbstat_opt_z = B_FALSE; /* non-zero requests */
2845331Samw
285*12508Samw@Sun.COM static uint_t smbstat_interval = 0;
286*12508Samw@Sun.COM static long smbstat_nrcpus = 0;
287*12508Samw@Sun.COM static kstat_ctl_t *smbstat_ksc = NULL;
288*12508Samw@Sun.COM static kstat_t *smbstat_srv_ksp = NULL;
289*12508Samw@Sun.COM static kstat_t *smbstat_wrk_ksp = NULL;
290*12508Samw@Sun.COM static struct winsize smbstat_ws;
291*12508Samw@Sun.COM static uint16_t smbstat_rows = 0;
292*12508Samw@Sun.COM
293*12508Samw@Sun.COM static int smbstat_snapshot_idx = 0;
294*12508Samw@Sun.COM static smbstat_cpu_snapshot_t *smbstat_cpu_snapshots[SMBSTAT_SNAPSHOT_COUNT];
295*12508Samw@Sun.COM static smbstat_srv_snapshot_t smbstat_srv_snapshots[SMBSTAT_SNAPSHOT_COUNT];
296*12508Samw@Sun.COM static smbstat_wrk_snapshot_t smbstat_wrk_snapshots[SMBSTAT_SNAPSHOT_COUNT];
297*12508Samw@Sun.COM static smbstat_srv_info_t smbstat_srv_info;
298*12508Samw@Sun.COM
299*12508Samw@Sun.COM /*
300*12508Samw@Sun.COM * main
301*12508Samw@Sun.COM */
3025331Samw int
main(int argc,char * argv[])3035331Samw main(int argc, char *argv[])
3045331Samw {
305*12508Samw@Sun.COM int c;
306*12508Samw@Sun.COM
307*12508Samw@Sun.COM (void) setlocale(LC_ALL, "");
308*12508Samw@Sun.COM (void) textdomain(TEXT_DOMAIN);
3095331Samw
3105331Samw if (getzoneid() != GLOBAL_ZONEID) {
3115331Samw (void) fprintf(stderr,
3125331Samw gettext("%s: Cannot execute in non-global zone.\n"),
3135331Samw argv[0]);
3145331Samw return (0);
3155331Samw }
3165331Samw
3175331Samw if (is_system_labeled()) {
3185331Samw (void) fprintf(stderr,
3195331Samw gettext("%s: Trusted Extensions not supported.\n"),
3205331Samw argv[0]);
3215331Samw return (0);
3225331Samw }
3235331Samw
324*12508Samw@Sun.COM while ((c = getopt(argc, argv, "achnrtuz")) != EOF) {
3255331Samw switch (c) {
326*12508Samw@Sun.COM case 'a':
327*12508Samw@Sun.COM smbstat_opt_a = B_TRUE;
328*12508Samw@Sun.COM break;
329*12508Samw@Sun.COM case 'n':
330*12508Samw@Sun.COM smbstat_opt_n = B_TRUE;
331*12508Samw@Sun.COM break;
332*12508Samw@Sun.COM case 'u':
333*12508Samw@Sun.COM smbstat_opt_u = B_TRUE;
334*12508Samw@Sun.COM break;
335*12508Samw@Sun.COM case 'c':
336*12508Samw@Sun.COM smbstat_opt_c = B_TRUE;
3375331Samw break;
338*12508Samw@Sun.COM case 'r':
339*12508Samw@Sun.COM smbstat_opt_r = B_TRUE;
340*12508Samw@Sun.COM break;
341*12508Samw@Sun.COM case 't':
342*12508Samw@Sun.COM smbstat_opt_t = B_TRUE;
3435331Samw break;
344*12508Samw@Sun.COM case 'z':
345*12508Samw@Sun.COM smbstat_opt_z = B_TRUE;
346*12508Samw@Sun.COM break;
347*12508Samw@Sun.COM case 'h':
348*12508Samw@Sun.COM smbstat_usage(stdout, 0);
3495331Samw default:
350*12508Samw@Sun.COM smbstat_usage(stderr, 1);
3515331Samw }
3525331Samw }
3535331Samw
354*12508Samw@Sun.COM if (!smbstat_opt_u &&
355*12508Samw@Sun.COM !smbstat_opt_c &&
356*12508Samw@Sun.COM !smbstat_opt_r &&
357*12508Samw@Sun.COM !smbstat_opt_t) {
358*12508Samw@Sun.COM /* Default options when none is specified. */
359*12508Samw@Sun.COM smbstat_opt_u = B_TRUE;
360*12508Samw@Sun.COM smbstat_opt_t = B_TRUE;
361*12508Samw@Sun.COM }
362*12508Samw@Sun.COM
363*12508Samw@Sun.COM if (optind < argc) {
364*12508Samw@Sun.COM smbstat_interval =
365*12508Samw@Sun.COM smbstat_strtoi(argv[optind], "invalid count");
366*12508Samw@Sun.COM optind++;
3675331Samw }
3685331Samw
369*12508Samw@Sun.COM if ((argc - optind) > 1)
370*12508Samw@Sun.COM smbstat_usage(stderr, 1);
3715331Samw
372*12508Samw@Sun.COM (void) atexit(smbstat_fini);
373*12508Samw@Sun.COM smbstat_init();
374*12508Samw@Sun.COM for (;;) {
375*12508Samw@Sun.COM smbstat_kstat_snapshot();
376*12508Samw@Sun.COM smbstat_kstat_process();
377*12508Samw@Sun.COM smbstat_kstat_print();
378*12508Samw@Sun.COM if (smbstat_interval == 0)
379*12508Samw@Sun.COM break;
380*12508Samw@Sun.COM (void) sleep(smbstat_interval);
381*12508Samw@Sun.COM smbstat_snapshot_inc_idx();
3825331Samw }
3835331Samw return (0);
3845331Samw }
3855331Samw
386*12508Samw@Sun.COM /*
387*12508Samw@Sun.COM * smbstat_init
388*12508Samw@Sun.COM *
389*12508Samw@Sun.COM * Global initialization.
390*12508Samw@Sun.COM */
391*12508Samw@Sun.COM static void
smbstat_init(void)392*12508Samw@Sun.COM smbstat_init(void)
393*12508Samw@Sun.COM {
394*12508Samw@Sun.COM if ((smbstat_ksc = kstat_open()) == NULL)
395*12508Samw@Sun.COM smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat"));
3965331Samw
397*12508Samw@Sun.COM smbstat_cpu_init();
398*12508Samw@Sun.COM smbstat_srv_init();
399*12508Samw@Sun.COM smbstat_wrk_init();
400*12508Samw@Sun.COM smbstat_req_order();
401*12508Samw@Sun.COM }
402*12508Samw@Sun.COM
403*12508Samw@Sun.COM /*
404*12508Samw@Sun.COM * smbstat_fini
405*12508Samw@Sun.COM *
406*12508Samw@Sun.COM * Releases the resources smbstat_init() allocated.
407*12508Samw@Sun.COM */
408*12508Samw@Sun.COM static void
smbstat_fini(void)409*12508Samw@Sun.COM smbstat_fini(void)
410*12508Samw@Sun.COM {
411*12508Samw@Sun.COM smbstat_wrk_fini();
412*12508Samw@Sun.COM smbstat_srv_fini();
413*12508Samw@Sun.COM smbstat_cpu_fini();
414*12508Samw@Sun.COM (void) kstat_close(smbstat_ksc);
415*12508Samw@Sun.COM }
416*12508Samw@Sun.COM
417*12508Samw@Sun.COM /*
418*12508Samw@Sun.COM * smbstat_kstat_snapshot
419*12508Samw@Sun.COM *
420*12508Samw@Sun.COM * Takes a snapshot of the data.
421*12508Samw@Sun.COM */
422*12508Samw@Sun.COM static void
smbstat_kstat_snapshot(void)423*12508Samw@Sun.COM smbstat_kstat_snapshot(void)
4245331Samw {
425*12508Samw@Sun.COM smbstat_cpu_snapshot();
426*12508Samw@Sun.COM smbstat_srv_snapshot();
427*12508Samw@Sun.COM smbstat_wrk_snapshot();
428*12508Samw@Sun.COM }
429*12508Samw@Sun.COM
430*12508Samw@Sun.COM /*
431*12508Samw@Sun.COM * smbstat_kstat_process
432*12508Samw@Sun.COM */
433*12508Samw@Sun.COM static void
smbstat_kstat_process(void)434*12508Samw@Sun.COM smbstat_kstat_process(void)
435*12508Samw@Sun.COM {
436*12508Samw@Sun.COM smbstat_cpu_process();
437*12508Samw@Sun.COM smbstat_srv_process();
438*12508Samw@Sun.COM smbstat_wrk_process();
439*12508Samw@Sun.COM }
440*12508Samw@Sun.COM
441*12508Samw@Sun.COM /*
442*12508Samw@Sun.COM * smbstat_kstat_print
443*12508Samw@Sun.COM *
444*12508Samw@Sun.COM * Print the data processed.
445*12508Samw@Sun.COM */
446*12508Samw@Sun.COM static void
smbstat_kstat_print(void)447*12508Samw@Sun.COM smbstat_kstat_print(void)
448*12508Samw@Sun.COM {
449*12508Samw@Sun.COM smbstat_termio_init();
450*12508Samw@Sun.COM smbstat_print_counters();
451*12508Samw@Sun.COM smbstat_print_throughput();
452*12508Samw@Sun.COM smbstat_print_utilization();
453*12508Samw@Sun.COM smbstat_print_requests();
4545331Samw }
4555331Samw
456*12508Samw@Sun.COM /*
457*12508Samw@Sun.COM * smbstat_print_counters
458*12508Samw@Sun.COM *
459*12508Samw@Sun.COM * Displays the SMB server counters (session, users...).
460*12508Samw@Sun.COM */
461*12508Samw@Sun.COM static void
smbstat_print_counters(void)462*12508Samw@Sun.COM smbstat_print_counters(void)
463*12508Samw@Sun.COM {
464*12508Samw@Sun.COM if (!smbstat_opt_c)
465*12508Samw@Sun.COM return;
466*12508Samw@Sun.COM
467*12508Samw@Sun.COM if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_t ||
468*12508Samw@Sun.COM (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
469*12508Samw@Sun.COM (void) printf(SMBSRV_COUNTERS_BANNER);
470*12508Samw@Sun.COM smbstat_rows = 1;
471*12508Samw@Sun.COM }
472*12508Samw@Sun.COM
473*12508Samw@Sun.COM (void) printf(SMBSRV_COUNTERS_FORMAT,
474*12508Samw@Sun.COM smbstat_srv_info.si_nbt_sess,
475*12508Samw@Sun.COM smbstat_srv_info.si_tcp_sess,
476*12508Samw@Sun.COM smbstat_srv_info.si_users,
477*12508Samw@Sun.COM smbstat_srv_info.si_trees,
478*12508Samw@Sun.COM smbstat_srv_info.si_files,
479*12508Samw@Sun.COM smbstat_srv_info.si_pipes);
480*12508Samw@Sun.COM
481*12508Samw@Sun.COM ++smbstat_rows;
482*12508Samw@Sun.COM }
483*12508Samw@Sun.COM /*
484*12508Samw@Sun.COM * smbstat_print_throughput
485*12508Samw@Sun.COM *
486*12508Samw@Sun.COM * Formats the SMB server throughput output.
487*12508Samw@Sun.COM */
488*12508Samw@Sun.COM static void
smbstat_print_throughput(void)489*12508Samw@Sun.COM smbstat_print_throughput(void)
4905331Samw {
491*12508Samw@Sun.COM if (!smbstat_opt_t)
492*12508Samw@Sun.COM return;
493*12508Samw@Sun.COM
494*12508Samw@Sun.COM if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_c ||
495*12508Samw@Sun.COM (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
496*12508Samw@Sun.COM (void) printf(SMBSRV_THROUGHPUT_BANNER);
497*12508Samw@Sun.COM smbstat_rows = 1;
498*12508Samw@Sun.COM }
499*12508Samw@Sun.COM (void) printf(SMBSRV_THROUGHPUT_FORMAT,
500*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_rbs),
501*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_tbs),
502*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_rqs),
503*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_rds),
504*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_wrs));
505*12508Samw@Sun.COM
506*12508Samw@Sun.COM ++smbstat_rows;
507*12508Samw@Sun.COM }
508*12508Samw@Sun.COM
509*12508Samw@Sun.COM /*
510*12508Samw@Sun.COM * smbstat_print_utilization
511*12508Samw@Sun.COM */
512*12508Samw@Sun.COM static void
smbstat_print_utilization(void)513*12508Samw@Sun.COM smbstat_print_utilization(void)
514*12508Samw@Sun.COM {
515*12508Samw@Sun.COM char *sat;
516*12508Samw@Sun.COM if (!smbstat_opt_u)
517*12508Samw@Sun.COM return;
518*12508Samw@Sun.COM
519*12508Samw@Sun.COM if (smbstat_opt_t || smbstat_opt_r || smbstat_opt_c ||
520*12508Samw@Sun.COM (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
521*12508Samw@Sun.COM (void) printf(SMBSRV_UTILIZATION_BANNER);
522*12508Samw@Sun.COM smbstat_rows = 1;
523*12508Samw@Sun.COM }
524*12508Samw@Sun.COM
525*12508Samw@Sun.COM if (smbstat_srv_info.si_sat)
526*12508Samw@Sun.COM sat = "yes";
527*12508Samw@Sun.COM else
528*12508Samw@Sun.COM sat = "no ";
529*12508Samw@Sun.COM
530*12508Samw@Sun.COM (void) printf(SMBSRV_UTILIZATION_FORMAT,
531*12508Samw@Sun.COM smbstat_srv_info.si_avw,
532*12508Samw@Sun.COM smbstat_srv_info.si_avr,
533*12508Samw@Sun.COM smbstat_srv_info.si_wserv,
534*12508Samw@Sun.COM smbstat_srv_info.si_rserv,
535*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_wpct),
536*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_rpct),
537*12508Samw@Sun.COM smbstat_zero(smbstat_srv_info.si_upct),
538*12508Samw@Sun.COM sat,
539*12508Samw@Sun.COM smbstat_srv_info.si_ticks[CPU_TICKS_USER],
540*12508Samw@Sun.COM smbstat_srv_info.si_ticks[CPU_TICKS_KERNEL],
541*12508Samw@Sun.COM smbstat_srv_info.si_ticks[CPU_TICKS_IDLE]);
542*12508Samw@Sun.COM
543*12508Samw@Sun.COM ++smbstat_rows;
5445331Samw }
5455331Samw
546*12508Samw@Sun.COM /*
547*12508Samw@Sun.COM * smbstat_print_requests
548*12508Samw@Sun.COM */
5495331Samw static void
smbstat_print_requests(void)550*12508Samw@Sun.COM smbstat_print_requests(void)
5515331Samw {
552*12508Samw@Sun.COM smbstat_req_info_t *prq;
553*12508Samw@Sun.COM int i;
5545331Samw
555*12508Samw@Sun.COM if (!smbstat_opt_r)
5565331Samw return;
5575331Samw
558*12508Samw@Sun.COM prq = smbstat_srv_info.si_reqs;
559*12508Samw@Sun.COM
560*12508Samw@Sun.COM (void) printf(SMBSRV_REQUESTS_BANNER, " ");
561*12508Samw@Sun.COM
562*12508Samw@Sun.COM for (i = 0; i < SMB_COM_NUM; i++) {
563*12508Samw@Sun.COM if (!smbstat_opt_a &&
564*12508Samw@Sun.COM strncmp(prq[i].ri_name, "Invalid", sizeof ("Invalid")) == 0)
565*12508Samw@Sun.COM continue;
566*12508Samw@Sun.COM
567*12508Samw@Sun.COM if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
568*12508Samw@Sun.COM (void) printf(SMBSRV_REQUESTS_FORMAT,
569*12508Samw@Sun.COM prq[i].ri_name,
570*12508Samw@Sun.COM prq[i].ri_opcode,
571*12508Samw@Sun.COM smbstat_zero(prq[i].ri_pct),
572*12508Samw@Sun.COM smbstat_zero(prq[i].ri_rbs),
573*12508Samw@Sun.COM smbstat_zero(prq[i].ri_tbs),
574*12508Samw@Sun.COM smbstat_zero(prq[i].ri_rqs),
575*12508Samw@Sun.COM prq[i].ri_mean,
576*12508Samw@Sun.COM prq[i].ri_stddev);
577*12508Samw@Sun.COM }
578*12508Samw@Sun.COM }
579*12508Samw@Sun.COM }
580*12508Samw@Sun.COM
581*12508Samw@Sun.COM /*
582*12508Samw@Sun.COM * smbstat_cpu_init
583*12508Samw@Sun.COM */
584*12508Samw@Sun.COM static void
smbstat_cpu_init(void)585*12508Samw@Sun.COM smbstat_cpu_init(void)
586*12508Samw@Sun.COM {
587*12508Samw@Sun.COM size_t size;
588*12508Samw@Sun.COM int i;
589*12508Samw@Sun.COM
590*12508Samw@Sun.COM smbstat_nrcpus = sysconf(_SC_CPUID_MAX) + 1;
591*12508Samw@Sun.COM size = smbstat_nrcpus * sizeof (smbstat_cpu_snapshot_t);
5926432Sas200622
593*12508Samw@Sun.COM for (i = 0; i < SMBSTAT_SNAPSHOT_COUNT; i++)
594*12508Samw@Sun.COM smbstat_cpu_snapshots[i] = smbstat_zalloc(size);
595*12508Samw@Sun.COM }
596*12508Samw@Sun.COM
597*12508Samw@Sun.COM /*
598*12508Samw@Sun.COM * smbstat_cpu_fini
599*12508Samw@Sun.COM */
600*12508Samw@Sun.COM static void
smbstat_cpu_fini(void)601*12508Samw@Sun.COM smbstat_cpu_fini(void)
602*12508Samw@Sun.COM {
603*12508Samw@Sun.COM size_t size;
604*12508Samw@Sun.COM int i;
605*12508Samw@Sun.COM
606*12508Samw@Sun.COM size = smbstat_nrcpus * sizeof (smbstat_cpu_snapshot_t);
607*12508Samw@Sun.COM
608*12508Samw@Sun.COM for (i = 0; i < SMBSTAT_SNAPSHOT_COUNT; i++)
609*12508Samw@Sun.COM smbstat_free(smbstat_cpu_snapshots[i], size);
610*12508Samw@Sun.COM }
611*12508Samw@Sun.COM
612*12508Samw@Sun.COM /*
613*12508Samw@Sun.COM * smbstat_cpu_current_snapshot
614*12508Samw@Sun.COM */
615*12508Samw@Sun.COM static smbstat_cpu_snapshot_t *
smbstat_cpu_current_snapshot(void)616*12508Samw@Sun.COM smbstat_cpu_current_snapshot(void)
617*12508Samw@Sun.COM {
618*12508Samw@Sun.COM return (smbstat_cpu_snapshots[smbstat_snapshot_idx]);
619*12508Samw@Sun.COM }
620*12508Samw@Sun.COM
621*12508Samw@Sun.COM /*
622*12508Samw@Sun.COM * smbstat_cpu_previous_snapshot
623*12508Samw@Sun.COM */
624*12508Samw@Sun.COM static smbstat_cpu_snapshot_t *
smbstat_cpu_previous_snapshot(void)625*12508Samw@Sun.COM smbstat_cpu_previous_snapshot(void)
626*12508Samw@Sun.COM {
627*12508Samw@Sun.COM int idx;
628*12508Samw@Sun.COM
629*12508Samw@Sun.COM idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
630*12508Samw@Sun.COM return (smbstat_cpu_snapshots[idx]);
631*12508Samw@Sun.COM }
6326432Sas200622
633*12508Samw@Sun.COM /*
634*12508Samw@Sun.COM * smbstat_cpu_snapshot
635*12508Samw@Sun.COM */
636*12508Samw@Sun.COM static void
smbstat_cpu_snapshot(void)637*12508Samw@Sun.COM smbstat_cpu_snapshot(void)
638*12508Samw@Sun.COM {
639*12508Samw@Sun.COM kstat_t *ksp;
640*12508Samw@Sun.COM kstat_named_t *ksn;
641*12508Samw@Sun.COM smbstat_cpu_snapshot_t *curr;
642*12508Samw@Sun.COM long i;
643*12508Samw@Sun.COM int j;
644*12508Samw@Sun.COM
645*12508Samw@Sun.COM curr = smbstat_cpu_current_snapshot();
646*12508Samw@Sun.COM
647*12508Samw@Sun.COM for (i = 0; i < smbstat_nrcpus; i++, curr++) {
648*12508Samw@Sun.COM curr->cs_id = SMBSTAT_ID_NO_CPU;
649*12508Samw@Sun.COM curr->cs_state = p_online(i, P_STATUS);
650*12508Samw@Sun.COM /* If no valid CPU is present, move on to the next one */
651*12508Samw@Sun.COM if (curr->cs_state == -1)
652*12508Samw@Sun.COM continue;
653*12508Samw@Sun.COM
654*12508Samw@Sun.COM curr->cs_id = i;
655*12508Samw@Sun.COM
656*12508Samw@Sun.COM ksp = kstat_lookup(smbstat_ksc, "cpu", i, "sys");
657*12508Samw@Sun.COM if (ksp == NULL)
658*12508Samw@Sun.COM smbstat_fail(1,
659*12508Samw@Sun.COM gettext("kstat_lookup('cpu sys %d') failed"), i);
660*12508Samw@Sun.COM
661*12508Samw@Sun.COM if (kstat_read(smbstat_ksc, ksp, NULL) == -1)
662*12508Samw@Sun.COM smbstat_fail(1,
663*12508Samw@Sun.COM gettext("kstat_read('cpu sys %d') failed"), i);
664*12508Samw@Sun.COM
665*12508Samw@Sun.COM for (j = 0; j < CPU_TICKS_SENTINEL; j++) {
666*12508Samw@Sun.COM ksn = kstat_data_lookup(ksp, smbstat_cpu_states[j]);
667*12508Samw@Sun.COM if (ksn == NULL)
668*12508Samw@Sun.COM smbstat_fail(1,
669*12508Samw@Sun.COM gettext("kstat_data_lookup('%s') failed"),
670*12508Samw@Sun.COM smbstat_cpu_states[j]);
671*12508Samw@Sun.COM curr->cs_ticks[j] = ksn->value.ui64;
6726432Sas200622 }
673*12508Samw@Sun.COM }
674*12508Samw@Sun.COM }
675*12508Samw@Sun.COM
676*12508Samw@Sun.COM /*
677*12508Samw@Sun.COM * smbstat_cpu_process
678*12508Samw@Sun.COM */
679*12508Samw@Sun.COM static void
smbstat_cpu_process(void)680*12508Samw@Sun.COM smbstat_cpu_process(void)
681*12508Samw@Sun.COM {
682*12508Samw@Sun.COM smbstat_cpu_snapshot_t *curr, *prev;
683*12508Samw@Sun.COM double total_ticks;
684*12508Samw@Sun.COM double agg_ticks[CPU_TICKS_SENTINEL];
685*12508Samw@Sun.COM int i, j;
686*12508Samw@Sun.COM
687*12508Samw@Sun.COM curr = smbstat_cpu_current_snapshot();
688*12508Samw@Sun.COM prev = smbstat_cpu_previous_snapshot();
689*12508Samw@Sun.COM bzero(agg_ticks, sizeof (agg_ticks));
690*12508Samw@Sun.COM total_ticks = 0;
691*12508Samw@Sun.COM
692*12508Samw@Sun.COM for (i = 0; i < smbstat_nrcpus; i++, curr++, prev++) {
693*12508Samw@Sun.COM for (j = 0; j < CPU_TICKS_SENTINEL; j++) {
694*12508Samw@Sun.COM agg_ticks[j] += smbstat_sub_64(curr->cs_ticks[j],
695*12508Samw@Sun.COM prev->cs_ticks[j]);
696*12508Samw@Sun.COM total_ticks += smbstat_sub_64(curr->cs_ticks[j],
697*12508Samw@Sun.COM prev->cs_ticks[j]);
6986432Sas200622 }
6996432Sas200622 }
700*12508Samw@Sun.COM
701*12508Samw@Sun.COM for (j = 0; j < CPU_TICKS_SENTINEL; j++)
702*12508Samw@Sun.COM smbstat_srv_info.si_ticks[j] =
703*12508Samw@Sun.COM (agg_ticks[j] * 100.0) / total_ticks;
704*12508Samw@Sun.COM }
705*12508Samw@Sun.COM
706*12508Samw@Sun.COM /*
707*12508Samw@Sun.COM * smbstat_wrk_init
708*12508Samw@Sun.COM */
709*12508Samw@Sun.COM static void
smbstat_wrk_init(void)710*12508Samw@Sun.COM smbstat_wrk_init(void)
711*12508Samw@Sun.COM {
712*12508Samw@Sun.COM smbstat_wrk_ksp =
713*12508Samw@Sun.COM kstat_lookup(smbstat_ksc, "unix", -1, SMBSRV_KSTAT_WORKERS);
714*12508Samw@Sun.COM if (smbstat_wrk_ksp == NULL)
715*12508Samw@Sun.COM smbstat_fail(1,
716*12508Samw@Sun.COM gettext("cannot retrieve smbsrv workers kstat\n"));
7175331Samw }
7185331Samw
7195331Samw static void
smbstat_wrk_fini(void)720*12508Samw@Sun.COM smbstat_wrk_fini(void)
721*12508Samw@Sun.COM {
722*12508Samw@Sun.COM smbstat_wrk_ksp = NULL;
723*12508Samw@Sun.COM }
724*12508Samw@Sun.COM
725*12508Samw@Sun.COM /*
726*12508Samw@Sun.COM * smbstat_wrk_snapshot
727*12508Samw@Sun.COM */
728*12508Samw@Sun.COM static void
smbstat_wrk_snapshot(void)729*12508Samw@Sun.COM smbstat_wrk_snapshot(void)
7305331Samw {
731*12508Samw@Sun.COM smbstat_wrk_snapshot_t *curr;
732*12508Samw@Sun.COM kstat_named_t *kn;
733*12508Samw@Sun.COM
734*12508Samw@Sun.COM curr = smbstat_wrk_current_snapshot();
735*12508Samw@Sun.COM
736*12508Samw@Sun.COM if (kstat_read(smbstat_ksc, smbstat_wrk_ksp, NULL) == -1)
737*12508Samw@Sun.COM smbstat_fail(1, gettext("kstat_read('%s') failed"),
738*12508Samw@Sun.COM smbstat_wrk_ksp->ks_name);
739*12508Samw@Sun.COM
740*12508Samw@Sun.COM kn = kstat_data_lookup(smbstat_wrk_ksp, "maxthreads");
741*12508Samw@Sun.COM if ((kn == NULL) || (kn->data_type != KSTAT_DATA_UINT64))
742*12508Samw@Sun.COM smbstat_fail(1, gettext("kstat_read('%s') failed"),
743*12508Samw@Sun.COM "maxthreads");
744*12508Samw@Sun.COM curr->ws_maxthreads = kn->value.ui64;
7455331Samw
746*12508Samw@Sun.COM kn = kstat_data_lookup(smbstat_wrk_ksp, "bnalloc");
747*12508Samw@Sun.COM if ((kn == NULL) || (kn->data_type != KSTAT_DATA_UINT64))
748*12508Samw@Sun.COM smbstat_fail(1, gettext("kstat_read('%s') failed"),
749*12508Samw@Sun.COM "bnalloc");
750*12508Samw@Sun.COM curr->ws_bnalloc = kn->value.ui64;
751*12508Samw@Sun.COM }
752*12508Samw@Sun.COM
753*12508Samw@Sun.COM /*
754*12508Samw@Sun.COM * smbstat_wrk_process
755*12508Samw@Sun.COM */
756*12508Samw@Sun.COM static void
smbstat_wrk_process(void)757*12508Samw@Sun.COM smbstat_wrk_process(void)
758*12508Samw@Sun.COM {
759*12508Samw@Sun.COM smbstat_wrk_snapshot_t *curr;
7605331Samw
761*12508Samw@Sun.COM curr = smbstat_wrk_current_snapshot();
762*12508Samw@Sun.COM
763*12508Samw@Sun.COM if (curr->ws_maxthreads >= curr->ws_bnalloc)
764*12508Samw@Sun.COM smbstat_srv_info.si_sat = B_TRUE;
765*12508Samw@Sun.COM else
766*12508Samw@Sun.COM smbstat_srv_info.si_sat = B_FALSE;
767*12508Samw@Sun.COM }
768*12508Samw@Sun.COM
769*12508Samw@Sun.COM /*
770*12508Samw@Sun.COM * smbstat_wrk_current_snapshot
771*12508Samw@Sun.COM */
772*12508Samw@Sun.COM static smbstat_wrk_snapshot_t *
smbstat_wrk_current_snapshot(void)773*12508Samw@Sun.COM smbstat_wrk_current_snapshot(void)
774*12508Samw@Sun.COM {
775*12508Samw@Sun.COM return (&smbstat_wrk_snapshots[smbstat_snapshot_idx]);
7765331Samw }
7775331Samw
778*12508Samw@Sun.COM /*
779*12508Samw@Sun.COM * smbstat_srv_init
780*12508Samw@Sun.COM */
7815331Samw static void
smbstat_srv_init(void)782*12508Samw@Sun.COM smbstat_srv_init(void)
7835331Samw {
784*12508Samw@Sun.COM smbstat_srv_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
785*12508Samw@Sun.COM getzoneid(), SMBSRV_KSTAT_STATISTICS);
786*12508Samw@Sun.COM if (smbstat_srv_ksp == NULL)
787*12508Samw@Sun.COM smbstat_fail(1, gettext("cannot retrieve smbsrv kstat\n"));
788*12508Samw@Sun.COM }
7896432Sas200622
790*12508Samw@Sun.COM /*
791*12508Samw@Sun.COM * smbstat_srv_fini
792*12508Samw@Sun.COM */
793*12508Samw@Sun.COM static void
smbstat_srv_fini(void)794*12508Samw@Sun.COM smbstat_srv_fini(void)
795*12508Samw@Sun.COM {
796*12508Samw@Sun.COM smbstat_srv_ksp = NULL;
7975331Samw }
7985331Samw
799*12508Samw@Sun.COM /*
800*12508Samw@Sun.COM * smbstat_srv_snapshot
801*12508Samw@Sun.COM *
802*12508Samw@Sun.COM * Take a snapshot of the smbsrv module statistics.
803*12508Samw@Sun.COM */
8046432Sas200622 static void
smbstat_srv_snapshot(void)805*12508Samw@Sun.COM smbstat_srv_snapshot(void)
806*12508Samw@Sun.COM {
807*12508Samw@Sun.COM smbstat_srv_snapshot_t *curr;
808*12508Samw@Sun.COM
809*12508Samw@Sun.COM curr = smbstat_srv_current_snapshot();
810*12508Samw@Sun.COM
811*12508Samw@Sun.COM if ((kstat_read(smbstat_ksc, smbstat_srv_ksp, NULL) == -1) ||
812*12508Samw@Sun.COM (smbstat_srv_ksp->ks_data_size != sizeof (curr->ss_data)))
813*12508Samw@Sun.COM smbstat_fail(1, gettext("kstat_read('%s') failed"),
814*12508Samw@Sun.COM smbstat_srv_ksp->ks_name);
815*12508Samw@Sun.COM
816*12508Samw@Sun.COM curr->ss_snaptime = smbstat_srv_ksp->ks_snaptime;
817*12508Samw@Sun.COM bcopy(smbstat_srv_ksp->ks_data, &curr->ss_data, sizeof (curr->ss_data));
818*12508Samw@Sun.COM }
819*12508Samw@Sun.COM
820*12508Samw@Sun.COM /*
821*12508Samw@Sun.COM * smbstat_srv_process
822*12508Samw@Sun.COM *
823*12508Samw@Sun.COM * Processes the snapshot data.
824*12508Samw@Sun.COM */
825*12508Samw@Sun.COM static void
smbstat_srv_process(void)826*12508Samw@Sun.COM smbstat_srv_process(void)
8276432Sas200622 {
828*12508Samw@Sun.COM smbstat_srv_snapshot_t *curr, *prev;
829*12508Samw@Sun.COM
830*12508Samw@Sun.COM curr = smbstat_srv_current_snapshot();
831*12508Samw@Sun.COM prev = smbstat_srv_previous_snapshot();
832*12508Samw@Sun.COM
833*12508Samw@Sun.COM if (prev->ss_snaptime == 0)
834*12508Samw@Sun.COM smbstat_srv_info.si_hretime =
835*12508Samw@Sun.COM smbstat_hrtime_delta(curr->ss_data.ks_start_time,
836*12508Samw@Sun.COM curr->ss_snaptime);
837*12508Samw@Sun.COM else
838*12508Samw@Sun.COM smbstat_srv_info.si_hretime =
839*12508Samw@Sun.COM smbstat_hrtime_delta(prev->ss_snaptime, curr->ss_snaptime);
840*12508Samw@Sun.COM
841*12508Samw@Sun.COM smbstat_srv_info.si_etime = smbstat_srv_info.si_hretime / NANOSEC;
842*12508Samw@Sun.COM smbstat_srv_info.si_total_nreqs =
843*12508Samw@Sun.COM smbstat_sub_64(curr->ss_data.ks_nreq, prev->ss_data.ks_nreq);
844*12508Samw@Sun.COM
845*12508Samw@Sun.COM if (smbstat_opt_c)
846*12508Samw@Sun.COM smbstat_srv_process_counters(curr);
847*12508Samw@Sun.COM if (smbstat_opt_t)
848*12508Samw@Sun.COM smbstat_srv_process_throughput(curr, prev);
849*12508Samw@Sun.COM if (smbstat_opt_u)
850*12508Samw@Sun.COM smbstat_srv_process_utilization(curr, prev);
851*12508Samw@Sun.COM if (smbstat_opt_r)
852*12508Samw@Sun.COM smbstat_srv_process_requests(curr, prev);
8536432Sas200622 }
8546432Sas200622
855*12508Samw@Sun.COM /*
856*12508Samw@Sun.COM * smbstat_srv_process_counters
857*12508Samw@Sun.COM */
858*12508Samw@Sun.COM static void
smbstat_srv_process_counters(smbstat_srv_snapshot_t * curr)859*12508Samw@Sun.COM smbstat_srv_process_counters(smbstat_srv_snapshot_t *curr)
8605331Samw {
861*12508Samw@Sun.COM smbstat_srv_info.si_nbt_sess = curr->ss_data.ks_nbt_sess;
862*12508Samw@Sun.COM smbstat_srv_info.si_tcp_sess = curr->ss_data.ks_tcp_sess;
863*12508Samw@Sun.COM smbstat_srv_info.si_users = curr->ss_data.ks_users;
864*12508Samw@Sun.COM smbstat_srv_info.si_trees = curr->ss_data.ks_trees;
865*12508Samw@Sun.COM smbstat_srv_info.si_files = curr->ss_data.ks_files;
866*12508Samw@Sun.COM smbstat_srv_info.si_pipes = curr->ss_data.ks_pipes;
867*12508Samw@Sun.COM }
8685331Samw
869*12508Samw@Sun.COM /*
870*12508Samw@Sun.COM * smbstat_srv_process_throughput
871*12508Samw@Sun.COM *
872*12508Samw@Sun.COM * Processes the data relative to the throughput of the smbsrv module and
873*12508Samw@Sun.COM * stores the results in the structure smbstat_srv_info.
874*12508Samw@Sun.COM */
875*12508Samw@Sun.COM static void
smbstat_srv_process_throughput(smbstat_srv_snapshot_t * curr,smbstat_srv_snapshot_t * prev)876*12508Samw@Sun.COM smbstat_srv_process_throughput(
877*12508Samw@Sun.COM smbstat_srv_snapshot_t *curr,
878*12508Samw@Sun.COM smbstat_srv_snapshot_t *prev)
879*12508Samw@Sun.COM {
880*12508Samw@Sun.COM smbstat_srv_info.si_tbs =
881*12508Samw@Sun.COM smbstat_sub_64(curr->ss_data.ks_txb, prev->ss_data.ks_txb);
882*12508Samw@Sun.COM smbstat_srv_info.si_tbs /= smbstat_srv_info.si_etime;
883*12508Samw@Sun.COM smbstat_srv_info.si_rbs =
884*12508Samw@Sun.COM smbstat_sub_64(curr->ss_data.ks_rxb, prev->ss_data.ks_rxb);
885*12508Samw@Sun.COM smbstat_srv_info.si_rbs /= smbstat_srv_info.si_etime;
886*12508Samw@Sun.COM smbstat_srv_info.si_rqs = smbstat_srv_info.si_total_nreqs;
887*12508Samw@Sun.COM smbstat_srv_info.si_rqs /= smbstat_srv_info.si_etime;
888*12508Samw@Sun.COM
889*12508Samw@Sun.COM smbstat_srv_info.si_rds = smbstat_sub_64(
890*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_READ].kr_nreq,
891*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_READ].kr_nreq);
892*12508Samw@Sun.COM smbstat_srv_info.si_rds += smbstat_sub_64(
893*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_LOCK_AND_READ].kr_nreq,
894*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_LOCK_AND_READ].kr_nreq);
895*12508Samw@Sun.COM smbstat_srv_info.si_rds += smbstat_sub_64(
896*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_READ_RAW].kr_nreq,
897*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_READ_RAW].kr_nreq);
898*12508Samw@Sun.COM smbstat_srv_info.si_rds += smbstat_sub_64(
899*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_READ_ANDX].kr_nreq,
900*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_READ_ANDX].kr_nreq);
901*12508Samw@Sun.COM smbstat_srv_info.si_rds /= smbstat_srv_info.si_etime;
902*12508Samw@Sun.COM
903*12508Samw@Sun.COM smbstat_srv_info.si_wrs = smbstat_sub_64(
904*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_WRITE].kr_nreq,
905*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_WRITE].kr_nreq);
906*12508Samw@Sun.COM smbstat_srv_info.si_wrs += smbstat_sub_64(
907*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_WRITE_AND_UNLOCK].kr_nreq,
908*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_WRITE_AND_UNLOCK].kr_nreq);
909*12508Samw@Sun.COM smbstat_srv_info.si_wrs += smbstat_sub_64(
910*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_WRITE_RAW].kr_nreq,
911*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_WRITE_RAW].kr_nreq);
912*12508Samw@Sun.COM smbstat_srv_info.si_wrs += smbstat_sub_64(
913*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_WRITE_AND_CLOSE].kr_nreq,
914*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_WRITE_AND_CLOSE].kr_nreq);
915*12508Samw@Sun.COM smbstat_srv_info.si_wrs += smbstat_sub_64(
916*12508Samw@Sun.COM curr->ss_data.ks_reqs[SMB_COM_WRITE_ANDX].kr_nreq,
917*12508Samw@Sun.COM prev->ss_data.ks_reqs[SMB_COM_WRITE_ANDX].kr_nreq);
918*12508Samw@Sun.COM smbstat_srv_info.si_wrs /= smbstat_srv_info.si_etime;
9195331Samw }
9205331Samw
921*12508Samw@Sun.COM /*
922*12508Samw@Sun.COM * smbstat_srv_process_utilization
923*12508Samw@Sun.COM *
924*12508Samw@Sun.COM * Processes the data relative to the utilization of the smbsrv module and
925*12508Samw@Sun.COM * stores the results in the structure smbstat_srv_info.
926*12508Samw@Sun.COM */
9275331Samw static void
smbstat_srv_process_utilization(smbstat_srv_snapshot_t * curr,smbstat_srv_snapshot_t * prev)928*12508Samw@Sun.COM smbstat_srv_process_utilization(
929*12508Samw@Sun.COM smbstat_srv_snapshot_t *curr,
930*12508Samw@Sun.COM smbstat_srv_snapshot_t *prev)
9315331Samw {
932*12508Samw@Sun.COM double tw_delta, tr_delta;
933*12508Samw@Sun.COM double w_delta, r_delta;
934*12508Samw@Sun.COM double tps, rqs;
9355331Samw
936*12508Samw@Sun.COM w_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_wlentime,
937*12508Samw@Sun.COM curr->ss_data.ks_utilization.ku_wlentime);
938*12508Samw@Sun.COM r_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_rlentime,
939*12508Samw@Sun.COM curr->ss_data.ks_utilization.ku_rlentime);
940*12508Samw@Sun.COM tw_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_wtime,
941*12508Samw@Sun.COM curr->ss_data.ks_utilization.ku_wtime);
942*12508Samw@Sun.COM tr_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_rtime,
943*12508Samw@Sun.COM curr->ss_data.ks_utilization.ku_rtime);
944*12508Samw@Sun.COM rqs = smbstat_srv_info.si_total_nreqs / smbstat_srv_info.si_etime;
9455331Samw
946*12508Samw@Sun.COM /* Average number of requests waiting */
947*12508Samw@Sun.COM if (w_delta != 0)
948*12508Samw@Sun.COM smbstat_srv_info.si_avw = w_delta / smbstat_srv_info.si_hretime;
949*12508Samw@Sun.COM else
950*12508Samw@Sun.COM smbstat_srv_info.si_avw = 0.0;
9515331Samw
952*12508Samw@Sun.COM /* Average number of request running */
953*12508Samw@Sun.COM if (r_delta != 0)
954*12508Samw@Sun.COM smbstat_srv_info.si_avr = r_delta / smbstat_srv_info.si_hretime;
955*12508Samw@Sun.COM else
956*12508Samw@Sun.COM smbstat_srv_info.si_avr = 0.0;
957*12508Samw@Sun.COM
958*12508Samw@Sun.COM /* Utilization */
959*12508Samw@Sun.COM smbstat_srv_info.si_upct =
960*12508Samw@Sun.COM (smbstat_srv_info.si_avr / curr->ss_data.ks_maxreqs) * 100;
9615331Samw
962*12508Samw@Sun.COM /* Average wait service time in milliseconds */
963*12508Samw@Sun.COM smbstat_srv_info.si_rserv = 0.0;
964*12508Samw@Sun.COM smbstat_srv_info.si_wserv = 0.0;
965*12508Samw@Sun.COM if (rqs > 0.0 &&
966*12508Samw@Sun.COM (smbstat_srv_info.si_avw != 0.0 ||
967*12508Samw@Sun.COM smbstat_srv_info.si_avr != 0.0)) {
968*12508Samw@Sun.COM tps = 1 / rqs;
969*12508Samw@Sun.COM if (smbstat_srv_info.si_avw != 0.0)
970*12508Samw@Sun.COM smbstat_srv_info.si_wserv =
971*12508Samw@Sun.COM smbstat_srv_info.si_avw * tps;
972*12508Samw@Sun.COM if (smbstat_srv_info.si_avr != 0.0)
973*12508Samw@Sun.COM smbstat_srv_info.si_rserv =
974*12508Samw@Sun.COM smbstat_srv_info.si_avr * tps;
975*12508Samw@Sun.COM }
9765331Samw
977*12508Samw@Sun.COM /* % of time there is a transaction waiting for service */
978*12508Samw@Sun.COM if (tw_delta != 0) {
979*12508Samw@Sun.COM smbstat_srv_info.si_wpct = tw_delta;
980*12508Samw@Sun.COM smbstat_srv_info.si_wpct /= smbstat_srv_info.si_hretime;
981*12508Samw@Sun.COM smbstat_srv_info.si_wpct *= 100.0;
982*12508Samw@Sun.COM } else {
983*12508Samw@Sun.COM smbstat_srv_info.si_wpct = 0.0;
984*12508Samw@Sun.COM }
985*12508Samw@Sun.COM
986*12508Samw@Sun.COM /* % of time there is a transaction running */
987*12508Samw@Sun.COM if (tr_delta != 0) {
988*12508Samw@Sun.COM smbstat_srv_info.si_rpct = tr_delta;
989*12508Samw@Sun.COM smbstat_srv_info.si_rpct /= smbstat_srv_info.si_hretime;
990*12508Samw@Sun.COM smbstat_srv_info.si_rpct *= 100.0;
991*12508Samw@Sun.COM } else {
992*12508Samw@Sun.COM smbstat_srv_info.si_rpct = 0.0;
9935331Samw }
9945331Samw }
9955331Samw
996*12508Samw@Sun.COM /*
997*12508Samw@Sun.COM * smbstat_srv_process_requests
998*12508Samw@Sun.COM *
999*12508Samw@Sun.COM * Processes the data relative to the SMB requests and stores the results in
1000*12508Samw@Sun.COM * the structure smbstat_srv_info.
1001*12508Samw@Sun.COM */
10025331Samw static void
smbstat_srv_process_requests(smbstat_srv_snapshot_t * curr,smbstat_srv_snapshot_t * prev)1003*12508Samw@Sun.COM smbstat_srv_process_requests(
1004*12508Samw@Sun.COM smbstat_srv_snapshot_t *curr,
1005*12508Samw@Sun.COM smbstat_srv_snapshot_t *prev)
10065331Samw {
1007*12508Samw@Sun.COM smbstat_req_info_t *info;
1008*12508Samw@Sun.COM double nrqs;
1009*12508Samw@Sun.COM int i, idx;
1010*12508Samw@Sun.COM
1011*12508Samw@Sun.COM info = smbstat_srv_info.si_reqs;
1012*12508Samw@Sun.COM
1013*12508Samw@Sun.COM for (i = 0; i < SMB_COM_NUM; i++) {
1014*12508Samw@Sun.COM idx = info[i].ri_opcode;
1015*12508Samw@Sun.COM
1016*12508Samw@Sun.COM nrqs = smbstat_sub_64(curr->ss_data.ks_reqs[idx].kr_nreq,
1017*12508Samw@Sun.COM prev->ss_data.ks_reqs[idx].kr_nreq);
1018*12508Samw@Sun.COM
1019*12508Samw@Sun.COM info[i].ri_rqs = nrqs / smbstat_srv_info.si_etime;
1020*12508Samw@Sun.COM
1021*12508Samw@Sun.COM info[i].ri_rbs = smbstat_sub_64(
1022*12508Samw@Sun.COM curr->ss_data.ks_reqs[idx].kr_rxb,
1023*12508Samw@Sun.COM prev->ss_data.ks_reqs[idx].kr_rxb) /
1024*12508Samw@Sun.COM smbstat_srv_info.si_etime;
1025*12508Samw@Sun.COM
1026*12508Samw@Sun.COM info[i].ri_tbs = smbstat_sub_64(
1027*12508Samw@Sun.COM curr->ss_data.ks_reqs[idx].kr_txb,
1028*12508Samw@Sun.COM prev->ss_data.ks_reqs[idx].kr_txb) /
1029*12508Samw@Sun.COM smbstat_srv_info.si_etime;
1030*12508Samw@Sun.COM
1031*12508Samw@Sun.COM info[i].ri_pct = nrqs * 100;
1032*12508Samw@Sun.COM if (smbstat_srv_info.si_total_nreqs > 0)
1033*12508Samw@Sun.COM info[i].ri_pct /= smbstat_srv_info.si_total_nreqs;
1034*12508Samw@Sun.COM
1035*12508Samw@Sun.COM if (prev->ss_snaptime == 0) {
1036*12508Samw@Sun.COM /* First time. Take the aggregate */
1037*12508Samw@Sun.COM info[i].ri_stddev =
1038*12508Samw@Sun.COM curr->ss_data.ks_reqs[idx].kr_a_stddev;
1039*12508Samw@Sun.COM info[i].ri_mean = curr->ss_data.ks_reqs[idx].kr_a_mean;
1040*12508Samw@Sun.COM } else {
1041*12508Samw@Sun.COM /* Take the differential */
1042*12508Samw@Sun.COM info[i].ri_stddev =
1043*12508Samw@Sun.COM curr->ss_data.ks_reqs[idx].kr_d_stddev;
1044*12508Samw@Sun.COM info[i].ri_mean = curr->ss_data.ks_reqs[idx].kr_d_mean;
1045*12508Samw@Sun.COM }
1046*12508Samw@Sun.COM if (nrqs > 0) {
1047*12508Samw@Sun.COM info[i].ri_stddev /= nrqs;
1048*12508Samw@Sun.COM info[i].ri_stddev = sqrt(info[i].ri_stddev);
1049*12508Samw@Sun.COM } else {
1050*12508Samw@Sun.COM info[i].ri_stddev = 0;
1051*12508Samw@Sun.COM }
1052*12508Samw@Sun.COM info[i].ri_stddev /= NANOSEC;
1053*12508Samw@Sun.COM info[i].ri_mean /= NANOSEC;
1054*12508Samw@Sun.COM }
10555331Samw }
10565331Samw
1057*12508Samw@Sun.COM /*
1058*12508Samw@Sun.COM * smbstat_srv_current_snapshot
1059*12508Samw@Sun.COM *
1060*12508Samw@Sun.COM * Returns the current snapshot.
1061*12508Samw@Sun.COM */
1062*12508Samw@Sun.COM static smbstat_srv_snapshot_t *
smbstat_srv_current_snapshot(void)1063*12508Samw@Sun.COM smbstat_srv_current_snapshot(void)
1064*12508Samw@Sun.COM {
1065*12508Samw@Sun.COM return (&smbstat_srv_snapshots[smbstat_snapshot_idx]);
1066*12508Samw@Sun.COM }
1067*12508Samw@Sun.COM
1068*12508Samw@Sun.COM /*
1069*12508Samw@Sun.COM * smbstat_srv_previous_snapshot
1070*12508Samw@Sun.COM *
1071*12508Samw@Sun.COM * Returns the previous snapshot.
1072*12508Samw@Sun.COM */
1073*12508Samw@Sun.COM static smbstat_srv_snapshot_t *
smbstat_srv_previous_snapshot(void)1074*12508Samw@Sun.COM smbstat_srv_previous_snapshot(void)
1075*12508Samw@Sun.COM {
1076*12508Samw@Sun.COM int idx;
1077*12508Samw@Sun.COM
1078*12508Samw@Sun.COM idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
1079*12508Samw@Sun.COM return (&smbstat_srv_snapshots[idx]);
1080*12508Samw@Sun.COM }
1081*12508Samw@Sun.COM
1082*12508Samw@Sun.COM /*
1083*12508Samw@Sun.COM * smbstat_usage
1084*12508Samw@Sun.COM *
1085*12508Samw@Sun.COM * Prints out a help message.
1086*12508Samw@Sun.COM */
1087*12508Samw@Sun.COM static void
smbstat_usage(FILE * fd,int exit_code)1088*12508Samw@Sun.COM smbstat_usage(FILE *fd, int exit_code)
1089*12508Samw@Sun.COM {
1090*12508Samw@Sun.COM (void) fprintf(fd, gettext(SMBSTAT_HELP));
1091*12508Samw@Sun.COM exit(exit_code);
1092*12508Samw@Sun.COM }
1093*12508Samw@Sun.COM
1094*12508Samw@Sun.COM /*
1095*12508Samw@Sun.COM * smbstat_fail
1096*12508Samw@Sun.COM *
1097*12508Samw@Sun.COM * Prints out to stderr an error message and exits the process.
1098*12508Samw@Sun.COM */
10995331Samw static void
smbstat_fail(int do_perror,char * message,...)11005331Samw smbstat_fail(int do_perror, char *message, ...)
11015331Samw {
11025331Samw va_list args;
11035331Samw
11045331Samw va_start(args, message);
11055331Samw (void) fprintf(stderr, gettext("smbstat: "));
11065331Samw /* LINTED E_SEC_PRINTF_VAR_FMT */
11075331Samw (void) vfprintf(stderr, message, args);
11085331Samw va_end(args);
11095331Samw if (do_perror)
11105331Samw (void) fprintf(stderr, ": %s", strerror(errno));
11115331Samw (void) fprintf(stderr, "\n");
11125331Samw exit(1);
11135331Samw }
11145331Samw
1115*12508Samw@Sun.COM /*
1116*12508Samw@Sun.COM * smbstat_sub_64
1117*12508Samw@Sun.COM *
1118*12508Samw@Sun.COM * Substract 2 uint64_t and returns a double.
1119*12508Samw@Sun.COM */
1120*12508Samw@Sun.COM static double
smbstat_sub_64(uint64_t a,uint64_t b)1121*12508Samw@Sun.COM smbstat_sub_64(uint64_t a, uint64_t b)
11225331Samw {
1123*12508Samw@Sun.COM return ((double)(a - b));
1124*12508Samw@Sun.COM }
1125*12508Samw@Sun.COM
1126*12508Samw@Sun.COM /*
1127*12508Samw@Sun.COM * smbstat_zero
1128*12508Samw@Sun.COM *
1129*12508Samw@Sun.COM * Returns zero if the value passed in is less than 1.
1130*12508Samw@Sun.COM */
1131*12508Samw@Sun.COM static double
smbstat_zero(double value)1132*12508Samw@Sun.COM smbstat_zero(double value)
1133*12508Samw@Sun.COM {
1134*12508Samw@Sun.COM if (value < 1)
1135*12508Samw@Sun.COM value = 0;
1136*12508Samw@Sun.COM return (value);
1137*12508Samw@Sun.COM }
1138*12508Samw@Sun.COM
1139*12508Samw@Sun.COM /*
1140*12508Samw@Sun.COM * smbstat_strtoi
1141*12508Samw@Sun.COM *
1142*12508Samw@Sun.COM * Converts a string representing an integer value into its binary value.
1143*12508Samw@Sun.COM * If the conversion fails this routine exits the process.
1144*12508Samw@Sun.COM */
1145*12508Samw@Sun.COM static uint_t
smbstat_strtoi(char const * val,char * errmsg)1146*12508Samw@Sun.COM smbstat_strtoi(char const *val, char *errmsg)
1147*12508Samw@Sun.COM {
1148*12508Samw@Sun.COM char *end;
1149*12508Samw@Sun.COM long tmp;
11505331Samw
1151*12508Samw@Sun.COM errno = 0;
1152*12508Samw@Sun.COM tmp = strtol(val, &end, 10);
1153*12508Samw@Sun.COM if (*end != '\0' || errno)
1154*12508Samw@Sun.COM smbstat_fail(1, "%s %s", errmsg, val);
1155*12508Samw@Sun.COM return ((uint_t)tmp);
1156*12508Samw@Sun.COM }
1157*12508Samw@Sun.COM
1158*12508Samw@Sun.COM /*
1159*12508Samw@Sun.COM * smbstat_termio_init
1160*12508Samw@Sun.COM *
1161*12508Samw@Sun.COM * Determines the size of the terminal associated with the process.
1162*12508Samw@Sun.COM */
1163*12508Samw@Sun.COM static void
smbstat_termio_init(void)1164*12508Samw@Sun.COM smbstat_termio_init(void)
1165*12508Samw@Sun.COM {
1166*12508Samw@Sun.COM char *envp;
1167*12508Samw@Sun.COM
1168*12508Samw@Sun.COM if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &smbstat_ws) != -1) {
1169*12508Samw@Sun.COM if (smbstat_ws.ws_row == 0) {
1170*12508Samw@Sun.COM envp = getenv("LINES");
1171*12508Samw@Sun.COM if (envp != NULL)
1172*12508Samw@Sun.COM smbstat_ws.ws_row = atoi(envp);
1173*12508Samw@Sun.COM }
1174*12508Samw@Sun.COM
1175*12508Samw@Sun.COM if (smbstat_ws.ws_col == 0) {
1176*12508Samw@Sun.COM envp = getenv("COLUMNS");
1177*12508Samw@Sun.COM if (envp != NULL)
1178*12508Samw@Sun.COM smbstat_ws.ws_row = atoi(envp);
1179*12508Samw@Sun.COM }
1180*12508Samw@Sun.COM }
1181*12508Samw@Sun.COM if (smbstat_ws.ws_col == 0)
1182*12508Samw@Sun.COM smbstat_ws.ws_col = 80;
1183*12508Samw@Sun.COM if (smbstat_ws.ws_row == 0)
1184*12508Samw@Sun.COM smbstat_ws.ws_row = 25;
1185*12508Samw@Sun.COM }
1186*12508Samw@Sun.COM
1187*12508Samw@Sun.COM /*
1188*12508Samw@Sun.COM * smbstat_snapshot_idx_inc
1189*12508Samw@Sun.COM *
1190*12508Samw@Sun.COM * Increments the snapshot index.
1191*12508Samw@Sun.COM */
1192*12508Samw@Sun.COM static void
smbstat_snapshot_inc_idx(void)1193*12508Samw@Sun.COM smbstat_snapshot_inc_idx(void)
1194*12508Samw@Sun.COM {
1195*12508Samw@Sun.COM smbstat_snapshot_idx++;
1196*12508Samw@Sun.COM smbstat_snapshot_idx &= SMBSTAT_SNAPSHOT_MASK;
11975331Samw }
11985331Samw
11995331Samw /*
1200*12508Samw@Sun.COM * smbstat_req_cmp_name
1201*12508Samw@Sun.COM *
1202*12508Samw@Sun.COM * Call back function passed to qsort() when the list of requests must be sorted
1203*12508Samw@Sun.COM * by name.
12045331Samw */
1205*12508Samw@Sun.COM static int
smbstat_req_cmp_name(const void * obj1,const void * obj2)1206*12508Samw@Sun.COM smbstat_req_cmp_name(const void *obj1, const void *obj2)
12075331Samw {
1208*12508Samw@Sun.COM return (strncasecmp(
1209*12508Samw@Sun.COM ((smbstat_req_info_t *)obj1)->ri_name,
1210*12508Samw@Sun.COM ((smbstat_req_info_t *)obj2)->ri_name,
1211*12508Samw@Sun.COM sizeof (((smbstat_req_info_t *)obj2)->ri_name)));
1212*12508Samw@Sun.COM }
1213*12508Samw@Sun.COM
1214*12508Samw@Sun.COM /*
1215*12508Samw@Sun.COM * smbstat_req_order
1216*12508Samw@Sun.COM *
1217*12508Samw@Sun.COM * Snapshots the smbsrv module statistics once to get the name of the requests.
1218*12508Samw@Sun.COM * The request list is smbstat_srv_info is then sorted by name or by code
1219*12508Samw@Sun.COM * depending on the boolean smbstat_opt_a.
1220*12508Samw@Sun.COM * The function should be called once during initialization.
1221*12508Samw@Sun.COM */
1222*12508Samw@Sun.COM static void
smbstat_req_order(void)1223*12508Samw@Sun.COM smbstat_req_order(void)
1224*12508Samw@Sun.COM {
1225*12508Samw@Sun.COM smbstat_req_info_t *info;
1226*12508Samw@Sun.COM smb_kstat_req_t *reqs;
1227*12508Samw@Sun.COM int i;
1228*12508Samw@Sun.COM
1229*12508Samw@Sun.COM smbstat_srv_snapshot();
1230*12508Samw@Sun.COM reqs = smbstat_srv_current_snapshot()->ss_data.ks_reqs;
1231*12508Samw@Sun.COM info = smbstat_srv_info.si_reqs;
1232*12508Samw@Sun.COM
1233*12508Samw@Sun.COM for (i = 0; i < SMB_COM_NUM; i++) {
1234*12508Samw@Sun.COM (void) strlcpy(info[i].ri_name, reqs[i].kr_name,
1235*12508Samw@Sun.COM sizeof (reqs[i].kr_name));
1236*12508Samw@Sun.COM info[i].ri_opcode = i;
1237*12508Samw@Sun.COM }
1238*12508Samw@Sun.COM if (smbstat_opt_n)
1239*12508Samw@Sun.COM qsort(info, SMB_COM_NUM, sizeof (smbstat_req_info_t),
1240*12508Samw@Sun.COM smbstat_req_cmp_name);
12415331Samw }
12425331Samw
1243*12508Samw@Sun.COM /*
1244*12508Samw@Sun.COM * Return the number of ticks delta between two hrtime_t
1245*12508Samw@Sun.COM * values. Attempt to cater for various kinds of overflow
1246*12508Samw@Sun.COM * in hrtime_t - no matter how improbable.
1247*12508Samw@Sun.COM */
1248*12508Samw@Sun.COM static double
smbstat_hrtime_delta(hrtime_t old,hrtime_t new)1249*12508Samw@Sun.COM smbstat_hrtime_delta(hrtime_t old, hrtime_t new)
12505331Samw {
1251*12508Samw@Sun.COM uint64_t del;
1252*12508Samw@Sun.COM
1253*12508Samw@Sun.COM if ((new >= old) && (old >= 0L))
1254*12508Samw@Sun.COM return ((double)(new - old));
1255*12508Samw@Sun.COM /*
1256*12508Samw@Sun.COM * We've overflowed the positive portion of an hrtime_t.
1257*12508Samw@Sun.COM */
1258*12508Samw@Sun.COM if (new < 0L) {
1259*12508Samw@Sun.COM /*
1260*12508Samw@Sun.COM * The new value is negative. Handle the case where the old
1261*12508Samw@Sun.COM * value is positive or negative.
1262*12508Samw@Sun.COM */
1263*12508Samw@Sun.COM uint64_t n1;
1264*12508Samw@Sun.COM uint64_t o1;
1265*12508Samw@Sun.COM
1266*12508Samw@Sun.COM n1 = -new;
1267*12508Samw@Sun.COM if (old > 0L)
1268*12508Samw@Sun.COM return ((double)(n1 - old));
1269*12508Samw@Sun.COM
1270*12508Samw@Sun.COM o1 = -old;
1271*12508Samw@Sun.COM del = n1 - o1;
1272*12508Samw@Sun.COM return ((double)del);
1273*12508Samw@Sun.COM }
1274*12508Samw@Sun.COM
1275*12508Samw@Sun.COM /*
1276*12508Samw@Sun.COM * Either we've just gone from being negative to positive *or* the last
1277*12508Samw@Sun.COM * entry was positive and the new entry is also positive but *less* than
1278*12508Samw@Sun.COM * the old entry. This implies we waited quite a few days on a very fast
1279*12508Samw@Sun.COM * system between displays.
1280*12508Samw@Sun.COM */
1281*12508Samw@Sun.COM if (old < 0L) {
1282*12508Samw@Sun.COM uint64_t o2;
1283*12508Samw@Sun.COM o2 = -old;
1284*12508Samw@Sun.COM del = UINT64_MAX - o2;
1285*12508Samw@Sun.COM } else {
1286*12508Samw@Sun.COM del = UINT64_MAX - old;
1287*12508Samw@Sun.COM }
1288*12508Samw@Sun.COM del += new;
1289*12508Samw@Sun.COM return ((double)del);
12905331Samw }
1291*12508Samw@Sun.COM
1292*12508Samw@Sun.COM static void *
smbstat_zalloc(size_t size)1293*12508Samw@Sun.COM smbstat_zalloc(size_t size)
1294*12508Samw@Sun.COM {
1295*12508Samw@Sun.COM void *ptr;
1296*12508Samw@Sun.COM
1297*12508Samw@Sun.COM ptr = umem_zalloc(size, UMEM_DEFAULT);
1298*12508Samw@Sun.COM if (ptr == NULL)
1299*12508Samw@Sun.COM smbstat_fail(1, gettext("out of memory"));
1300*12508Samw@Sun.COM return (ptr);
1301*12508Samw@Sun.COM }
1302*12508Samw@Sun.COM
1303*12508Samw@Sun.COM static void
smbstat_free(void * ptr,size_t size)1304*12508Samw@Sun.COM smbstat_free(void *ptr, size_t size)
1305*12508Samw@Sun.COM {
1306*12508Samw@Sun.COM umem_free(ptr, size);
1307*12508Samw@Sun.COM }
1308