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 /* 23*6537f381Sas * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24da6c28aaSamw * Use is subject to license terms. 25da6c28aaSamw */ 26da6c28aaSamw 27da6c28aaSamw #pragma ident "%Z%%M% %I% %E% SMI" 28da6c28aaSamw 29da6c28aaSamw /* 30da6c28aaSamw * smbstat: Server Message Block File System statistics 31da6c28aaSamw */ 32da6c28aaSamw #include <stdio.h> 33da6c28aaSamw #include <stdlib.h> 34da6c28aaSamw #include <kstat.h> 35da6c28aaSamw #include <stdarg.h> 36da6c28aaSamw #include <errno.h> 37da6c28aaSamw #include <inttypes.h> 38da6c28aaSamw #include <strings.h> 39da6c28aaSamw #include <utility.h> 40da6c28aaSamw #include <libintl.h> 41da6c28aaSamw #include <zone.h> 42*6537f381Sas #include <smbsrv/smb_kstat.h> 43da6c28aaSamw 44*6537f381Sas static kstat_ctl_t *kc; /* libkstat cookie */ 45*6537f381Sas static kstat_t *smb_server; 46*6537f381Sas static kstat_t *smb_cmds; 47da6c28aaSamw 48da6c28aaSamw static int get_smbinfo_stat(void); 49da6c28aaSamw static int get_smbdispatch_stat(void); 50*6537f381Sas static void smbstat_init(void); 51*6537f381Sas static void smbstat_fini(void); 52*6537f381Sas static void smbstat_smb_server_print(); 53*6537f381Sas static void smbstat_smb_cmds_print(); 54da6c28aaSamw static void smbstat_print(const char *, kstat_t *, int); 55da6c28aaSamw static int smbstat_width(kstat_t *, int); 56da6c28aaSamw static void smbstat_fail(int, char *, ...); 57da6c28aaSamw static kid_t smbstat_kstat_read(kstat_ctl_t *, kstat_t *, void *); 58da6c28aaSamw static void smbstat_usage(void); 59da6c28aaSamw 60da6c28aaSamw #define MAX_COLUMNS 80 61da6c28aaSamw 62da6c28aaSamw int 63da6c28aaSamw main(int argc, char *argv[]) 64da6c28aaSamw { 65da6c28aaSamw int c; 66*6537f381Sas int iflag = 0; /* smb_server stats */ 67*6537f381Sas int dflag = 0; /* smb_cmds_all stats */ 68da6c28aaSamw 69da6c28aaSamw if (getzoneid() != GLOBAL_ZONEID) { 70da6c28aaSamw (void) fprintf(stderr, 71da6c28aaSamw gettext("%s: Cannot execute in non-global zone.\n"), 72da6c28aaSamw argv[0]); 73da6c28aaSamw return (0); 74da6c28aaSamw } 75da6c28aaSamw 76da6c28aaSamw if (is_system_labeled()) { 77da6c28aaSamw (void) fprintf(stderr, 78da6c28aaSamw gettext("%s: Trusted Extensions not supported.\n"), 79da6c28aaSamw argv[0]); 80da6c28aaSamw return (0); 81da6c28aaSamw } 82da6c28aaSamw 83da6c28aaSamw while ((c = getopt(argc, argv, "id")) != EOF) { 84da6c28aaSamw switch (c) { 85da6c28aaSamw case 'i': 86da6c28aaSamw iflag++; 87da6c28aaSamw break; 88da6c28aaSamw case 'd': 89da6c28aaSamw dflag++; 90da6c28aaSamw break; 91da6c28aaSamw case '?': 92da6c28aaSamw default: 93da6c28aaSamw smbstat_usage(); 94da6c28aaSamw } 95da6c28aaSamw } 96da6c28aaSamw 97da6c28aaSamw if ((argc - optind) > 0) { 98da6c28aaSamw smbstat_usage(); 99da6c28aaSamw } 100da6c28aaSamw 101*6537f381Sas smbstat_init(); 102da6c28aaSamw 103da6c28aaSamw if (iflag) { 104*6537f381Sas smbstat_smb_server_print(); 105da6c28aaSamw } else if (dflag) { 106*6537f381Sas smbstat_smb_cmds_print(); 107da6c28aaSamw } else { 108*6537f381Sas smbstat_smb_server_print(); 109*6537f381Sas smbstat_smb_cmds_print(); 110da6c28aaSamw } 111da6c28aaSamw 112*6537f381Sas smbstat_fini(); 113da6c28aaSamw return (0); 114da6c28aaSamw } 115da6c28aaSamw 116da6c28aaSamw 117da6c28aaSamw static int 118da6c28aaSamw get_smbinfo_stat(void) 119da6c28aaSamw { 120*6537f381Sas (void) smbstat_kstat_read(kc, smb_server, NULL); 121*6537f381Sas return (smbstat_width(smb_server, 0)); 122da6c28aaSamw } 123da6c28aaSamw 124da6c28aaSamw static int 125da6c28aaSamw get_smbdispatch_stat(void) 126da6c28aaSamw { 127*6537f381Sas (void) smbstat_kstat_read(kc, smb_cmds, NULL); 128*6537f381Sas return (smbstat_width(smb_cmds, 0)); 129da6c28aaSamw } 130da6c28aaSamw 131da6c28aaSamw static void 132*6537f381Sas smbstat_smb_server_print() 133da6c28aaSamw { 134*6537f381Sas int field_width; 135*6537f381Sas int i, j, nreq, ncolumns; 136*6537f381Sas char fixlen[128]; 137*6537f381Sas kstat_named_t *knp; 138da6c28aaSamw 139da6c28aaSamw field_width = get_smbinfo_stat(); 140da6c28aaSamw if (field_width == 0) 141da6c28aaSamw return; 142da6c28aaSamw 143*6537f381Sas (void) printf("%s\n", "\nSMB Info:\n"); 144*6537f381Sas ncolumns = (MAX_COLUMNS -1)/field_width; 145*6537f381Sas 146*6537f381Sas knp = KSTAT_NAMED_PTR(smb_server); 147*6537f381Sas nreq = smb_server->ks_ndata; 148*6537f381Sas 149*6537f381Sas for (i = 0; i < nreq; i += ncolumns) { 150*6537f381Sas /* prints out the titles of the columns */ 151*6537f381Sas for (j = i; j < MIN(i + ncolumns, nreq); j++) { 152*6537f381Sas (void) printf("%-*s", field_width, knp[j].name); 153*6537f381Sas } 154*6537f381Sas (void) printf("\n"); 155*6537f381Sas /* prints out the stat numbers */ 156*6537f381Sas for (j = i; j < MIN(i + ncolumns, nreq); j++) { 157*6537f381Sas (void) sprintf(fixlen, "%" PRIu32 " ", 158*6537f381Sas knp[j].value.ui32); 159*6537f381Sas (void) printf("%-*s", field_width, fixlen); 160*6537f381Sas } 161*6537f381Sas (void) printf("\n"); 162*6537f381Sas } 163da6c28aaSamw } 164da6c28aaSamw 165da6c28aaSamw static void 166*6537f381Sas smbstat_smb_cmds_print() 167da6c28aaSamw { 168da6c28aaSamw int field_width; 169da6c28aaSamw 170da6c28aaSamw field_width = get_smbdispatch_stat(); 171da6c28aaSamw if (field_width == 0) 172da6c28aaSamw return; 173da6c28aaSamw 174da6c28aaSamw smbstat_print(gettext("\nAll dispatched SMB requests statistics:\n"), 175*6537f381Sas smb_cmds, field_width); 176da6c28aaSamw } 177da6c28aaSamw 178da6c28aaSamw static void 179*6537f381Sas smbstat_init(void) 180da6c28aaSamw { 181*6537f381Sas char smbsrv_name[KSTAT_STRLEN]; 182*6537f381Sas 183*6537f381Sas (void) snprintf(smbsrv_name, sizeof (smbsrv_name), "%s%d", 184*6537f381Sas SMBSRV_KSTAT_NAME, getzoneid()); 185*6537f381Sas 186da6c28aaSamw if ((kc = kstat_open()) == NULL) 187da6c28aaSamw smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat")); 188da6c28aaSamw 189*6537f381Sas smb_server = kstat_lookup(kc, SMBSRV_KSTAT_MODULE, 0, smbsrv_name); 190*6537f381Sas smb_cmds = kstat_lookup(kc, SMBSRV_KSTAT_MODULE, 0, 191*6537f381Sas SMBSRV_KSTAT_NAME_CMDS); 192da6c28aaSamw 193*6537f381Sas if ((smb_server == NULL) || (smb_cmds == NULL)) 194da6c28aaSamw smbstat_fail(0, gettext("kstat lookups failed for smb. " 195da6c28aaSamw "Your kernel module may not be loaded\n")); 196da6c28aaSamw } 197da6c28aaSamw 198*6537f381Sas static void 199*6537f381Sas smbstat_fini(void) 200*6537f381Sas { 201*6537f381Sas (void) kstat_close(kc); 202*6537f381Sas } 203*6537f381Sas 204da6c28aaSamw static int 205da6c28aaSamw smbstat_width(kstat_t *req, int field_width) 206da6c28aaSamw { 207da6c28aaSamw int i, nreq, len; 208da6c28aaSamw char fixlen[128]; 209da6c28aaSamw kstat_named_t *knp; 210da6c28aaSamw 211da6c28aaSamw knp = KSTAT_NAMED_PTR(req); 212da6c28aaSamw nreq = req->ks_ndata; 213da6c28aaSamw 214da6c28aaSamw for (i = 0; i < nreq; i++) { 215da6c28aaSamw len = strlen(knp[i].name) + 1; 216da6c28aaSamw if (field_width < len) 217da6c28aaSamw field_width = len; 218da6c28aaSamw (void) sprintf(fixlen, "%" PRIu64, knp[i].value.ui64); 219da6c28aaSamw len = strlen(fixlen) + 1; 220da6c28aaSamw if (field_width < len) 221da6c28aaSamw field_width = len; 222da6c28aaSamw } 223da6c28aaSamw return (field_width); 224da6c28aaSamw } 225da6c28aaSamw 226da6c28aaSamw static void 227da6c28aaSamw smbstat_print(const char *title_string, kstat_t *req, int field_width) 228da6c28aaSamw { 229da6c28aaSamw int i, j, nreq, ncolumns; 230da6c28aaSamw char fixlen[128]; 231da6c28aaSamw kstat_named_t *knp; 232da6c28aaSamw 233da6c28aaSamw if (req == NULL) 234da6c28aaSamw return; 235da6c28aaSamw 236da6c28aaSamw if (field_width == 0) 237da6c28aaSamw return; 238da6c28aaSamw 239da6c28aaSamw (void) printf("%s\n", title_string); 240da6c28aaSamw ncolumns = (MAX_COLUMNS -1)/field_width; 241da6c28aaSamw 242da6c28aaSamw knp = KSTAT_NAMED_PTR(req); 243da6c28aaSamw nreq = req->ks_ndata; 244da6c28aaSamw 245da6c28aaSamw for (i = 0; i < nreq; i += ncolumns) { 246da6c28aaSamw /* prints out the titles of the columns */ 247da6c28aaSamw for (j = i; j < MIN(i + ncolumns, nreq); j++) { 248da6c28aaSamw (void) printf("%-*s", field_width, knp[j].name); 249da6c28aaSamw } 250da6c28aaSamw (void) printf("\n"); 251da6c28aaSamw /* prints out the stat numbers */ 252da6c28aaSamw for (j = i; j < MIN(i + ncolumns, nreq); j++) { 253da6c28aaSamw (void) sprintf(fixlen, "%" PRIu64 " ", 254da6c28aaSamw knp[j].value.ui64); 255da6c28aaSamw (void) printf("%-*s", field_width, fixlen); 256da6c28aaSamw } 257da6c28aaSamw (void) printf("\n"); 258da6c28aaSamw 259da6c28aaSamw } 260da6c28aaSamw } 261da6c28aaSamw 262da6c28aaSamw static void 263da6c28aaSamw smbstat_usage(void) 264da6c28aaSamw { 265da6c28aaSamw (void) fprintf(stderr, gettext("Usage: smbstat [-id]\n")); 266da6c28aaSamw exit(1); 267da6c28aaSamw } 268da6c28aaSamw 269da6c28aaSamw static void 270da6c28aaSamw smbstat_fail(int do_perror, char *message, ...) 271da6c28aaSamw { 272da6c28aaSamw va_list args; 273da6c28aaSamw 274da6c28aaSamw va_start(args, message); 275da6c28aaSamw (void) fprintf(stderr, gettext("smbstat: ")); 276da6c28aaSamw /* LINTED E_SEC_PRINTF_VAR_FMT */ 277da6c28aaSamw (void) vfprintf(stderr, message, args); 278da6c28aaSamw va_end(args); 279da6c28aaSamw if (do_perror) 280da6c28aaSamw (void) fprintf(stderr, ": %s", strerror(errno)); 281da6c28aaSamw (void) fprintf(stderr, "\n"); 282da6c28aaSamw exit(1); 283da6c28aaSamw } 284da6c28aaSamw 285da6c28aaSamw static kid_t 286da6c28aaSamw smbstat_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data) 287da6c28aaSamw { 288da6c28aaSamw kid_t kstat_chain_id = kstat_read(kc, ksp, data); 289da6c28aaSamw 290da6c28aaSamw if (kstat_chain_id == -1) 291da6c28aaSamw smbstat_fail(1, gettext("kstat_read('%s') failed"), 292da6c28aaSamw ksp->ks_name); 293da6c28aaSamw return (kstat_chain_id); 294da6c28aaSamw } 295da6c28aaSamw 296da6c28aaSamw /* 297da6c28aaSamw * Enable libumem debugging by default on DEBUG builds. 298da6c28aaSamw */ 299da6c28aaSamw #ifdef DEBUG 300da6c28aaSamw const char * 301da6c28aaSamw _umem_debug_init(void) 302da6c28aaSamw { 303da6c28aaSamw return ("default,verbose"); /* $UMEM_DEBUG setting */ 304da6c28aaSamw } 305da6c28aaSamw 306da6c28aaSamw const char * 307da6c28aaSamw _umem_logging_init(void) 308da6c28aaSamw { 309da6c28aaSamw return ("fail,contents"); /* $UMEM_LOGGING setting */ 310da6c28aaSamw } 311da6c28aaSamw #endif 312