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).
*** 19,29 ****
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* smbstat: Server Message Block File System statistics
*
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
*/
/*
* smbstat: Server Message Block File System statistics
*
*** 101,110 ****
--- 101,112 ----
#include <stropts.h>
#include <math.h>
#include <umem.h>
#include <locale.h>
#include <smbsrv/smb_kstat.h>
+ #include <smbsrv/smb.h>
+ #include <smbsrv/smb2.h>
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif /* TEXT_DOMAIN */
*** 142,151 ****
--- 144,159 ----
"\n%30s code %% rbytes/s tbytes/s req/s rt-mean" \
" rt-stddev\n"
#define SMBSRV_REQUESTS_FORMAT \
"%30s %02X %3.0f %1.3e %1.3e %1.3e %1.3e %1.3e\n"
+ #define SMBSRV_CLNT_SHARE_BANNER \
+ "%30s rbytes/s tbytes/s req/s rt-mean rt-stddev\n"
+ #define SMBSRV_CLNT_SHARE_FORMAT \
+ "%30s %1.3e %1.3e %1.3e %1.3e %1.3e\n"
+
+
typedef enum {
CPU_TICKS_IDLE = 0,
CPU_TICKS_USER,
CPU_TICKS_KERNEL,
CPU_TICKS_SENTINEL
*** 165,174 ****
--- 173,188 ----
typedef struct smbstat_wrk_snapshot {
uint64_t ws_maxthreads;
uint64_t ws_bnalloc;
} smbstat_wrk_snapshot_t;
+ /* Per-Client or Per-Share statistics. */
+ typedef struct smbstat_clsh_snapshot {
+ hrtime_t cs_snaptime;
+ smbsrv_clsh_kstats_t cs_data;
+ } smbstat_clsh_snapshot_t;
+
typedef struct smbstat_req_info {
char ri_name[KSTAT_STRLEN];
int ri_opcode;
double ri_pct;
double ri_tbs;
*** 212,223 ****
boolean_t si_sat;
double si_ticks[CPU_TICKS_SENTINEL];
/*
* Latency & Throughput per request
*/
! smbstat_req_info_t si_reqs1[SMB_COM_NUM];
! smbstat_req_info_t si_reqs2[SMB2__NCMDS];
} smbstat_srv_info_t;
static void smbstat_init(void);
static void smbstat_fini(void);
static void smbstat_kstat_snapshot(void);
--- 226,241 ----
boolean_t si_sat;
double si_ticks[CPU_TICKS_SENTINEL];
/*
* Latency & Throughput per request
*/
! smbstat_req_info_t si_reqs1[SMBSRV_KS_NREQS1];
! smbstat_req_info_t si_reqs2[SMBSRV_KS_NREQS2];
! /*
! * Latency & Throughput on specified client or share
! */
! smbstat_req_info_t si_clsh[SMBSRV_CLSH__NREQ];
} smbstat_srv_info_t;
static void smbstat_init(void);
static void smbstat_fini(void);
static void smbstat_kstat_snapshot(void);
*** 226,235 ****
--- 244,254 ----
static void smbstat_print_counters(void);
static void smbstat_print_throughput(void);
static void smbstat_print_utilization(void);
static void smbstat_print_requests(void);
+ static void smbstat_print_client_or_share(void);
static void smbstat_cpu_init(void);
static void smbstat_cpu_fini(void);
static smbstat_cpu_snapshot_t *smbstat_cpu_current_snapshot(void);
static smbstat_cpu_snapshot_t *smbstat_cpu_previous_snapshot(void);
*** 240,249 ****
--- 259,275 ----
static void smbstat_wrk_fini(void);
static void smbstat_wrk_snapshot(void);
static void smbstat_wrk_process(void);
static smbstat_wrk_snapshot_t *smbstat_wrk_current_snapshot(void);
+ static void smbstat_clsh_init(void);
+ static void smbstat_clsh_fini(void);
+ static void smbstat_clsh_snapshot(void);
+ static void smbstat_clsh_process(void);
+ static smbstat_clsh_snapshot_t *smbstat_clsh_current_snapshot(void);
+ static smbstat_clsh_snapshot_t *smbstat_clsh_previous_snapshot(void);
+
static void smbstat_srv_init(void);
static void smbstat_srv_fini(void);
static void smbstat_srv_snapshot(void);
static void smbstat_srv_process(void);
static void smbstat_srv_process_counters(smbstat_srv_snapshot_t *);
*** 284,306 ****
--- 310,337 ----
static boolean_t smbstat_opt_n = B_FALSE; /* by name */
static boolean_t smbstat_opt_u = B_FALSE; /* utilization */
static boolean_t smbstat_opt_t = B_FALSE; /* throughput */
static boolean_t smbstat_opt_r = B_FALSE; /* requests */
static boolean_t smbstat_opt_z = B_FALSE; /* non-zero requests */
+ static boolean_t smbstat_opt_C = B_FALSE; /* per-client stats */
+ static boolean_t smbstat_opt_S = B_FALSE; /* per-share stats */
+ static char *smbstat_opt_clsh = NULL; /* -C or -S arg. */
static uint_t smbstat_interval = 0;
static long smbstat_nrcpus = 0;
static kstat_ctl_t *smbstat_ksc = NULL;
static kstat_t *smbstat_srv_ksp = NULL;
static kstat_t *smbstat_wrk_ksp = NULL;
+ static kstat_t *smbstat_clsh_ksp = NULL;
static struct winsize smbstat_ws;
static uint16_t smbstat_rows = 0;
static int smbstat_snapshot_idx = 0;
static smbstat_cpu_snapshot_t *smbstat_cpu_snapshots[SMBSTAT_SNAPSHOT_COUNT];
static smbstat_srv_snapshot_t smbstat_srv_snapshots[SMBSTAT_SNAPSHOT_COUNT];
static smbstat_wrk_snapshot_t smbstat_wrk_snapshots[SMBSTAT_SNAPSHOT_COUNT];
+ static smbstat_clsh_snapshot_t smbstat_clsh_snapshots[SMBSTAT_SNAPSHOT_COUNT];
static smbstat_srv_info_t smbstat_srv_info;
/*
* main
*/
*** 317,327 ****
gettext("%s: Trusted Extensions not supported.\n"),
argv[0]);
return (1);
}
! while ((c = getopt(argc, argv, "achnrtuz")) != EOF) {
switch (c) {
case 'a':
smbstat_opt_a = B_TRUE;
break;
case 'n':
--- 348,358 ----
gettext("%s: Trusted Extensions not supported.\n"),
argv[0]);
return (1);
}
! while ((c = getopt(argc, argv, "achnrtuzC:S:")) != EOF) {
switch (c) {
case 'a':
smbstat_opt_a = B_TRUE;
break;
case 'n':
*** 340,349 ****
--- 371,390 ----
smbstat_opt_t = B_TRUE;
break;
case 'z':
smbstat_opt_z = B_TRUE;
break;
+ case 'C': /* per-client stats. */
+ smbstat_opt_S = B_FALSE;
+ smbstat_opt_C = B_TRUE;
+ smbstat_opt_clsh = optarg;
+ break;
+ case 'S': /* per-share stats. */
+ smbstat_opt_C = B_FALSE;
+ smbstat_opt_S = B_TRUE;
+ smbstat_opt_clsh = optarg;
+ break;
case 'h':
smbstat_usage(stdout, 0);
default:
smbstat_usage(stderr, 1);
}
*** 350,360 ****
}
if (!smbstat_opt_u &&
!smbstat_opt_c &&
!smbstat_opt_r &&
! !smbstat_opt_t) {
/* Default options when none is specified. */
smbstat_opt_u = B_TRUE;
smbstat_opt_t = B_TRUE;
}
--- 391,403 ----
}
if (!smbstat_opt_u &&
!smbstat_opt_c &&
!smbstat_opt_r &&
! !smbstat_opt_t &&
! !smbstat_opt_C &&
! !smbstat_opt_S) {
/* Default options when none is specified. */
smbstat_opt_u = B_TRUE;
smbstat_opt_t = B_TRUE;
}
*** 367,376 ****
--- 410,420 ----
if ((argc - optind) > 1)
smbstat_usage(stderr, 1);
(void) atexit(smbstat_fini);
smbstat_init();
+ smbstat_req_order();
for (;;) {
smbstat_kstat_snapshot();
smbstat_kstat_process();
smbstat_kstat_print();
if (smbstat_interval == 0)
*** 393,403 ****
smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat"));
smbstat_cpu_init();
smbstat_srv_init();
smbstat_wrk_init();
! smbstat_req_order();
}
/*
* smbstat_fini
*
--- 437,447 ----
smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat"));
smbstat_cpu_init();
smbstat_srv_init();
smbstat_wrk_init();
! smbstat_clsh_init();
}
/*
* smbstat_fini
*
*** 404,413 ****
--- 448,458 ----
* Releases the resources smbstat_init() allocated.
*/
static void
smbstat_fini(void)
{
+ smbstat_clsh_fini();
smbstat_wrk_fini();
smbstat_srv_fini();
smbstat_cpu_fini();
(void) kstat_close(smbstat_ksc);
}
*** 421,430 ****
--- 466,476 ----
smbstat_kstat_snapshot(void)
{
smbstat_cpu_snapshot();
smbstat_srv_snapshot();
smbstat_wrk_snapshot();
+ smbstat_clsh_snapshot();
}
/*
* smbstat_kstat_process
*/
*** 432,441 ****
--- 478,488 ----
smbstat_kstat_process(void)
{
smbstat_cpu_process();
smbstat_srv_process();
smbstat_wrk_process();
+ smbstat_clsh_process();
}
/*
* smbstat_kstat_print
*
*** 447,456 ****
--- 494,504 ----
smbstat_termio_init();
smbstat_print_counters();
smbstat_print_throughput();
smbstat_print_utilization();
smbstat_print_requests();
+ smbstat_print_client_or_share();
(void) fflush(stdout);
}
/*
* smbstat_print_counters
*** 489,499 ****
{
if (!smbstat_opt_t)
return;
if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_c ||
! (smbstat_rows == 0) || (smbstat_rows >= smbstat_ws.ws_row)) {
(void) printf(SMBSRV_THROUGHPUT_BANNER);
smbstat_rows = 1;
}
(void) printf(SMBSRV_THROUGHPUT_FORMAT,
smbstat_zero(smbstat_srv_info.si_rbs),
--- 537,548 ----
{
if (!smbstat_opt_t)
return;
if (smbstat_opt_u || smbstat_opt_r || smbstat_opt_c ||
! smbstat_opt_C || smbstat_opt_S || (smbstat_rows == 0) ||
! (smbstat_rows >= smbstat_ws.ws_row)) {
(void) printf(SMBSRV_THROUGHPUT_BANNER);
smbstat_rows = 1;
}
(void) printf(SMBSRV_THROUGHPUT_FORMAT,
smbstat_zero(smbstat_srv_info.si_rbs),
*** 555,565 ****
return;
(void) printf(SMBSRV_REQUESTS_BANNER, " ");
prq = smbstat_srv_info.si_reqs1;
! for (i = 0; i < SMB_COM_NUM; i++) {
if (!smbstat_opt_a &&
strncmp(prq[i].ri_name, "Invalid", sizeof ("Invalid")) == 0)
continue;
if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
--- 604,614 ----
return;
(void) printf(SMBSRV_REQUESTS_BANNER, " ");
prq = smbstat_srv_info.si_reqs1;
! for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
if (!smbstat_opt_a &&
strncmp(prq[i].ri_name, "Invalid", sizeof ("Invalid")) == 0)
continue;
if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
*** 574,584 ****
prq[i].ri_stddev);
}
}
prq = smbstat_srv_info.si_reqs2;
! for (i = 0; i < SMB2__NCMDS; i++) {
if (!smbstat_opt_a && i == SMB2_INVALID_CMD)
continue;
if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
(void) printf(SMBSRV_REQUESTS_FORMAT,
--- 623,633 ----
prq[i].ri_stddev);
}
}
prq = smbstat_srv_info.si_reqs2;
! for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
if (!smbstat_opt_a && i == SMB2_INVALID_CMD)
continue;
if (!smbstat_opt_z || (prq[i].ri_pct != 0)) {
(void) printf(SMBSRV_REQUESTS_FORMAT,
*** 592,601 ****
--- 641,675 ----
prq[i].ri_stddev);
}
}
}
+ static void
+ smbstat_print_client_or_share(void)
+ {
+ smbstat_req_info_t *prq;
+ int idx;
+
+ if (smbstat_opt_clsh == NULL)
+ return;
+
+ (void) printf(SMBSRV_CLNT_SHARE_BANNER, " ");
+
+ prq = &smbstat_srv_info.si_clsh[0];
+
+ for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++, prq++) {
+ (void) printf(SMBSRV_CLNT_SHARE_FORMAT,
+ prq->ri_name,
+ smbstat_zero(prq->ri_rbs),
+ smbstat_zero(prq->ri_tbs),
+ smbstat_zero(prq->ri_rqs),
+ prq->ri_mean,
+ prq->ri_stddev);
+ }
+ }
+
+
/*
* smbstat_cpu_init
*/
static void
smbstat_cpu_init(void)
*** 790,806 ****
{
return (&smbstat_wrk_snapshots[smbstat_snapshot_idx]);
}
/*
* smbstat_srv_init
*/
static void
smbstat_srv_init(void)
{
smbstat_srv_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
! getzoneid(), SMBSRV_KSTAT_STATISTICS);
if (smbstat_srv_ksp == NULL)
smbstat_fail(1, gettext("cannot retrieve smbsrv kstat\n"));
}
/*
--- 864,1003 ----
{
return (&smbstat_wrk_snapshots[smbstat_snapshot_idx]);
}
/*
+ * smbstat_clsh_init
+ *
+ * Lookup the kstat for the client or share specified.
+ * The names for these look like:
+ * session (a.k.a. client)
+ * cl/$IPADDR and instance ss->s_kid
+ * share
+ * sh/sharename (always instance 0)
+ *
+ * These will look like: smbsrv:0:sh/myshare
+ * or smbsrv:N:cl/10.10.0.2
+ */
+ static void
+ smbstat_clsh_init(void)
+ {
+ static const char *kr_names[] = SMBSRV_CLSH__NAMES;
+ char ks_name[KSTAT_STRLEN];
+ char *prefix = "";
+ smbstat_req_info_t *info;
+ int instance = -1;
+ int i;
+
+ if (smbstat_opt_clsh == NULL)
+ return;
+
+ /*
+ * Currently we don't take an instance so this will return data
+ * from the first or the only client from the IP address specified.
+ */
+ if (smbstat_opt_C)
+ prefix = "cl";
+ if (smbstat_opt_S)
+ prefix = "sh";
+ (void) snprintf(ks_name, sizeof (ks_name),
+ "%s/%s", prefix, smbstat_opt_clsh);
+
+ smbstat_clsh_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
+ instance, ks_name);
+ if (smbstat_clsh_ksp == NULL) {
+ smbstat_fail(1, gettext("cannot retrieve smbsrv %s kstat\n"),
+ ks_name);
+ }
+
+ info = smbstat_srv_info.si_clsh;
+ for (i = 0; i < SMBSRV_CLSH__NREQ; i++) {
+ (void) strlcpy(info[i].ri_name, kr_names[i],
+ sizeof (info[i].ri_name));
+ }
+ }
+
+ static void
+ smbstat_clsh_fini(void)
+ {
+ smbstat_clsh_ksp = NULL;
+ }
+
+ /*
+ * smbstat_clsh_snapshot
+ */
+ static void
+ smbstat_clsh_snapshot(void)
+ {
+ smbstat_clsh_snapshot_t *curr;
+
+ if (smbstat_clsh_ksp == NULL)
+ return;
+
+ curr = smbstat_clsh_current_snapshot();
+
+ if ((kstat_read(smbstat_ksc, smbstat_clsh_ksp, NULL) == -1) ||
+ (smbstat_clsh_ksp->ks_data_size != sizeof (curr->cs_data)))
+ smbstat_fail(1, gettext("kstat_read('%s') failed"),
+ smbstat_clsh_ksp->ks_name);
+
+ curr->cs_snaptime = smbstat_clsh_ksp->ks_snaptime;
+
+ bcopy(smbstat_clsh_ksp->ks_data, &curr->cs_data,
+ sizeof (curr->cs_data));
+ }
+
+ /*
+ * smbstat_clsh_process
+ */
+ static void
+ smbstat_clsh_process(void)
+ {
+ smbstat_clsh_snapshot_t *curr, *prev;
+ boolean_t firstcall;
+ int idx;
+
+ curr = smbstat_clsh_current_snapshot();
+ prev = smbstat_clsh_previous_snapshot();
+ firstcall = (prev->cs_snaptime == 0);
+
+
+ for (idx = 0; idx < SMBSRV_CLSH__NREQ; idx++) {
+ smbstat_srv_process_one_req(
+ &smbstat_srv_info.si_clsh[idx],
+ &curr->cs_data.ks_clsh[idx],
+ &prev->cs_data.ks_clsh[idx],
+ firstcall);
+ }
+ }
+
+ /*
+ * smbstat_clsh_current_snapshot
+ */
+ static smbstat_clsh_snapshot_t *
+ smbstat_clsh_current_snapshot(void)
+ {
+ return (&smbstat_clsh_snapshots[smbstat_snapshot_idx]);
+ }
+
+ static smbstat_clsh_snapshot_t *
+ smbstat_clsh_previous_snapshot(void)
+ {
+ int idx;
+
+ idx = (smbstat_snapshot_idx - 1) & SMBSTAT_SNAPSHOT_MASK;
+ return (&smbstat_clsh_snapshots[idx]);
+ }
+
+ /*
* smbstat_srv_init
*/
static void
smbstat_srv_init(void)
{
smbstat_srv_ksp = kstat_lookup(smbstat_ksc, SMBSRV_KSTAT_MODULE,
! -1, SMBSRV_KSTAT_STATISTICS);
if (smbstat_srv_ksp == NULL)
smbstat_fail(1, gettext("cannot retrieve smbsrv kstat\n"));
}
/*
*** 1030,1049 ****
smb_kstat_req_t *curr_req;
smb_kstat_req_t *prev_req;
int i, idx;
boolean_t firstcall = (prev->ss_snaptime == 0);
! for (i = 0; i < SMB_COM_NUM; i++) {
info = &smbstat_srv_info.si_reqs1[i];
idx = info[i].ri_opcode & 0xFF;
curr_req = &curr->ss_data.ks_reqs1[idx];
prev_req = &prev->ss_data.ks_reqs1[idx];
smbstat_srv_process_one_req(
info, curr_req, prev_req, firstcall);
}
! for (i = 0; i < SMB2__NCMDS; i++) {
info = &smbstat_srv_info.si_reqs2[i];
curr_req = &curr->ss_data.ks_reqs2[i];
prev_req = &prev->ss_data.ks_reqs2[i];
smbstat_srv_process_one_req(
info, curr_req, prev_req, firstcall);
--- 1227,1246 ----
smb_kstat_req_t *curr_req;
smb_kstat_req_t *prev_req;
int i, idx;
boolean_t firstcall = (prev->ss_snaptime == 0);
! for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
info = &smbstat_srv_info.si_reqs1[i];
idx = info[i].ri_opcode & 0xFF;
curr_req = &curr->ss_data.ks_reqs1[idx];
prev_req = &prev->ss_data.ks_reqs1[idx];
smbstat_srv_process_one_req(
info, curr_req, prev_req, firstcall);
}
! for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
info = &smbstat_srv_info.si_reqs2[i];
curr_req = &curr->ss_data.ks_reqs2[i];
prev_req = &prev->ss_data.ks_reqs2[i];
smbstat_srv_process_one_req(
info, curr_req, prev_req, firstcall);
*** 1097,1107 ****
}
info->ri_stddev /= NANOSEC;
info->ri_mean /= NANOSEC;
}
-
/*
* smbstat_srv_current_snapshot
*
* Returns the current snapshot.
*/
--- 1294,1303 ----
*** 1276,1303 ****
smbstat_srv_snapshot();
ss = smbstat_srv_current_snapshot();
reqs = ss->ss_data.ks_reqs1;
info = smbstat_srv_info.si_reqs1;
! for (i = 0; i < SMB_COM_NUM; i++) {
(void) strlcpy(info[i].ri_name, reqs[i].kr_name,
sizeof (reqs[i].kr_name));
info[i].ri_opcode = i;
}
if (smbstat_opt_n)
! qsort(info, SMB_COM_NUM, sizeof (smbstat_req_info_t),
smbstat_req_cmp_name);
reqs = ss->ss_data.ks_reqs2;
info = smbstat_srv_info.si_reqs2;
! for (i = 0; i < SMB2__NCMDS; i++) {
(void) strlcpy(info[i].ri_name, reqs[i].kr_name,
sizeof (reqs[i].kr_name));
info[i].ri_opcode = i;
}
if (smbstat_opt_n)
! qsort(info, SMB2__NCMDS, sizeof (smbstat_req_info_t),
smbstat_req_cmp_name);
}
/*
* Return the number of ticks delta between two hrtime_t
--- 1472,1499 ----
smbstat_srv_snapshot();
ss = smbstat_srv_current_snapshot();
reqs = ss->ss_data.ks_reqs1;
info = smbstat_srv_info.si_reqs1;
! for (i = 0; i < SMBSRV_KS_NREQS1; i++) {
(void) strlcpy(info[i].ri_name, reqs[i].kr_name,
sizeof (reqs[i].kr_name));
info[i].ri_opcode = i;
}
if (smbstat_opt_n)
! qsort(info, SMBSRV_KS_NREQS1, sizeof (smbstat_req_info_t),
smbstat_req_cmp_name);
reqs = ss->ss_data.ks_reqs2;
info = smbstat_srv_info.si_reqs2;
! for (i = 0; i < SMBSRV_KS_NREQS2; i++) {
(void) strlcpy(info[i].ri_name, reqs[i].kr_name,
sizeof (reqs[i].kr_name));
info[i].ri_opcode = i;
}
if (smbstat_opt_n)
! qsort(info, SMBSRV_KS_NREQS2, sizeof (smbstat_req_info_t),
smbstat_req_cmp_name);
}
/*
* Return the number of ticks delta between two hrtime_t