xref: /onnv-gate/usr/src/cmd/smbsrv/smbstat/smbstat.c (revision 5331:3047ad28a67b)
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