1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
20da6c28aaSamw  */
21da6c28aaSamw 
22da6c28aaSamw /*
23148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24*5015ecc3SGordon Ross  * Copyright 2020 Nexenta by DDN, Inc.  All rights reserved.
25da6c28aaSamw  */
26da6c28aaSamw 
27da6c28aaSamw /*
28da6c28aaSamw  * smbstat: Server Message Block File System statistics
29148c5f43SAlan Wright  *
30148c5f43SAlan Wright  * The statistics this CLI displays come from two sources:
31148c5f43SAlan Wright  *
32148c5f43SAlan Wright  * 1) The kernel module 'smbsrv'.
33148c5f43SAlan Wright  * 2) The SMB workers task queue statistics the task queue manager of Solaris
34148c5f43SAlan Wright  *    maintains.
35148c5f43SAlan Wright  *
36148c5f43SAlan Wright  * The flow of the code is the following:
37148c5f43SAlan Wright  *
38148c5f43SAlan Wright  *
39*5015ecc3SGordon Ross  *			+----------------+
40*5015ecc3SGordon Ross  *			| Initialization |
41*5015ecc3SGordon Ross  *			+----------------+
42148c5f43SAlan Wright  *				|
43148c5f43SAlan Wright  *				|
44148c5f43SAlan Wright  *				v
45148c5f43SAlan Wright  *		  +--------------------------*
46148c5f43SAlan Wright  *		  | Take a snapshot the data | <--------+
47148c5f43SAlan Wright  *		  +--------------------------+		|
48148c5f43SAlan Wright  *				|			|
49*5015ecc3SGordon Ross  *				|			|
50148c5f43SAlan Wright  *				v			|
51148c5f43SAlan Wright  *		    +----------------------+		|
52148c5f43SAlan Wright  *		    | Process the snapshot |		|
53148c5f43SAlan Wright  *		    +----------------------+		|
54148c5f43SAlan Wright  *				|			|
55148c5f43SAlan Wright  *				|			|
56148c5f43SAlan Wright  *				v			|
57148c5f43SAlan Wright  *	     +------------------------------------+	|
58148c5f43SAlan Wright  *	     | Print the result of the processing |	|
59148c5f43SAlan Wright  *	     +------------------------------------+	|
60148c5f43SAlan Wright  *				|			|
61148c5f43SAlan Wright  *				|			|
62148c5f43SAlan Wright  *				v			|
63148c5f43SAlan Wright  *		Yes	---------------			|
64148c5f43SAlan Wright  *	+------------ < interval == 0 ? >		|
65*5015ecc3SGordon Ross  *	|		---------------			|
66148c5f43SAlan Wright  *	|		       |			|
67*5015ecc3SGordon Ross  *	|		       | No			|
68*5015ecc3SGordon Ross  *	|		       v			|
69148c5f43SAlan Wright  *	|	   +------------------------+		|
70*5015ecc3SGordon Ross  *	|	   | Sleep for the duration | ----------+
71*5015ecc3SGordon Ross  *	|	   |   of the interval.     |
72*5015ecc3SGordon Ross  *	|	   +------------------------+
73*5015ecc3SGordon Ross  *	|
74*5015ecc3SGordon Ross  *	+---------------------+
75148c5f43SAlan Wright  *			      |
76148c5f43SAlan Wright  *			      v
77148c5f43SAlan Wright  *
78148c5f43SAlan Wright  *			    Exit
79148c5f43SAlan Wright  *
80148c5f43SAlan Wright  * There are two sets of snapshots. One set for the smbsrv module and the other
81148c5f43SAlan Wright  * for the task queue (SMB workers). Each set contains 2 snapshots. One is
82148c5f43SAlan Wright  * labeled 'current' the other one 'previous'. Their role changes after each
83148c5f43SAlan Wright  * snapshot. The 'current' becomes 'previous' and vice versa.
84148c5f43SAlan Wright  * The first snapshot taken is compared against the data gathered since the
85148c5f43SAlan Wright  * smbsrv module was loaded. Subsequent snapshots will be compared against the
86148c5f43SAlan Wright  * previous snapshot.
87da6c28aaSamw  */
88148c5f43SAlan Wright 
89da6c28aaSamw #include <stdio.h>
90da6c28aaSamw #include <stdlib.h>
91148c5f43SAlan Wright #include <unistd.h>
92da6c28aaSamw #include <kstat.h>
93da6c28aaSamw #include <stdarg.h>
94da6c28aaSamw #include <errno.h>
95da6c28aaSamw #include <inttypes.h>
96da6c28aaSamw #include <strings.h>
97da6c28aaSamw #include <utility.h>
98da6c28aaSamw #include <libintl.h>
99da6c28aaSamw #include <zone.h>
100148c5f43SAlan Wright #include <termios.h>
101148c5f43SAlan Wright #include <stropts.h>
102148c5f43SAlan Wright #include <math.h>
103148c5f43SAlan Wright #include <umem.h>
104148c5f43SAlan Wright #include <locale.h>
105b3b35633SGordon Ross #include <sys/processor.h>
1066537f381Sas #include <smbsrv/smb_kstat.h>
107da6c28aaSamw 
108148c5f43SAlan Wright #if !defined(TEXT_DOMAIN)
109148c5f43SAlan Wright #define	TEXT_DOMAIN "SYS_TEST"
110148c5f43SAlan Wright #endif /* TEXT_DOMAIN */
111148c5f43SAlan Wright 
112148c5f43SAlan Wright #define	SMBSTAT_ID_NO_CPU	-1
113148c5f43SAlan Wright #define	SMBSTAT_SNAPSHOT_COUNT	2		/* Must be a power of 2 */
114148c5f43SAlan Wright #define	SMBSTAT_SNAPSHOT_MASK	(SMBSTAT_SNAPSHOT_COUNT - 1)
115148c5f43SAlan Wright 
116148c5f43SAlan Wright #define	SMBSTAT_HELP	\
117148c5f43SAlan Wright 	"Usage: smbstat [-acnrtuz] [interval]\n" \
118148c5f43SAlan Wright 	"    -c: display counters\n" \
119148c5f43SAlan Wright 	"    -t: display throughput\n" \
120148c5f43SAlan Wright 	"    -u: display utilization\n" \
121148c5f43SAlan Wright 	"    -r: display requests\n" \
122148c5f43SAlan Wright 	"        -a: all the requests (supported and unsupported)\n" \
123148c5f43SAlan Wright 	"        -z: skip the requests not received\n" \
124148c5f43SAlan Wright 	"        -n: display in alphabetic order\n" \
125148c5f43SAlan Wright 	"    interval: refresh cycle in seconds\n"
126148c5f43SAlan Wright 
127148c5f43SAlan Wright #define	SMBSRV_COUNTERS_BANNER	"\n  nbt   tcp users trees files pipes\n"
128148c5f43SAlan Wright #define	SMBSRV_COUNTERS_FORMAT	"%5d %5d %5d %5d %5d %5d\n"
129148c5f43SAlan Wright 
130148c5f43SAlan Wright #define	SMBSRV_THROUGHPUT_BANNER	\
131148c5f43SAlan Wright 	"\nrbytes/s   tbytes/s    reqs/s     reads/s   writes/s\n"
132148c5f43SAlan Wright #define	SMBSRV_THROUGHPUT_FORMAT	\
133148c5f43SAlan Wright 	"%1.3e  %1.3e  %1.3e  %1.3e  %1.3e\n"
134148c5f43SAlan Wright 
135148c5f43SAlan Wright #define	SMBSRV_UTILIZATION_BANNER	\
136148c5f43SAlan Wright 	"\n  wcnt       rcnt       wtime      rtime" \
137148c5f43SAlan Wright 	"     w%%   r%%   u%%  sat usr%% sys%%  idle%%\n"
138148c5f43SAlan Wright #define	SMBSRV_UTILIZATION_FORMAT	\
139148c5f43SAlan Wright 	"%1.3e  %1.3e  %1.3e  %1.3e  %3.0f  %3.0f  %3.0f  %s " \
140148c5f43SAlan Wright 	"%3.0f  %3.0f    %3.0f\n"
141148c5f43SAlan Wright 
142148c5f43SAlan Wright #define	SMBSRV_REQUESTS_BANNER	\
143148c5f43SAlan Wright 	"\n%30s code   %%   rbytes/s   tbytes/s     req/s     rt-mean"	\
144148c5f43SAlan Wright 	"   rt-stddev\n"
145148c5f43SAlan Wright #define	SMBSRV_REQUESTS_FORMAT	\
146148c5f43SAlan Wright 	"%30s  %02X   %3.0f  %1.3e  %1.3e  %1.3e  %1.3e  %1.3e\n"
147148c5f43SAlan Wright 
148148c5f43SAlan Wright typedef enum {
149148c5f43SAlan Wright 	CPU_TICKS_IDLE = 0,
150148c5f43SAlan Wright 	CPU_TICKS_USER,
151148c5f43SAlan Wright 	CPU_TICKS_KERNEL,
152148c5f43SAlan Wright 	CPU_TICKS_SENTINEL
153148c5f43SAlan Wright } cpu_state_idx_t;
154148c5f43SAlan Wright 
155148c5f43SAlan Wright typedef struct smbstat_cpu_snapshot {
156