1*5331Samw /* 2*5331Samw * CDDL HEADER START 3*5331Samw * 4*5331Samw * The contents of this file are subject to the terms of the 5*5331Samw * Common Development and Distribution License (the "License"). 6*5331Samw * You may not use this file except in compliance with the License. 7*5331Samw * 8*5331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5331Samw * or http://www.opensolaris.org/os/licensing. 10*5331Samw * See the License for the specific language governing permissions 11*5331Samw * and limitations under the License. 12*5331Samw * 13*5331Samw * When distributing Covered Code, include this CDDL HEADER in each 14*5331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5331Samw * If applicable, add the following below this CDDL HEADER, with the 16*5331Samw * fields enclosed by brackets "[]" replaced with your own identifying 17*5331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 18*5331Samw * 19*5331Samw * CDDL HEADER END 20*5331Samw */ 21*5331Samw 22*5331Samw /* 23*5331Samw * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 24*5331Samw * Use is subject to license terms. 25*5331Samw */ 26*5331Samw 27*5331Samw #pragma ident "%Z%%M% %I% %E% SMI" 28*5331Samw 29*5331Samw /* 30*5331Samw * smbstat: Server Message Block File System statistics 31*5331Samw */ 32*5331Samw #include <stdio.h> 33*5331Samw #include <stdlib.h> 34*5331Samw #include <kstat.h> 35*5331Samw #include <stdarg.h> 36*5331Samw #include <errno.h> 37*5331Samw #include <inttypes.h> 38*5331Samw #include <strings.h> 39*5331Samw #include <utility.h> 40*5331Samw #include <libintl.h> 41*5331Samw #include <zone.h> 42*5331Samw 43*5331Samw static kstat_ctl_t *kc; /* libkstat cookie */ 44*5331Samw static kstat_t *smb_info; 45*5331Samw static kstat_t *smb_dispatch; 46*5331Samw static kstat_t *ksmb_kstat; 47*5331Samw 48*5331Samw static int get_smbinfo_stat(void); 49*5331Samw static int get_smbdispatch_stat(void); 50*5331Samw static void smbstat_setup(void); 51*5331Samw static void smbstat_smb_info_print(); 52*5331Samw static void smbstat_smb_dispatch_print(); 53*5331Samw static void smbstat_print(const char *, kstat_t *, int); 54*5331Samw static int smbstat_width(kstat_t *, int); 55*5331Samw static void smbstat_fail(int, char *, ...); 56*5331Samw static kid_t smbstat_kstat_read(kstat_ctl_t *, kstat_t *, void *); 57*5331Samw static void smbstat_usage(void); 58*5331Samw 59*5331Samw #define MAX_COLUMNS 80 60*5331Samw 61*5331Samw int 62*5331Samw main(int argc, char *argv[]) 63*5331Samw { 64*5331Samw int c; 65*5331Samw int iflag = 0; /* smb_info stats */ 66*5331Samw int dflag = 0; /* smb_dispatch_all stats */ 67*5331Samw 68*5331Samw if (getzoneid() != GLOBAL_ZONEID) { 69*5331Samw (void) fprintf(stderr, 70*5331Samw gettext("%s: Cannot execute in non-global zone.\n"), 71*5331Samw argv[0]); 72*5331Samw return (0); 73*5331Samw } 74*5331Samw 75*5331Samw if (is_system_labeled()) { 76*5331Samw (void) fprintf(stderr, 77*5331Samw gettext("%s: Trusted Extensions not supported.\n"), 78*5331Samw argv[0]); 79*5331Samw return (0); 80*5331Samw } 81*5331Samw 82*5331Samw while ((c = getopt(argc, argv, "id")) != EOF) { 83*5331Samw switch (c) { 84*5331Samw case 'i': 85*5331Samw iflag++; 86*5331Samw break; 87*5331Samw case 'd': 88*5331Samw dflag++; 89*5331Samw break; 90*5331Samw case '?': 91*5331Samw default: 92*5331Samw smbstat_usage(); 93*5331Samw } 94*5331Samw } 95*5331Samw 96*5331Samw if ((argc - optind) > 0) { 97*5331Samw smbstat_usage(); 98*5331Samw } 99*5331Samw 100*5331Samw smbstat_setup(); 101*5331Samw 102*5331Samw if (iflag) { 103*5331Samw smbstat_smb_info_print(); 104*5331Samw } else if (dflag) { 105*5331Samw smbstat_smb_dispatch_print(); 106*5331Samw } else { 107*5331Samw smbstat_smb_info_print(); 108*5331Samw smbstat_smb_dispatch_print(); 109*5331Samw } 110*5331Samw 111*5331Samw (void) kstat_close(kc); 112*5331Samw free(ksmb_kstat); 113*5331Samw return (0); 114*5331Samw } 115*5331Samw 116*5331Samw 117*5331Samw static int 118*5331Samw get_smbinfo_stat(void) 119*5331Samw { 120*5331Samw (void) smbstat_kstat_read(kc, smb_info, NULL); 121*5331Samw return (smbstat_width(smb_info, 0)); 122*5331Samw } 123*5331Samw 124*5331Samw static int 125*5331Samw get_smbdispatch_stat(void) 126*5331Samw { 127*5331Samw (void) smbstat_kstat_read(kc, smb_dispatch, NULL); 128*5331Samw return (smbstat_width(smb_dispatch, 0)); 129*5331Samw } 130*5331Samw 131*5331Samw static void 132*5331Samw smbstat_smb_info_print() 133*5331Samw { 134*5331Samw int field_width; 135*5331Samw 136*5331Samw field_width = get_smbinfo_stat(); 137*5331Samw if (field_width == 0) 138*5331Samw return; 139*5331Samw 140*5331Samw smbstat_print(gettext("\nSMB Info:\n"), smb_info, field_width); 141*5331Samw } 142*5331Samw 143*5331Samw static void 144*5331Samw smbstat_smb_dispatch_print() 145*5331Samw { 146*5331Samw int field_width; 147*5331Samw 148*5331Samw field_width = get_smbdispatch_stat(); 149*5331Samw if (field_width == 0) 150*5331Samw return; 151*5331Samw 152*5331Samw smbstat_print(gettext("\nAll dispatched SMB requests statistics:\n"), 153*5331Samw smb_dispatch, field_width); 154*5331Samw } 155*5331Samw 156*5331Samw static void 157*5331Samw smbstat_setup(void) 158*5331Samw { 159*5331Samw if ((kc = kstat_open()) == NULL) 160*5331Samw smbstat_fail(1, gettext("kstat_open(): can't open /dev/kstat")); 161*5331Samw 162*5331Samw if ((ksmb_kstat = malloc(sizeof (kstat_t))) == NULL) { 163*5331Samw (void) kstat_close(kc); 164*5331Samw smbstat_fail(1, gettext("Out of memory")); 165*5331Samw } 166*5331Samw 167*5331Samw smb_info = kstat_lookup(kc, "smb", 0, "smb_info"); 168*5331Samw smb_dispatch = kstat_lookup(kc, "smb", 0, "smb_dispatch_all"); 169*5331Samw if ((smb_info == NULL) || (smb_dispatch == NULL)) 170*5331Samw smbstat_fail(0, gettext("kstat lookups failed for smb. " 171*5331Samw "Your kernel module may not be loaded\n")); 172*5331Samw } 173*5331Samw 174*5331Samw static int 175*5331Samw smbstat_width(kstat_t *req, int field_width) 176*5331Samw { 177*5331Samw int i, nreq, len; 178*5331Samw char fixlen[128]; 179*5331Samw kstat_named_t *knp; 180*5331Samw 181*5331Samw knp = KSTAT_NAMED_PTR(req); 182*5331Samw nreq = req->ks_ndata; 183*5331Samw 184*5331Samw for (i = 0; i < nreq; i++) { 185*5331Samw len = strlen(knp[i].name) + 1; 186*5331Samw if (field_width < len) 187*5331Samw field_width = len; 188*5331Samw (void) sprintf(fixlen, "%" PRIu64, knp[i].value.ui64); 189*5331Samw len = strlen(fixlen) + 1; 190*5331Samw if (field_width < len) 191*5331Samw field_width = len; 192*5331Samw } 193*5331Samw return (field_width); 194*5331Samw } 195*5331Samw 196*5331Samw static void 197*5331Samw smbstat_print(const char *title_string, kstat_t *req, int field_width) 198*5331Samw { 199*5331Samw int i, j, nreq, ncolumns; 200*5331Samw char fixlen[128]; 201*5331Samw kstat_named_t *knp; 202*5331Samw 203*5331Samw if (req == NULL) 204*5331Samw return; 205*5331Samw 206*5331Samw if (field_width == 0) 207*5331Samw return; 208*5331Samw 209*5331Samw (void) printf("%s\n", title_string); 210*5331Samw ncolumns = (MAX_COLUMNS -1)/field_width; 211*5331Samw 212*5331Samw knp = KSTAT_NAMED_PTR(req); 213*5331Samw nreq = req->ks_ndata; 214*5331Samw 215*5331Samw for (i = 0; i < nreq; i += ncolumns) { 216*5331Samw /* prints out the titles of the columns */ 217*5331Samw for (j = i; j < MIN(i + ncolumns, nreq); j++) { 218*5331Samw (void) printf("%-*s", field_width, knp[j].name); 219*5331Samw } 220*5331Samw (void) printf("\n"); 221*5331Samw /* prints out the stat numbers */ 222*5331Samw for (j = i; j < MIN(i + ncolumns, nreq); j++) { 223*5331Samw (void) sprintf(fixlen, "%" PRIu64 " ", 224*5331Samw knp[j].value.ui64); 225*5331Samw (void) printf("%-*s", field_width, fixlen); 226*5331Samw } 227*5331Samw (void) printf("\n"); 228*5331Samw 229*5331Samw } 230*5331Samw } 231*5331Samw 232*5331Samw static void 233*5331Samw smbstat_usage(void) 234*5331Samw { 235*5331Samw (void) fprintf(stderr, gettext("Usage: smbstat [-id]\n")); 236*5331Samw exit(1); 237*5331Samw } 238*5331Samw 239*5331Samw static void 240*5331Samw smbstat_fail(int do_perror, char *message, ...) 241*5331Samw { 242*5331Samw va_list args; 243*5331Samw 244*5331Samw va_start(args, message); 245*5331Samw (void) fprintf(stderr, gettext("smbstat: ")); 246*5331Samw /* LINTED E_SEC_PRINTF_VAR_FMT */ 247*5331Samw (void) vfprintf(stderr, message, args); 248*5331Samw va_end(args); 249*5331Samw if (do_perror) 250*5331Samw (void) fprintf(stderr, ": %s", strerror(errno)); 251*5331Samw (void) fprintf(stderr, "\n"); 252*5331Samw exit(1); 253*5331Samw } 254*5331Samw 255*5331Samw static kid_t 256*5331Samw smbstat_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data) 257*5331Samw { 258*5331Samw kid_t kstat_chain_id = kstat_read(kc, ksp, data); 259*5331Samw 260*5331Samw if (kstat_chain_id == -1) 261*5331Samw smbstat_fail(1, gettext("kstat_read('%s') failed"), 262*5331Samw ksp->ks_name); 263*5331Samw return (kstat_chain_id); 264*5331Samw } 265*5331Samw 266*5331Samw /* 267*5331Samw * Enable libumem debugging by default on DEBUG builds. 268*5331Samw */ 269*5331Samw #ifdef DEBUG 270*5331Samw /* LINTED - external libumem symbol */ 271*5331Samw const char * 272*5331Samw _umem_debug_init(void) 273*5331Samw { 274*5331Samw return ("default,verbose"); /* $UMEM_DEBUG setting */ 275*5331Samw } 276*5331Samw 277*5331Samw /* LINTED - external libumem symbol */ 278*5331Samw const char * 279*5331Samw _umem_logging_init(void) 280*5331Samw { 281*5331Samw return ("fail,contents"); /* $UMEM_LOGGING setting */ 282*5331Samw } 283*5331Samw #endif 284