Print this page
NEX-5175 want SMB statistics separately for reads, writes, other
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-5197 smbstat copying out wrong stats for per-share or per-client
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-4811 SMB needs to export a header for kstats
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
NEX-4313 want iops, bandwidth, and latency kstats for smb
Portions contributed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
5606 support build with binutils 2.25
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
Reviewed by: Piotr Jasiukajtis <estibi@me.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
NEX-3273 smbstat delays its output when redirected to a file
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-2705 smbstat output may lie about sat and show only zero for writes/s
SMB-78 smbstat should show SMB2 activity
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/cmd/smbsrv/smbstat/smbstat.c
+++ new/usr/src/cmd/smbsrv/smbstat/smbstat.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
24 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
25 25 */
26 26
27 27 /*
28 28 * smbstat: Server Message Block File System statistics
29 29 *
30 30 * The statistics this CLI displays come from two sources:
31 31 *
32 32 * 1) The kernel module 'smbsrv'.
33 33 * 2) The SMB workers task queue statistics the task queue manager of Solaris
34 34 * maintains.
35 35 *
36 36 * The flow of the code is the following:
37 37 *
38 38 *
39 39 * +----------------+
40 40 * | Initialization |
41 41 * +----------------+
42 42 * |
43 43 * |
44 44 * v
45 45 * +--------------------------*
46 46 * | Take a snapshot the data | <--------+
47 47 * +--------------------------+ |
48 48 * | |
49 49 * | |
50 50 * v |
51 51 * +----------------------+ |
52 52 * | Process the snapshot | |
53 53 * +----------------------+ |
54 54 * | |
55 55 * | |
56 56 * v |
57 57 * +------------------------------------+ |
58 58 * | Print the result of the processing | |
59 59 * +------------------------------------+ |
60 60 * | |
61 61 * | |
62 62 * v |
63 63 * Yes --------------- |
64 64 * +------------ < interval == 0 ? > |
65 65 * | --------------- |
66 66 * | | |
67 67 * | | No |
68 68 * | v |
69 69 * | +------------------------+ |
70 70 * | | Sleep for the duration | ----------+
71 71 * | | of the interval. |
72 72 * | +------------------------+
73 73 * |
74 74 * +---------------------+
75 75 * |
76 76 * v
77 77 *
78 78 * Exit
79 79 *
80 80 * There are two sets of snapshots. One set for the smbsrv module and the other
81 81 * for the task queue (SMB workers). Each set contains 2 snapshots. One is
82 82 * labeled 'current' the other one 'previous'. Their role changes after each
83 83 * snapshot. The 'current' becomes 'previous' and vice versa.
84 84 * The first snapshot taken is compared against the data gathered since the
85 85 * smbsrv module was loaded. Subsequent snapshots will be compared against the
86 86 * previous snapshot.
87 87 */
88 88
89 89 #include <stdio.h>
90 90 #include <stdlib.h>
91 91 #include <unistd.h>
92 92 #include <kstat.h>
93 93 #include <stdarg.h>
94 94 #include <errno.h>
95 95 #include <inttypes.h>
|
↓ open down ↓ |
61 lines elided |
↑ open up ↑ |
96 96 #include <strings.h>
97 97 #include <utility.h>
98 98 #include <libintl.h>
99 99 #include <zone.h>
100 100 #include <termios.h>
101 101 #include <stropts.h>
102 102 #include <math.h>
103 103 #include <umem.h>
104 104 #include <locale.h>
105 105 #include <smbsrv/smb_kstat.h>
106 +#include <smbsrv/smb.h>
107 +#include <smbsrv/smb2.h>
106 108
107 109 #if !defined(TEXT_DOMAIN)
108 110 #define TEXT_DOMAIN "SYS_TEST"
109 111 #endif /* TEXT_DOMAIN */
110 112
111 113 #define SMBSTAT_ID_NO_CPU -1
112 114 #define SMBSTAT_SNAPSHOT_COUNT 2 /* Must be a power of 2 */
113 115 #define SMBSTAT_SNAPSHOT_MASK (SMBSTAT_SNAPSHOT_COUNT - 1)
114 116
115 117 #define SMBSTAT_HELP \
116 118 "Usage: smbstat [-acnrtuz] [interval]\n" \
117 119 " -c: display counters\n" \
118 120 " -t: display throughput\n" \
119 121 " -u: display utilization\n" \
120 122 " -r: display requests\n" \
121 123 " -a: all the requests (supported and unsupported)\n" \
122 124 " -z: skip the requests not received\n" \
123 125 " -n: display in alphabetic order\n" \
124 126 " interval: refresh cycle in seconds\n"
125 127
126 128 #define SMBSRV_COUNTERS_BANNER "\n nbt tcp users trees files pipes\n"
127 129 #define SMBSRV_COUNTERS_FORMAT "%5d %5d %5d %5d %5d %5d\n"
128 130
129 131 #define SMBSRV_THROUGHPUT_BANNER \
130 132 "\nrbytes/s tbytes/s reqs/s reads/s writes/s\n"
131 133 #define SMBSRV_THROUGHPUT_FORMAT \
132 134 "%1.3e %1.3e %1.3e %1.3e %1.3e\n"
133 135
134 136 #define SMBSRV_UTILIZATION_BANNER \
135 137 "\n wcnt rcnt wtime rtime" \
136 138 " w%% r%% u%% sat usr%% sys%% idle%%\n"
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
137 139 #define SMBSRV_UTILIZATION_FORMAT \
138 140 "%1.3e %1.3e %1.3e %1.3e %3.0f %3.0f %3.0f %s " \
139 141 "%3.0f %3.0f %3.0f\n"
140 142
141 143 #define SMBSRV_REQUESTS_BANNER \
142 144 "\n%30s code %% rbytes/s tbytes/s req/s rt-mean" \
143 145 " rt-stddev\n"
144 146 #define SMBSRV_REQUESTS_FORMAT \
145 147 "%30s %02X %3.0f %1.3e %1.3e %1.3e %1.3e %1.3e\n"
146 148
149 +#define SMBSRV_CLNT_SHARE_BANNER \
150 + "%30s rbytes/s tbytes/s req/s rt-mean rt-stddev\n"
151 +#define SMBSRV_CLNT_SHARE_FORMAT \
152 + "%30s %1.3e %1.3e %1.3e %1.3e %1.3e\n"
153 +
154 +
147 155 typedef enum {
148 156 CPU_TICKS_IDLE = 0,
149 157 CPU_TICKS_USER,
150 158 CPU_TICKS_KERNEL,
151 159 CPU_TICKS_SENTINEL
152 160 } cpu_state_idx_t;
153 161
154 162 typedef struct smbstat_cpu_snapshot {
155 163 processorid_t cs_id;
156 164 int cs_state;
157 165 uint64_t cs_ticks[CPU_TICKS_SENTINEL];
158 166 } smbstat_cpu_snapshot_t;
159 167
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
160 168 typedef struct smbstat_srv_snapshot {
161 169 hrtime_t ss_snaptime;
162 170 smbsrv_kstats_t ss_data;
163 171 } smbstat_srv_snapshot_t;
164 172
165 173 typedef struct smbstat_wrk_snapshot {
166 174 uint64_t ws_maxthreads;
167 175 uint64_t ws_bnalloc;
168 176 } smbstat_wrk_snapshot_t;
169 177
178 +/* Per-Client or Per-Share statistics. */
179 +typedef struct smbstat_clsh_snapshot {
180 + hrtime_t cs_snaptime;
181 + smbsrv_clsh_kstats_t cs_data;
182 +} smbstat_clsh_snapshot_t;
183 +
170 184 typedef struct smbstat_req_info {
171 185 char ri_name[KSTAT_STRLEN];
172 186 int ri_opcode;
173 187 double ri_pct;
174 188 double ri_tbs;
175 189 double ri_rbs;
176 190 double ri_rqs;
177 191 double ri_stddev;
178 192 double ri_mean;
179 193 } smbstat_req_info_t;
180 194
181 195 typedef struct smbstat_srv_info {
182 196 double si_hretime;
183 197 double si_etime;
184 198 double si_total_nreqs;
185 199 /*
186 200 * Counters
187 201 */
188 202 uint32_t si_nbt_sess; /* NBT sessions */
189 203 uint32_t si_tcp_sess; /* TCP sessions */
190 204 uint32_t si_users; /* Users logged in */
191 205 uint32_t si_trees; /* Trees connected */
192 206 uint32_t si_files; /* Open files */
193 207 uint32_t si_pipes; /* Open pipes */
194 208 /*
195 209 * Throughput of the server
196 210 */
197 211 double si_tbs; /* Bytes transmitted / second */
198 212 double si_rbs; /* Bytes received / second */
199 213 double si_rqs; /* Requests treated / second */
200 214 double si_rds; /* Reads treated / second */
201 215 double si_wrs; /* Writes treated / second */
202 216 /*
203 217 * Utilization of the server
204 218 */
205 219 double si_wpct; /* */
206 220 double si_rpct; /* */
|
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
207 221 double si_upct; /* Utilization in % */
208 222 double si_avw; /* Average number of requests waiting */
209 223 double si_avr; /* Average number of requests running */
210 224 double si_wserv; /* Average waiting time */
211 225 double si_rserv; /* Average running time */
212 226 boolean_t si_sat;
213 227 double si_ticks[CPU_TICKS_SENTINEL];
214 228 /*
215 229 * Latency & Throughput per request
216 230 */
217 - smbstat_req_info_t si_reqs1[SMB_COM_NUM];
218 - smbstat_req_info_t si_reqs2[SMB2__NCMDS];
231 + smbstat_req_info_t si_reqs1[SMBSRV_KS_NREQS1];
232 + smbstat_req_info_t si_reqs2[SMBSRV_KS_NREQS2];
233 + /*
234 + * Latency & Throughput on specified client or share
235 + */
236 + smbstat_req_info_t si_clsh[SMBSRV_CLSH__NREQ];
219 237 } smbstat_srv_info_t;
220 238
221 239 static void smbstat_init(void);
222 240 static void smbstat_fini(void);
223 241 static void smbstat_kstat_snapshot(void);
224 242 static void smbstat_kstat_process(void);
225 243 static void smbstat_kstat_print(void);
226 244
227 245 static void smbstat_print_counters(void);
228 246 static void smbstat_print_throughput(void);
229 247 static void smbstat_print_utilization(void);
230 248 static void smbstat_print_requests(void);
249 +static void smbstat_print_client_or_share(void);
231 250
232 251 static void smbstat_cpu_init(void);
233 252 static void smbstat_cpu_fini(void);
234 253 static smbstat_cpu_snapshot_t *smbstat_cpu_current_snapshot(void);
235 254 static smbstat_cpu_snapshot_t *smbstat_cpu_previous_snapshot(void);
236 255 static void smbstat_cpu_snapshot(void);
237 256 static void smbstat_cpu_process(void);
238 257
239 258 static void smbstat_wrk_init(void);
240 259 static void smbstat_wrk_fini(void);
241 260 static void smbstat_wrk_snapshot(void);
242 261 static void smbstat_wrk_process(void);
243 262 static smbstat_wrk_snapshot_t *smbstat_wrk_current_snapshot(void);
244 263
264 +static void smbstat_clsh_init(void);
265 +static void smbstat_clsh_fini(void);
266 +static void smbstat_clsh_snapshot(void);
267 +static void smbstat_clsh_process(void);
268 +static smbstat_clsh_snapshot_t *smbstat_clsh_current_snapshot(void);
269 +static smbstat_clsh_snapshot_t *smbstat_clsh_previous_snapshot(void);
270 +
245 271 static void smbstat_srv_init(void);
246 272 static void smbstat_srv_fini(void);
247 273 static void smbstat_srv_snapshot(void);
248 274 static void smbstat_srv_process(void);
249 275 static void smbstat_srv_process_counters(smbstat_srv_snapshot_t *);
250 276 static void smbstat_srv_process_throughput(smbstat_srv_snapshot_t *,
251 277 smbstat_srv_snapshot_t *);
252 278 static void smbstat_srv_process_utilization(smbstat_srv_snapshot_t *,
253 279 smbstat_srv_snapshot_t *);
254 280 static void smbstat_srv_process_requests(smbstat_srv_snapshot_t *,
255 281 smbstat_srv_snapshot_t *);
256 282 static void smbstat_srv_process_one_req(smbstat_req_info_t *,
257 283 smb_kstat_req_t *, smb_kstat_req_t *, boolean_t);
258 284
259 285 static smbstat_srv_snapshot_t *smbstat_srv_current_snapshot(void);
260 286 static smbstat_srv_snapshot_t *smbstat_srv_previous_snapshot(void);
261 287
262 288 static void *smbstat_zalloc(size_t);
263 289 static void smbstat_free(void *, size_t);
264 290 static void smbstat_fail(int, char *, ...);
265 291 static void smbstat_snapshot_inc_idx(void);
266 292 static void smbstat_usage(FILE *, int);
267 293 static uint_t smbstat_strtoi(char const *, char *);
268 294 static double smbstat_hrtime_delta(hrtime_t, hrtime_t);
269 295 static double smbstat_sub_64(uint64_t, uint64_t);
270 296 static void smbstat_req_order(void);
271 297 static double smbstat_zero(double);
272 298 static void smbstat_termio_init(void);
273 299
274 300 #pragma does_not_return(smbstat_fail, smbstat_usage)
275 301
276 302 static char *smbstat_cpu_states[CPU_TICKS_SENTINEL] = {
277 303 "cpu_ticks_idle",
278 304 "cpu_ticks_user",
|
↓ open down ↓ |
24 lines elided |
↑ open up ↑ |
279 305 "cpu_ticks_kernel"
280 306 };
281 307
282 308 static boolean_t smbstat_opt_a = B_FALSE; /* all */
283 309 static boolean_t smbstat_opt_c = B_FALSE; /* counters */
284 310 static boolean_t smbstat_opt_n = B_FALSE; /* by name */
285 311 static boolean_t smbstat_opt_u = B_FALSE; /* utilization */
286 312 static boolean_t smbstat_opt_t = B_FALSE; /* throughput */
287 313 static boolean_t smbstat_opt_r = B_FALSE; /* requests */
288 314 static boolean_t smbstat_opt_z = B_FALSE; /* non-zero requests */
315 +static boolean_t smbstat_opt_C = B_FALSE; /* per-client stats */
316 +static boolean_t smbstat_opt_S = B_FALSE; /* per-share stats */
317 +static char *smbstat_opt_clsh = NULL; /* -C or -S arg. */
289 318
290 319 static uint_t smbstat_interval = 0;
291 320 static long smbstat_nrcpus = 0;
292 321 static kstat_ctl_t *smbstat_ksc = NULL;
293 322 static kstat_t *smbstat_srv_ksp = NULL;
294 323 static kstat_t *smbstat_wrk_ksp = NULL;
324 +static kstat_t *smbstat_clsh_ksp = NULL;
295 325 static struct winsize smbstat_ws;
296 326 static uint16_t smbstat_rows = 0;
297 327
298 328 static int smbstat_snapshot_idx = 0;
299 329 static smbstat_cpu_snapshot_t *smbstat_cpu_snapshots[SMBSTAT_SNAPSHOT_COUNT];
300 330 static smbstat_srv_snapshot_t smbstat_srv_snapshots[SMBSTAT_SNAPSHOT_COUNT];
301 331 static smbstat_wrk_snapshot_t smbstat_wrk_snapshots[SMBSTAT_SNAPSHOT_COUNT];
332 +static smbstat_clsh_snapshot_t smbstat_clsh_snapshots[SMBSTAT_SNAPSHOT_COUNT];
302 333 static smbstat_srv_info_t smbstat_srv_info;
303 334
304 335 /*
305 336 * main
306 337 */
307 338 int
308 339 main(int argc, char *argv[])
309 340 {
310 341 int c;
311 342
312 343 (void) setlocale(LC_ALL, "");
313 344 (void) textdomain(TEXT_DOMAIN);
314 345
315 346 if (is_system_labeled()) {
316 347 (void) fprintf(stderr,
317 348 gettext("%s: Trusted Extensions not supported.\n"),
318 349 argv[0]);
319 350 return (1);
320 351 }
321 352
322 - while ((c = getopt(argc, argv, "achnrtuz")) != EOF) {
353 + while ((c = getopt(argc, argv, "achnrtuzC:S:")) != EOF) {
323 354 switch (c) {
324 355 case 'a':
325 356 smbstat_opt_a = B_TRUE;
326 357 break;
327 358 case 'n':
328 359 smbstat_opt_n = B_TRUE;
329 360 break;
330 361 case 'u':
331 362 smbstat_opt_u = B_TRUE;
332 363 break;
333 364 case 'c':
334 365 smbstat_opt_c = B_TRUE;
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
335 366 break;
336 367 case 'r':
337 368 smbstat_opt_r = B_TRUE;
338 369 break;
339 370 case 't':
340 371 smbstat_opt_t = B_TRUE;
341 372 break;
342 373 case 'z':
343 374 smbstat_opt_z = B_TRUE;
344 375 break;
376 + case 'C': /* per-client stats. */
377 + smbstat_opt_S = B_FALSE;
378 + smbstat_opt_C = B_TRUE;
379 + smbstat_opt_clsh = optarg;
380 + break;
381 + case 'S': /* per-share stats. */
382 + smbstat_opt_C = B_FALSE;
383 + smbstat_opt_S = B_TRUE;
384 + smbstat_opt_clsh = optarg;
385 + break;
345 386 case 'h':
346 387 smbstat_usage(stdout, 0);
347 388 default:
348 389 smbstat_usage(stderr, 1);
349 390 }
350 391 }
351 392
352 393 if (!smbstat_opt_u &&
353 394 !smbstat_opt_c &&
354 395 !smbstat_opt_r &&
355 - !smbstat_opt_t) {
396 + !smbstat_opt_t &&
397 + !smbstat_opt_C &&
398 + !smbstat_opt_S) {
356 399 /* Default options when none is specified. */
357 400 smbstat_opt_u = B_TRUE;
358 401 smbstat_opt_t = B_TRUE;
359 402 }
360 403
361 404 if (optind < argc) {
362 405 smbstat_interval =
363 406 smbstat_strtoi(argv[optind], "invalid count");
364 407 optind++;
365 408 }
366 409
367 410 if ((argc - optind) > 1)
368 411 smbstat_usage(stderr, 1);
369 412
370 413 (void) atexit(smbstat_fini);
371 414 smbstat_init();
415 + smbstat_req_order();
372 416 for (;;) {
373 417 smbstat_kstat_snapshot();
374 418 smbstat_kstat_process();
375 419 smbstat_kstat_print();
376 420 if (smbstat_interval == 0)
377 421 break;
378 422 (void) sleep(smbstat_interval);
379 423 smbstat_snapshot_inc_idx();
380 424 }
381 425 return (0);
382 426 }
383 427
384 428 /*
385 429 * smbstat_init
386 430 *
387 431 * Global initialization.
|
↓ open down ↓ |
6 lines elided |
↑ open up ↑ |
388 432 */
389 433 static void
390 434 smbstat_init(void)
391 435 {
392 436 if ((smbstat_ksc = kstat_open()) == NULL)
393 437 smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat"));
394 438
395 439 smbstat_cpu_init();
396 440 smbstat_srv_init();
397 441 smbstat_wrk_init();
398 - smbstat_req_order();
442 + smbstat_clsh_init();
399 443 }
400 444
401 445 /*
402 446 * smbstat_fini
403 447 *
404 448 * Releases the resources smbstat_init() allocated.
405 449 */
406 450 static void
407 451 smbstat_fini(void)
408 452 {
453 + smbstat_clsh_fini();
409 454 smbstat_wrk_fini();
410 455 smbstat_srv_fini();
411 456 smbstat_cpu_fini();
412 457 (void) kstat_close(smbstat_ksc);
413 458 }
414 459
415 460 /*
416 461 * smbstat_kstat_snapshot
417 462 *
418 463 * Takes a snapshot of the data.
419 464 */
420 465 static void
421 466 smbstat_kstat_snapshot(void)
422 467 {
423 468 smbstat_cpu_snapshot();
424 469 smbstat_srv_snapshot();
425 470 smbstat_wrk_snapshot();
471 + smbstat_clsh_snapshot();
426 472 }
427 473
428 474 /*
429 475 * smbstat_kstat_process
430 476 */
431 477 static void
432 478 smbstat_kstat_process(void)
433 479 {
434 480 smbstat_cpu_process();
435 481 smbstat_srv_process();
436 482 smbstat_wrk_process();
483 + smbstat_clsh_process();
437 484 }
438 485
439 486 /*
440 487 * smbstat_kstat_print
441 488 *
442 489 * Print the data processed.
443 490 */
444 491 static void
445 492 smbstat_kstat_print(void)
446 493 {
447 494 smbstat_termio_init();
448 495 smbstat_print_counters();
449 496 smbstat_print_throughput();
450 497 smbstat_print_utilization();
451 498 smbstat_print_requests();
499 + smbstat_print_client_or_share();
452 500 (void) fflush(stdout);
453 501 }
454 502
455 503 /*
456 504 * smbstat_print_counters
457 505 *
458 506 * Displays the SMB server counters (session, users...).
459 507 */
460 508 static void
461 509 smbstat_print_counters(void)
462 510 {
463 511 if (!smbstat_opt_c)
464 512 return;
465 513
466 514 if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_t ||
467 515 (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
468 516 (void) printf(SMBSRV_COUNTERS_BANNER);
469 517 smbstat_rows = 1;
470 518 }
471 519
472 520 (void) printf(SMBSRV_COUNTERS_FORMAT,
473 521 smbstat_srv_info.si_nbt_sess,
474 522 smbstat_srv_info.si_tcp_sess,
475 523 smbstat_srv_info.si_users,
476 524 smbstat_srv_info.si_trees,
477 525 smbstat_srv_info.si_files,
478 526 smbstat_srv_info.si_pipes);
479 527
480 528 ++smbstat_rows;
481 529 }
482 530 /*
483 531 * smbstat_print_throughput
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
484 532 *
485 533 * Formats the SMB server throughput output.
486 534 */
487 535 static void
488 536 smbstat_print_throughput(void)
489 537 {
490 538 if (!smbstat_opt_t)
491 539 return;
492 540
493 541 if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_c ||
494 - (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
542 + smbstat_opt_C || smbstat_opt_S || (smbstat_rows == 0) ||
543 + (smbstat_rows >= smbstat_ws.ws_row)) {
495 544 (void) printf(SMBSRV_THROUGHPUT_BANNER);
496 545 smbstat_rows = 1;
497 546 }
498 547 (void) printf(SMBSRV_THROUGHPUT_FORMAT,
499 548 smbstat_zero(smbstat_srv_info.si_rbs),
500 549 smbstat_zero(smbstat_srv_info.si_tbs),
501 550 smbstat_zero(smbstat_srv_info.si_rqs),
502 551 smbstat_zero(smbstat_srv_info.si_rds),
503 552 smbstat_zero(smbstat_srv_info.si_wrs));
504 553
505 554 ++smbstat_rows;
506 555 }
507 556
508 557 /*
509 558 * smbstat_print_utilization
510 559 */
511 560 static void
512 561 smbstat_print_utilization(void)
513 562 {
514 563 char *sat;
515 564 if (!smbstat_opt_u)
516 565 return;
517 566
518 567 if (smbstat_opt_t || smbstat_opt_r || smbstat_opt_c ||
519 568 (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
520 569 (void) printf(SMBSRV_UTILIZATION_BANNER);
521 570 smbstat_rows = 1;
522 571 }
523 572
524 573 if (smbstat_srv_info.si_sat)
525 574 sat = "yes";
526 575 else
527 576 sat = "no ";
528 577
529 578 (void) printf(SMBSRV_UTILIZATION_FORMAT,
530 579 smbstat_srv_info.si_avw,
531 580 smbstat_srv_info.si_avr,
532 581 smbstat_srv_info.si_wserv,
533 582 smbstat_srv_info.si_rserv,
534 583 smbstat_zero(smbstat_srv_info.si_wpct),
535 584 smbstat_zero(smbstat_srv_info.si_rpct),
536 585 smbstat_zero(smbstat_srv_info.si_upct),
537 586 sat,
538 587 smbstat_srv_info.si_ticks[CPU_TICKS_USER],
539 588 smbstat_srv_info.si_ticks[CPU_TICKS_KERNEL],
540 589 smbstat_srv_info.si_ticks[CPU_TICKS_IDLE]);
541 590
542 591 ++smbstat_rows;
543 592 }
544 593
545 594 /*
546 595 * smbstat_print_requests
547 596 */
548 597 static void
549 598 smbstat_print_requests(void)
|
↓ open down ↓ |
45 lines elided |
↑ open up ↑ |
550 599 {
551 600 smbstat_req_info_t *prq;
552 601 int i;
553 602
554 603 if (!smbstat_opt_r)
555 604 return;
556 605
557 606 (void) printf(SMBSRV_REQUESTS_BANNER, " ");
558 607
559 608 prq = smbstat_srv_info.si_reqs1;
560 - for (i = 0; i < SMB_COM_NUM; i++) {
609 + for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
561 610 if (!smbstat_opt_a &&
562 611 strncmp(prq[i].ri_name, "Invalid", sizeof ("Invalid")) == 0)
563 612 continue;
564 613
565 614 if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
566 615 (void) printf(SMBSRV_REQUESTS_FORMAT,
567 616 prq[i].ri_name,
568 617 prq[i].ri_opcode,
569 618 smbstat_zero(prq[i].ri_pct),
570 619 smbstat_zero(prq[i].ri_rbs),
571 620 smbstat_zero(prq[i].ri_tbs),
572 621 smbstat_zero(prq[i].ri_rqs),
573 622 prq[i].ri_mean,
574 623 prq[i].ri_stddev);
575 624 }
576 625 }
577 626
578 627 prq = smbstat_srv_info.si_reqs2;
579 - for (i = 0; i < SMB2__NCMDS; i++) {
628 + for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
580 629 if (!smbstat_opt_a && i == SMB2_INVALID_CMD)
581 630 continue;
582 631
583 632 if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
584 633 (void) printf(SMBSRV_REQUESTS_FORMAT,
585 634 prq[i].ri_name,
586 635 prq[i].ri_opcode,
587 636 smbstat_zero(prq[i].ri_pct),
588 637 smbstat_zero(prq[i].ri_rbs),
589 638 smbstat_zero(prq[i].ri_tbs),
590 639 smbstat_zero(prq[i].ri_rqs),
591 640 prq[i].ri_mean,
592 641 prq[i].ri_stddev);
593 642 }
594 643 }
595 644 }
596 645
646 +static void
647 +smbstat_print_client_or_share(void)
648 +{
649 + smbstat_req_info_t *prq;
650 + int idx;
651 +
652 + if (smbstat_opt_clsh == NULL)
653 + return;
654 +
655 + (void) printf(SMBSRV_CLNT_SHARE_BANNER, " ");
656 +
657 + prq = &smbstat_srv_info.si_clsh[0];
658 +
659 + for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++, prq++) {
660 + (void) printf(SMBSRV_CLNT_SHARE_FORMAT,
661 + prq->ri_name,
662 + smbstat_zero(prq->ri_rbs),
663 + smbstat_zero(prq->ri_tbs),
664 + smbstat_zero(prq->ri_rqs),
665 + prq->ri_mean,
666 + prq->ri_stddev);
667 + }
668 +}
669 +
670 +
597 671 /*
598 672 * smbstat_cpu_init
599 673 */
600 674 static void
601 675 smbstat_cpu_init(void)
602 676 {
603 677 size_t size;
604 678 int i;
605 679
606 680 smbstat_nrcpus = sysconf(_SC_CPUID_MAX) + 1;
607 681 size = smbstat_nrcpus * sizeof (smbstat_cpu_snapshot_t);
608 682
609 683 for (i = 0; i < SMBSTAT_SNAPSHOT_COUNT; i++)
610 684 smbstat_cpu_snapshots[i] = smbstat_zalloc(size);
611 685 }
612 686
613 687 /*
614 688 * smbstat_cpu_fini
615 689 */
616 690 static void
617 691 smbstat_cpu_fini(void)
618 692 {
619 693 size_t size;
620 694 int i;
621 695
622 696 size = smbstat_nrcpus * sizeof (smbstat_cpu_snapshot_t);
623 697
624 698 for (i = 0; i < SMBSTAT_SNAPSHOT_COUNT; i++)
625 699 smbstat_free(smbstat_cpu_snapshots[i], size);
626 700 }
627 701
628 702 /*
629 703 * smbstat_cpu_current_snapshot
630 704 */
631 705 static smbstat_cpu_snapshot_t *
632 706 smbstat_cpu_current_snapshot(void)
633 707 {
634 708 return (smbstat_cpu_snapshots[smbstat_snapshot_idx]);
635 709 }
636 710
637 711 /*
638 712 * smbstat_cpu_previous_snapshot
639 713 */
640 714 static smbstat_cpu_snapshot_t *
641 715 smbstat_cpu_previous_snapshot(void)
642 716 {
643 717 int idx;
644 718
645 719 idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
646 720 return (smbstat_cpu_snapshots[idx]);
647 721 }
648 722
649 723 /*
650 724 * smbstat_cpu_snapshot
651 725 */
652 726 static void
653 727 smbstat_cpu_snapshot(void)
654 728 {
655 729 kstat_t *ksp;
656 730 kstat_named_t *ksn;
657 731 smbstat_cpu_snapshot_t *curr;
658 732 long i;
659 733 int j;
660 734
661 735 curr = smbstat_cpu_current_snapshot();
662 736
663 737 for (i = 0; i < smbstat_nrcpus; i++, curr++) {
664 738 curr->cs_id = SMBSTAT_ID_NO_CPU;
665 739 curr->cs_state = p_online(i, P_STATUS);
666 740 /* If no valid CPU is present, move on to the next one */
667 741 if (curr->cs_state == -1)
668 742 continue;
669 743
670 744 curr->cs_id = i;
671 745
672 746 ksp = kstat_lookup(smbstat_ksc, "cpu", i, "sys");
673 747 if (ksp == NULL)
674 748 smbstat_fail(1,
675 749 gettext("kstat_lookup('cpu sys %d') failed"), i);
676 750
677 751 if (kstat_read(smbstat_ksc, ksp, NULL) == -1)
678 752 smbstat_fail(1,
679 753 gettext("kstat_read('cpu sys %d') failed"), i);
680 754
681 755 for (j = 0; j < CPU_TICKS_SENTINEL; j++) {
682 756 ksn = kstat_data_lookup(ksp, smbstat_cpu_states[j]);
683 757 if (ksn == NULL)
684 758 smbstat_fail(1,
685 759 gettext("kstat_data_lookup('%s') failed"),
686 760 smbstat_cpu_states[j]);
687 761 curr->cs_ticks[j] = ksn->value.ui64;
688 762 }
689 763 }
690 764 }
691 765
692 766 /*
693 767 * smbstat_cpu_process
694 768 */
695 769 static void
696 770 smbstat_cpu_process(void)
697 771 {
698 772 smbstat_cpu_snapshot_t *curr, *prev;
699 773 double total_ticks;
700 774 double agg_ticks[CPU_TICKS_SENTINEL];
701 775 int i, j;
702 776
703 777 curr = smbstat_cpu_current_snapshot();
704 778 prev = smbstat_cpu_previous_snapshot();
705 779 bzero(agg_ticks, sizeof (agg_ticks));
706 780 total_ticks = 0;
707 781
708 782 for (i = 0; i < smbstat_nrcpus; i++, curr++, prev++) {
709 783 for (j = 0; j < CPU_TICKS_SENTINEL; j++) {
710 784 agg_ticks[j] += smbstat_sub_64(curr->cs_ticks[j],
711 785 prev->cs_ticks[j]);
712 786 total_ticks += smbstat_sub_64(curr->cs_ticks[j],
713 787 prev->cs_ticks[j]);
714 788 }
715 789 }
716 790
717 791 for (j = 0; j < CPU_TICKS_SENTINEL; j++)
718 792 smbstat_srv_info.si_ticks[j] =
719 793 (agg_ticks[j] * 100.0) / total_ticks;
720 794 }
721 795
722 796 /*
723 797 * smbstat_wrk_init
724 798 */
725 799 static void
726 800 smbstat_wrk_init(void)
727 801 {
728 802 smbstat_wrk_ksp =
729 803 kstat_lookup(smbstat_ksc, "unix", -1, SMBSRV_KSTAT_WORKERS);
730 804 if (smbstat_wrk_ksp == NULL)
731 805 smbstat_fail(1,
732 806 gettext("cannot retrieve smbsrv workers kstat\n"));
733 807 }
734 808
735 809 static void
736 810 smbstat_wrk_fini(void)
737 811 {
738 812 smbstat_wrk_ksp = NULL;
739 813 }
740 814
741 815 /*
742 816 * smbstat_wrk_snapshot
743 817 */
744 818 static void
745 819 smbstat_wrk_snapshot(void)
746 820 {
747 821 smbstat_wrk_snapshot_t *curr;
748 822 kstat_named_t *kn;
749 823
750 824 curr = smbstat_wrk_current_snapshot();
751 825
752 826 if (kstat_read(smbstat_ksc, smbstat_wrk_ksp, NULL) == -1)
753 827 smbstat_fail(1, gettext("kstat_read('%s') failed"),
754 828 smbstat_wrk_ksp->ks_name);
755 829
756 830 kn = kstat_data_lookup(smbstat_wrk_ksp, "maxthreads");
757 831 if ((kn == NULL) || (kn->data_type != KSTAT_DATA_UINT64))
758 832 smbstat_fail(1, gettext("kstat_read('%s') failed"),
759 833 "maxthreads");
760 834 curr->ws_maxthreads = kn->value.ui64;
761 835
762 836 kn = kstat_data_lookup(smbstat_wrk_ksp, "bnalloc");
763 837 if ((kn == NULL) || (kn->data_type != KSTAT_DATA_UINT64))
764 838 smbstat_fail(1, gettext("kstat_read('%s') failed"),
765 839 "bnalloc");
766 840 curr->ws_bnalloc = kn->value.ui64;
767 841 }
768 842
769 843 /*
770 844 * smbstat_wrk_process
771 845 */
772 846 static void
773 847 smbstat_wrk_process(void)
774 848 {
775 849 smbstat_wrk_snapshot_t *curr;
776 850
777 851 curr = smbstat_wrk_current_snapshot();
778 852
779 853 if (curr->ws_bnalloc >= curr->ws_maxthreads)
780 854 smbstat_srv_info.si_sat = B_TRUE;
781 855 else
782 856 smbstat_srv_info.si_sat = B_FALSE;
783 857 }
784 858
|
↓ open down ↓ |
178 lines elided |
↑ open up ↑ |
785 859 /*
786 860 * smbstat_wrk_current_snapshot
787 861 */
788 862 static smbstat_wrk_snapshot_t *
789 863 smbstat_wrk_current_snapshot(void)
790 864 {
791 865 return (&smbstat_wrk_snapshots[smbstat_snapshot_idx]);
792 866 }
793 867
794 868 /*
869 + * smbstat_clsh_init
870 + *
871 + * Lookup the kstat for the client or share specified.
872 + * The names for these look like:
873 + * session (a.k.a. client)
874 + * cl/$IPADDR and instance ss->s_kid
875 + * share
876 + * sh/sharename (always instance 0)
877 + *
878 + * These will look like: smbsrv:0:sh/myshare
879 + * or smbsrv:N:cl/10.10.0.2
880 + */
881 +static void
882 +smbstat_clsh_init(void)
883 +{
884 + static const char *kr_names[] = SMBSRV_CLSH__NAMES;
885 + char ks_name[KSTAT_STRLEN];
886 + char *prefix = "";
887 + smbstat_req_info_t *info;
888 + int instance = -1;
889 + int i;
890 +
891 + if (smbstat_opt_clsh == NULL)
892 + return;
893 +
894 + /*
895 + * Currently we don't take an instance so this will return data
896 + * from the first or the only client from the IP address specified.
897 + */
898 + if (smbstat_opt_C)
899 + prefix = "cl";
900 + if (smbstat_opt_S)
901 + prefix = "sh";
902 + (void) snprintf(ks_name, sizeof (ks_name),
903 + "%s/%s", prefix, smbstat_opt_clsh);
904 +
905 + smbstat_clsh_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
906 + instance, ks_name);
907 + if (smbstat_clsh_ksp == NULL) {
908 + smbstat_fail(1, gettext("cannot retrieve smbsrv %s kstat\n"),
909 + ks_name);
910 + }
911 +
912 + info = smbstat_srv_info.si_clsh;
913 + for (i = 0; i < SMBSRV_CLSH__NREQ; i++) {
914 + (void) strlcpy(info[i].ri_name, kr_names[i],
915 + sizeof (info[i].ri_name));
916 + }
917 +}
918 +
919 +static void
920 +smbstat_clsh_fini(void)
921 +{
922 + smbstat_clsh_ksp = NULL;
923 +}
924 +
925 +/*
926 + * smbstat_clsh_snapshot
927 + */
928 +static void
929 +smbstat_clsh_snapshot(void)
930 +{
931 + smbstat_clsh_snapshot_t *curr;
932 +
933 + if (smbstat_clsh_ksp == NULL)
934 + return;
935 +
936 + curr = smbstat_clsh_current_snapshot();
937 +
938 + if ((kstat_read(smbstat_ksc, smbstat_clsh_ksp, NULL) == -1) ||
939 + (smbstat_clsh_ksp->ks_data_size != sizeof (curr->cs_data)))
940 + smbstat_fail(1, gettext("kstat_read('%s') failed"),
941 + smbstat_clsh_ksp->ks_name);
942 +
943 + curr->cs_snaptime = smbstat_clsh_ksp->ks_snaptime;
944 +
945 + bcopy(smbstat_clsh_ksp->ks_data, &curr->cs_data,
946 + sizeof (curr->cs_data));
947 +}
948 +
949 +/*
950 + * smbstat_clsh_process
951 + */
952 +static void
953 +smbstat_clsh_process(void)
954 +{
955 + smbstat_clsh_snapshot_t *curr, *prev;
956 + boolean_t firstcall;
957 + int idx;
958 +
959 + curr = smbstat_clsh_current_snapshot();
960 + prev = smbstat_clsh_previous_snapshot();
961 + firstcall = (prev->cs_snaptime == 0);
962 +
963 +
964 + for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++) {
965 + smbstat_srv_process_one_req(
966 + &smbstat_srv_info.si_clsh[idx],
967 + &curr->cs_data.ks_clsh[idx],
968 + &prev->cs_data.ks_clsh[idx],
969 + firstcall);
970 + }
971 +}
972 +
973 +/*
974 + * smbstat_clsh_current_snapshot
975 + */
976 +static smbstat_clsh_snapshot_t *
977 +smbstat_clsh_current_snapshot(void)
978 +{
979 + return (&smbstat_clsh_snapshots[smbstat_snapshot_idx]);
980 +}
981 +
982 +static smbstat_clsh_snapshot_t *
983 +smbstat_clsh_previous_snapshot(void)
984 +{
985 + int idx;
986 +
987 + idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
988 + return (&smbstat_clsh_snapshots[idx]);
989 +}
990 +
991 +/*
795 992 * smbstat_srv_init
796 993 */
797 994 static void
798 995 smbstat_srv_init(void)
799 996 {
800 997 smbstat_srv_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
801 - getzoneid(), SMBSRV_KSTAT_STATISTICS);
998 + -1, SMBSRV_KSTAT_STATISTICS);
802 999 if (smbstat_srv_ksp == NULL)
803 1000 smbstat_fail(1, gettext("cannot retrieve smbsrv kstat\n"));
804 1001 }
805 1002
806 1003 /*
807 1004 * smbstat_srv_fini
808 1005 */
809 1006 static void
810 1007 smbstat_srv_fini(void)
811 1008 {
812 1009 smbstat_srv_ksp = NULL;
813 1010 }
814 1011
815 1012 /*
816 1013 * smbstat_srv_snapshot
817 1014 *
818 1015 * Take a snapshot of the smbsrv module statistics.
819 1016 */
820 1017 static void
821 1018 smbstat_srv_snapshot(void)
822 1019 {
823 1020 smbstat_srv_snapshot_t *curr;
824 1021
825 1022 curr = smbstat_srv_current_snapshot();
826 1023
827 1024 if ((kstat_read(smbstat_ksc, smbstat_srv_ksp, NULL) == -1) ||
828 1025 (smbstat_srv_ksp->ks_data_size != sizeof (curr->ss_data)))
829 1026 smbstat_fail(1, gettext("kstat_read('%s') failed"),
830 1027 smbstat_srv_ksp->ks_name);
831 1028
832 1029 curr->ss_snaptime = smbstat_srv_ksp->ks_snaptime;
833 1030 bcopy(smbstat_srv_ksp->ks_data, &curr->ss_data, sizeof (curr->ss_data));
834 1031 }
835 1032
836 1033 /*
837 1034 * smbstat_srv_process
838 1035 *
839 1036 * Processes the snapshot data.
840 1037 */
841 1038 static void
842 1039 smbstat_srv_process(void)
843 1040 {
844 1041 smbstat_srv_snapshot_t *curr, *prev;
845 1042
846 1043 curr = smbstat_srv_current_snapshot();
847 1044 prev = smbstat_srv_previous_snapshot();
848 1045
849 1046 if (prev->ss_snaptime == 0)
850 1047 smbstat_srv_info.si_hretime =
851 1048 smbstat_hrtime_delta(curr->ss_data.ks_start_time,
852 1049 curr->ss_snaptime);
853 1050 else
854 1051 smbstat_srv_info.si_hretime =
855 1052 smbstat_hrtime_delta(prev->ss_snaptime, curr->ss_snaptime);
856 1053
857 1054 smbstat_srv_info.si_etime = smbstat_srv_info.si_hretime / NANOSEC;
858 1055 smbstat_srv_info.si_total_nreqs =
859 1056 smbstat_sub_64(curr->ss_data.ks_nreq, prev->ss_data.ks_nreq);
860 1057
861 1058 if (smbstat_opt_c)
862 1059 smbstat_srv_process_counters(curr);
863 1060 if (smbstat_opt_t)
864 1061 smbstat_srv_process_throughput(curr, prev);
865 1062 if (smbstat_opt_u)
866 1063 smbstat_srv_process_utilization(curr, prev);
867 1064 if (smbstat_opt_r)
868 1065 smbstat_srv_process_requests(curr, prev);
869 1066 }
870 1067
871 1068 /*
872 1069 * smbstat_srv_process_counters
873 1070 */
874 1071 static void
875 1072 smbstat_srv_process_counters(smbstat_srv_snapshot_t *curr)
876 1073 {
877 1074 smbstat_srv_info.si_nbt_sess = curr->ss_data.ks_nbt_sess;
878 1075 smbstat_srv_info.si_tcp_sess = curr->ss_data.ks_tcp_sess;
879 1076 smbstat_srv_info.si_users = curr->ss_data.ks_users;
880 1077 smbstat_srv_info.si_trees = curr->ss_data.ks_trees;
881 1078 smbstat_srv_info.si_files = curr->ss_data.ks_files;
882 1079 smbstat_srv_info.si_pipes = curr->ss_data.ks_pipes;
883 1080 }
884 1081
885 1082 /*
886 1083 * smbstat_srv_process_throughput
887 1084 *
888 1085 * Processes the data relative to the throughput of the smbsrv module and
889 1086 * stores the results in the structure smbstat_srv_info.
890 1087 */
891 1088 static void
892 1089 smbstat_srv_process_throughput(
893 1090 smbstat_srv_snapshot_t *curr,
894 1091 smbstat_srv_snapshot_t *prev)
895 1092 {
896 1093 smbstat_srv_info.si_tbs =
897 1094 smbstat_sub_64(curr->ss_data.ks_txb, prev->ss_data.ks_txb);
898 1095 smbstat_srv_info.si_tbs /= smbstat_srv_info.si_etime;
899 1096 smbstat_srv_info.si_rbs =
900 1097 smbstat_sub_64(curr->ss_data.ks_rxb, prev->ss_data.ks_rxb);
901 1098 smbstat_srv_info.si_rbs /= smbstat_srv_info.si_etime;
902 1099 smbstat_srv_info.si_rqs = smbstat_srv_info.si_total_nreqs;
903 1100 smbstat_srv_info.si_rqs /= smbstat_srv_info.si_etime;
904 1101
905 1102 smbstat_srv_info.si_rds = smbstat_sub_64(
906 1103 curr->ss_data.ks_reqs1[SMB_COM_READ].kr_nreq,
907 1104 prev->ss_data.ks_reqs1[SMB_COM_READ].kr_nreq);
908 1105 smbstat_srv_info.si_rds += smbstat_sub_64(
909 1106 curr->ss_data.ks_reqs1[SMB_COM_LOCK_AND_READ].kr_nreq,
910 1107 prev->ss_data.ks_reqs1[SMB_COM_LOCK_AND_READ].kr_nreq);
911 1108 smbstat_srv_info.si_rds += smbstat_sub_64(
912 1109 curr->ss_data.ks_reqs1[SMB_COM_READ_RAW].kr_nreq,
913 1110 prev->ss_data.ks_reqs1[SMB_COM_READ_RAW].kr_nreq);
914 1111 smbstat_srv_info.si_rds += smbstat_sub_64(
915 1112 curr->ss_data.ks_reqs1[SMB_COM_READ_ANDX].kr_nreq,
916 1113 prev->ss_data.ks_reqs1[SMB_COM_READ_ANDX].kr_nreq);
917 1114 smbstat_srv_info.si_rds += smbstat_sub_64(
918 1115 curr->ss_data.ks_reqs2[SMB2_READ].kr_nreq,
919 1116 prev->ss_data.ks_reqs2[SMB2_READ].kr_nreq);
920 1117 smbstat_srv_info.si_rds /= smbstat_srv_info.si_etime;
921 1118
922 1119 smbstat_srv_info.si_wrs = smbstat_sub_64(
923 1120 curr->ss_data.ks_reqs1[SMB_COM_WRITE].kr_nreq,
924 1121 prev->ss_data.ks_reqs1[SMB_COM_WRITE].kr_nreq);
925 1122 smbstat_srv_info.si_wrs += smbstat_sub_64(
926 1123 curr->ss_data.ks_reqs1[SMB_COM_WRITE_AND_UNLOCK].kr_nreq,
927 1124 prev->ss_data.ks_reqs1[SMB_COM_WRITE_AND_UNLOCK].kr_nreq);
928 1125 smbstat_srv_info.si_wrs += smbstat_sub_64(
929 1126 curr->ss_data.ks_reqs1[SMB_COM_WRITE_RAW].kr_nreq,
930 1127 prev->ss_data.ks_reqs1[SMB_COM_WRITE_RAW].kr_nreq);
931 1128 smbstat_srv_info.si_wrs += smbstat_sub_64(
932 1129 curr->ss_data.ks_reqs1[SMB_COM_WRITE_AND_CLOSE].kr_nreq,
933 1130 prev->ss_data.ks_reqs1[SMB_COM_WRITE_AND_CLOSE].kr_nreq);
934 1131 smbstat_srv_info.si_wrs += smbstat_sub_64(
935 1132 curr->ss_data.ks_reqs1[SMB_COM_WRITE_ANDX].kr_nreq,
936 1133 prev->ss_data.ks_reqs1[SMB_COM_WRITE_ANDX].kr_nreq);
937 1134 smbstat_srv_info.si_wrs += smbstat_sub_64(
938 1135 curr->ss_data.ks_reqs2[SMB2_WRITE].kr_nreq,
939 1136 prev->ss_data.ks_reqs2[SMB2_WRITE].kr_nreq);
940 1137 smbstat_srv_info.si_wrs /= smbstat_srv_info.si_etime;
941 1138 }
942 1139
943 1140 /*
944 1141 * smbstat_srv_process_utilization
945 1142 *
946 1143 * Processes the data relative to the utilization of the smbsrv module and
947 1144 * stores the results in the structure smbstat_srv_info.
948 1145 */
949 1146 static void
950 1147 smbstat_srv_process_utilization(
951 1148 smbstat_srv_snapshot_t *curr,
952 1149 smbstat_srv_snapshot_t *prev)
953 1150 {
954 1151 double tw_delta, tr_delta;
955 1152 double w_delta, r_delta;
956 1153 double tps, rqs;
957 1154
958 1155 w_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_wlentime,
959 1156 curr->ss_data.ks_utilization.ku_wlentime);
960 1157 r_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_rlentime,
961 1158 curr->ss_data.ks_utilization.ku_rlentime);
962 1159 tw_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_wtime,
963 1160 curr->ss_data.ks_utilization.ku_wtime);
964 1161 tr_delta = smbstat_hrtime_delta(prev->ss_data.ks_utilization.ku_rtime,
965 1162 curr->ss_data.ks_utilization.ku_rtime);
966 1163 rqs = smbstat_srv_info.si_total_nreqs / smbstat_srv_info.si_etime;
967 1164
968 1165 /* Average number of requests waiting */
969 1166 if (w_delta != 0)
970 1167 smbstat_srv_info.si_avw = w_delta / smbstat_srv_info.si_hretime;
971 1168 else
972 1169 smbstat_srv_info.si_avw = 0.0;
973 1170
974 1171 /* Average number of request running */
975 1172 if (r_delta != 0)
976 1173 smbstat_srv_info.si_avr = r_delta / smbstat_srv_info.si_hretime;
977 1174 else
978 1175 smbstat_srv_info.si_avr = 0.0;
979 1176
980 1177 /* Utilization */
981 1178 smbstat_srv_info.si_upct =
982 1179 (smbstat_srv_info.si_avr / curr->ss_data.ks_maxreqs) * 100;
983 1180
984 1181 /* Average wait service time in milliseconds */
985 1182 smbstat_srv_info.si_rserv = 0.0;
986 1183 smbstat_srv_info.si_wserv = 0.0;
987 1184 if (rqs > 0.0 &&
988 1185 (smbstat_srv_info.si_avw != 0.0 ||
989 1186 smbstat_srv_info.si_avr != 0.0)) {
990 1187 tps = 1 / rqs;
991 1188 if (smbstat_srv_info.si_avw != 0.0)
992 1189 smbstat_srv_info.si_wserv =
993 1190 smbstat_srv_info.si_avw * tps;
994 1191 if (smbstat_srv_info.si_avr != 0.0)
995 1192 smbstat_srv_info.si_rserv =
996 1193 smbstat_srv_info.si_avr * tps;
997 1194 }
998 1195
999 1196 /* % of time there is a transaction waiting for service */
1000 1197 if (tw_delta != 0) {
1001 1198 smbstat_srv_info.si_wpct = tw_delta;
1002 1199 smbstat_srv_info.si_wpct /= smbstat_srv_info.si_hretime;
1003 1200 smbstat_srv_info.si_wpct *= 100.0;
1004 1201 } else {
1005 1202 smbstat_srv_info.si_wpct = 0.0;
1006 1203 }
1007 1204
1008 1205 /* % of time there is a transaction running */
1009 1206 if (tr_delta != 0) {
1010 1207 smbstat_srv_info.si_rpct = tr_delta;
1011 1208 smbstat_srv_info.si_rpct /= smbstat_srv_info.si_hretime;
1012 1209 smbstat_srv_info.si_rpct *= 100.0;
1013 1210 } else {
1014 1211 smbstat_srv_info.si_rpct = 0.0;
1015 1212 }
1016 1213 }
1017 1214
1018 1215 /*
1019 1216 * smbstat_srv_process_requests
1020 1217 *
1021 1218 * Processes the data relative to the SMB requests and stores the results in
1022 1219 * the structure smbstat_srv_info.
1023 1220 */
1024 1221 static void
|
↓ open down ↓ |
213 lines elided |
↑ open up ↑ |
1025 1222 smbstat_srv_process_requests(
1026 1223 smbstat_srv_snapshot_t *curr,
1027 1224 smbstat_srv_snapshot_t *prev)
1028 1225 {
1029 1226 smbstat_req_info_t *info;
1030 1227 smb_kstat_req_t *curr_req;
1031 1228 smb_kstat_req_t *prev_req;
1032 1229 int i, idx;
1033 1230 boolean_t firstcall = (prev->ss_snaptime == 0);
1034 1231
1035 - for (i = 0; i < SMB_COM_NUM; i++) {
1232 + for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
1036 1233 info = &smbstat_srv_info.si_reqs1[i];
1037 1234 idx = info[i].ri_opcode & 0xFF;
1038 1235 curr_req = &curr->ss_data.ks_reqs1[idx];
1039 1236 prev_req = &prev->ss_data.ks_reqs1[idx];
1040 1237 smbstat_srv_process_one_req(
1041 1238 info, curr_req, prev_req, firstcall);
1042 1239 }
1043 1240
1044 - for (i = 0; i < SMB2__NCMDS; i++) {
1241 + for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
1045 1242 info = &smbstat_srv_info.si_reqs2[i];
1046 1243 curr_req = &curr->ss_data.ks_reqs2[i];
1047 1244 prev_req = &prev->ss_data.ks_reqs2[i];
1048 1245 smbstat_srv_process_one_req(
1049 1246 info, curr_req, prev_req, firstcall);
1050 1247 }
1051 1248 }
1052 1249
1053 1250 static void
1054 1251 smbstat_srv_process_one_req(
1055 1252 smbstat_req_info_t *info,
1056 1253 smb_kstat_req_t *curr_req,
1057 1254 smb_kstat_req_t *prev_req,
1058 1255 boolean_t firstcall)
1059 1256 {
1060 1257 double nrqs;
1061 1258
1062 1259 nrqs = smbstat_sub_64(curr_req->kr_nreq,
1063 1260 prev_req->kr_nreq);
1064 1261
1065 1262 info->ri_rqs = nrqs / smbstat_srv_info.si_etime;
1066 1263
1067 1264 info->ri_rbs = smbstat_sub_64(
1068 1265 curr_req->kr_rxb,
1069 1266 prev_req->kr_rxb) /
1070 1267 smbstat_srv_info.si_etime;
1071 1268
1072 1269 info->ri_tbs = smbstat_sub_64(
1073 1270 curr_req->kr_txb,
1074 1271 prev_req->kr_txb) /
1075 1272 smbstat_srv_info.si_etime;
1076 1273
1077 1274 info->ri_pct = nrqs * 100;
1078 1275 if (smbstat_srv_info.si_total_nreqs > 0)
1079 1276 info->ri_pct /= smbstat_srv_info.si_total_nreqs;
1080 1277
1081 1278 if (firstcall) {
1082 1279 /* First time. Take the aggregate */
1083 1280 info->ri_stddev =
1084 1281 curr_req->kr_a_stddev;
1085 1282 info->ri_mean = curr_req->kr_a_mean;
1086 1283 } else {
1087 1284 /* Take the differential */
1088 1285 info->ri_stddev =
1089 1286 curr_req->kr_d_stddev;
1090 1287 info->ri_mean = curr_req->kr_d_mean;
1091 1288 }
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
1092 1289 if (nrqs > 0) {
1093 1290 info->ri_stddev /= nrqs;
1094 1291 info->ri_stddev = sqrt(info->ri_stddev);
1095 1292 } else {
1096 1293 info->ri_stddev = 0;
1097 1294 }
1098 1295 info->ri_stddev /= NANOSEC;
1099 1296 info->ri_mean /= NANOSEC;
1100 1297 }
1101 1298
1102 -
1103 1299 /*
1104 1300 * smbstat_srv_current_snapshot
1105 1301 *
1106 1302 * Returns the current snapshot.
1107 1303 */
1108 1304 static smbstat_srv_snapshot_t *
1109 1305 smbstat_srv_current_snapshot(void)
1110 1306 {
1111 1307 return (&smbstat_srv_snapshots[smbstat_snapshot_idx]);
1112 1308 }
1113 1309
1114 1310 /*
1115 1311 * smbstat_srv_previous_snapshot
1116 1312 *
1117 1313 * Returns the previous snapshot.
1118 1314 */
1119 1315 static smbstat_srv_snapshot_t *
1120 1316 smbstat_srv_previous_snapshot(void)
1121 1317 {
1122 1318 int idx;
1123 1319
1124 1320 idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
1125 1321 return (&smbstat_srv_snapshots[idx]);
1126 1322 }
1127 1323
1128 1324 /*
1129 1325 * smbstat_usage
1130 1326 *
1131 1327 * Prints out a help message.
1132 1328 */
1133 1329 static void
1134 1330 smbstat_usage(FILE *fd, int exit_code)
1135 1331 {
1136 1332 (void) fprintf(fd, gettext(SMBSTAT_HELP));
1137 1333 exit(exit_code);
1138 1334 }
1139 1335
1140 1336 /*
1141 1337 * smbstat_fail
1142 1338 *
1143 1339 * Prints out to stderr an error message and exits the process.
1144 1340 */
1145 1341 static void
1146 1342 smbstat_fail(int do_perror, char *message, ...)
1147 1343 {
1148 1344 va_list args;
1149 1345
1150 1346 va_start(args, message);
1151 1347 (void) fprintf(stderr, gettext("smbstat: "));
1152 1348 /* LINTED E_SEC_PRINTF_VAR_FMT */
1153 1349 (void) vfprintf(stderr, message, args);
1154 1350 va_end(args);
1155 1351 if (do_perror)
1156 1352 (void) fprintf(stderr, ": %s", strerror(errno));
1157 1353 (void) fprintf(stderr, "\n");
1158 1354 exit(1);
1159 1355 }
1160 1356
1161 1357 /*
1162 1358 * smbstat_sub_64
1163 1359 *
1164 1360 * Substract 2 uint64_t and returns a double.
1165 1361 */
1166 1362 static double
1167 1363 smbstat_sub_64(uint64_t a, uint64_t b)
1168 1364 {
1169 1365 return ((double)(a - b));
1170 1366 }
1171 1367
1172 1368 /*
1173 1369 * smbstat_zero
1174 1370 *
1175 1371 * Returns zero if the value passed in is less than 1.
1176 1372 */
1177 1373 static double
1178 1374 smbstat_zero(double value)
1179 1375 {
1180 1376 if (value < 1)
1181 1377 value = 0;
1182 1378 return (value);
1183 1379 }
1184 1380
1185 1381 /*
1186 1382 * smbstat_strtoi
1187 1383 *
1188 1384 * Converts a string representing an integer value into its binary value.
1189 1385 * If the conversion fails this routine exits the process.
1190 1386 */
1191 1387 static uint_t
1192 1388 smbstat_strtoi(char const *val, char *errmsg)
1193 1389 {
1194 1390 char *end;
1195 1391 long tmp;
1196 1392
1197 1393 errno = 0;
1198 1394 tmp = strtol(val, &end, 10);
1199 1395 if (*end != '\0' || errno)
1200 1396 smbstat_fail(1, "%s %s", errmsg, val);
1201 1397 return ((uint_t)tmp);
1202 1398 }
1203 1399
1204 1400 /*
1205 1401 * smbstat_termio_init
1206 1402 *
1207 1403 * Determines the size of the terminal associated with the process.
1208 1404 */
1209 1405 static void
1210 1406 smbstat_termio_init(void)
1211 1407 {
1212 1408 char *envp;
1213 1409
1214 1410 if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &smbstat_ws) != -1) {
1215 1411 if (smbstat_ws.ws_row == 0) {
1216 1412 envp = getenv("LINES");
1217 1413 if (envp != NULL)
1218 1414 smbstat_ws.ws_row = atoi(envp);
1219 1415 }
1220 1416
1221 1417 if (smbstat_ws.ws_col == 0) {
1222 1418 envp = getenv("COLUMNS");
1223 1419 if (envp != NULL)
1224 1420 smbstat_ws.ws_row = atoi(envp);
1225 1421 }
1226 1422 }
1227 1423 if (smbstat_ws.ws_col == 0)
1228 1424 smbstat_ws.ws_col = 80;
1229 1425 if (smbstat_ws.ws_row == 0)
1230 1426 smbstat_ws.ws_row = 25;
1231 1427 }
1232 1428
1233 1429 /*
1234 1430 * smbstat_snapshot_idx_inc
1235 1431 *
1236 1432 * Increments the snapshot index.
1237 1433 */
1238 1434 static void
1239 1435 smbstat_snapshot_inc_idx(void)
1240 1436 {
1241 1437 smbstat_snapshot_idx++;
1242 1438 smbstat_snapshot_idx &= SMBSTAT_SNAPSHOT_MASK;
1243 1439 }
1244 1440
1245 1441 /*
1246 1442 * smbstat_req_cmp_name
1247 1443 *
1248 1444 * Call back function passed to qsort() when the list of requests must be sorted
1249 1445 * by name.
1250 1446 */
1251 1447 static int
1252 1448 smbstat_req_cmp_name(const void *obj1, const void *obj2)
1253 1449 {
1254 1450 return (strncasecmp(
1255 1451 ((smbstat_req_info_t *)obj1)->ri_name,
1256 1452 ((smbstat_req_info_t *)obj2)->ri_name,
1257 1453 sizeof (((smbstat_req_info_t *)obj2)->ri_name)));
1258 1454 }
1259 1455
1260 1456 /*
1261 1457 * smbstat_req_order
1262 1458 *
1263 1459 * Snapshots the smbsrv module statistics once to get the name of the requests.
1264 1460 * The request list is smbstat_srv_info is then sorted by name or by code
1265 1461 * depending on the boolean smbstat_opt_a.
1266 1462 * The function should be called once during initialization.
1267 1463 */
1268 1464 static void
1269 1465 smbstat_req_order(void)
1270 1466 {
|
↓ open down ↓ |
158 lines elided |
↑ open up ↑ |
1271 1467 smbstat_srv_snapshot_t *ss;
1272 1468 smbstat_req_info_t *info;
1273 1469 smb_kstat_req_t *reqs;
1274 1470 int i;
1275 1471
1276 1472 smbstat_srv_snapshot();
1277 1473 ss = smbstat_srv_current_snapshot();
1278 1474
1279 1475 reqs = ss->ss_data.ks_reqs1;
1280 1476 info = smbstat_srv_info.si_reqs1;
1281 - for (i = 0; i < SMB_COM_NUM; i++) {
1477 + for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
1282 1478 (void) strlcpy(info[i].ri_name, reqs[i].kr_name,
1283 1479 sizeof (reqs[i].kr_name));
1284 1480 info[i].ri_opcode = i;
1285 1481 }
1286 1482 if (smbstat_opt_n)
1287 - qsort(info, SMB_COM_NUM, sizeof (smbstat_req_info_t),
1483 + qsort(info, SMBSRV_KS_NREQS1, sizeof (smbstat_req_info_t),
1288 1484 smbstat_req_cmp_name);
1289 1485
1290 1486 reqs = ss->ss_data.ks_reqs2;
1291 1487 info = smbstat_srv_info.si_reqs2;
1292 - for (i = 0; i < SMB2__NCMDS; i++) {
1488 + for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
1293 1489 (void) strlcpy(info[i].ri_name, reqs[i].kr_name,
1294 1490 sizeof (reqs[i].kr_name));
1295 1491 info[i].ri_opcode = i;
1296 1492 }
1297 1493 if (smbstat_opt_n)
1298 - qsort(info, SMB2__NCMDS, sizeof (smbstat_req_info_t),
1494 + qsort(info, SMBSRV_KS_NREQS2, sizeof (smbstat_req_info_t),
1299 1495 smbstat_req_cmp_name);
1300 1496 }
1301 1497
1302 1498 /*
1303 1499 * Return the number of ticks delta between two hrtime_t
1304 1500 * values. Attempt to cater for various kinds of overflow
1305 1501 * in hrtime_t - no matter how improbable.
1306 1502 */
1307 1503 static double
1308 1504 smbstat_hrtime_delta(hrtime_t old, hrtime_t new)
1309 1505 {
1310 1506 uint64_t del;
1311 1507
1312 1508 if ((new >= old) && (old >= 0L))
1313 1509 return ((double)(new - old));
1314 1510 /*
1315 1511 * We've overflowed the positive portion of an hrtime_t.
1316 1512 */
1317 1513 if (new < 0L) {
1318 1514 /*
1319 1515 * The new value is negative. Handle the case where the old
1320 1516 * value is positive or negative.
1321 1517 */
1322 1518 uint64_t n1;
1323 1519 uint64_t o1;
1324 1520
1325 1521 n1 = -new;
1326 1522 if (old > 0L)
1327 1523 return ((double)(n1 - old));
1328 1524
1329 1525 o1 = -old;
1330 1526 del = n1 - o1;
1331 1527 return ((double)del);
1332 1528 }
1333 1529
1334 1530 /*
1335 1531 * Either we've just gone from being negative to positive *or* the last
1336 1532 * entry was positive and the new entry is also positive but *less* than
1337 1533 * the old entry. This implies we waited quite a few days on a very fast
1338 1534 * system between displays.
1339 1535 */
1340 1536 if (old < 0L) {
1341 1537 uint64_t o2;
1342 1538 o2 = -old;
1343 1539 del = UINT64_MAX - o2;
1344 1540 } else {
1345 1541 del = UINT64_MAX - old;
1346 1542 }
1347 1543 del += new;
1348 1544 return ((double)del);
1349 1545 }
1350 1546
1351 1547 static void *
1352 1548 smbstat_zalloc(size_t size)
1353 1549 {
1354 1550 void *ptr;
1355 1551
1356 1552 ptr = umem_zalloc(size, UMEM_DEFAULT);
1357 1553 if (ptr == NULL)
1358 1554 smbstat_fail(1, gettext("out of memory"));
1359 1555 return (ptr);
1360 1556 }
1361 1557
1362 1558 static void
1363 1559 smbstat_free(void *ptr, size_t size)
1364 1560 {
1365 1561 umem_free(ptr, size);
1366 1562 }
|
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX