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