xref: /titanic_41/usr/src/uts/common/fs/nfs/nfs_stats.c (revision d58fda4376e4bf67072ce2e69f6f47036f9dbb68)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 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 #include <sys/types.h>
30 #include <sys/kstat.h>
31 #include <sys/zone.h>
32 #include <sys/kmem.h>
33 #include <sys/systm.h>
34 
35 #include <nfs/nfs.h>
36 #include <nfs/nfs4_kprot.h>
37 
38 /*
39  * Key to retrieve per-zone data corresponding to NFS kstats consumed by
40  * nfsstat(1m).
41  */
42 zone_key_t nfsstat_zone_key;
43 
44 /*
45  * Convenience routine to create a named kstat associated with zoneid, named
46  * module:0:name:"misc", using the provided template to initialize the names
47  * and values of the stats.
48  */
49 static kstat_named_t *
50 nfsstat_zone_init_common(zoneid_t zoneid, const char *module, int vers,
51 			    const char *name, const kstat_named_t *template,
52 			    size_t template_size)
53 {
54 	kstat_t *ksp;
55 	kstat_named_t *ks_data;
56 
57 	ks_data = kmem_alloc(template_size, KM_SLEEP);
58 	bcopy(template, ks_data, template_size);
59 	if ((ksp = kstat_create_zone((char *)module, vers, (char *)name, "misc",
60 	    KSTAT_TYPE_NAMED, template_size / sizeof (kstat_named_t),
61 	    KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE, zoneid)) != NULL) {
62 		ksp->ks_data = ks_data;
63 		kstat_install(ksp);
64 	}
65 	return (ks_data);
66 }
67 
68 /*
69  * Convenience routine to remove a kstat in specified zone with name
70  * module:0:name.
71  */
72 static void
73 nfsstat_zone_fini_common(zoneid_t zoneid, const char *module, int vers,
74 			    const char *name)
75 {
76 	kstat_delete_byname_zone((char *)module, vers, (char *)name, zoneid);
77 }
78 
79 /*
80  * Server statistics.  These are defined here, rather than in the server
81  * code, so that they can be referenced before the nfssrv kmod is loaded.
82  *
83  * The "calls" counter is a Contract Private interface covered by
84  * PSARC/2001/357.  Please contact contract-2001-357-01@eng.sun.com before
85  * making any changes.
86  */
87 
88 static const kstat_named_t svstat_tmpl[] = {
89 	{ "calls",	KSTAT_DATA_UINT64 },
90 	{ "badcalls",	KSTAT_DATA_UINT64 },
91 };
92 
93 /* Points to the global zone server kstat data for all nfs versions */
94 kstat_named_t *global_svstat_ptr[NFS_VERSMAX + 1];
95 
96 static void
97 nfsstat_zone_init_server(zoneid_t zoneid, kstat_named_t *svstatp[])
98 {
99 	int vers;
100 
101 	/*
102 	 * first two indexes of these arrays are not used, so initialize
103 	 * to NULL
104 	 */
105 	svstatp[0] = NULL;
106 	svstatp[1] = NULL;
107 	global_svstat_ptr[0] = NULL;
108 	global_svstat_ptr[0] = NULL;
109 
110 	for (vers = NFS_VERSION; vers <= NFS_V4; vers++) {
111 		svstatp[vers] = nfsstat_zone_init_common(zoneid, "nfs", vers,
112 			    "nfs_server", svstat_tmpl, sizeof (svstat_tmpl));
113 		if (zoneid == GLOBAL_ZONEID)
114 			global_svstat_ptr[vers] = svstatp[vers];
115 	}
116 }
117 
118 static void
119 nfsstat_zone_fini_server(zoneid_t zoneid, kstat_named_t **svstatp)
120 {
121 	int vers;
122 	for (vers = NFS_VERSION; vers <= NFS_V4; vers++) {
123 		if (zoneid == GLOBAL_ZONEID)
124 			global_svstat_ptr[vers] = NULL;
125 		nfsstat_zone_fini_common(zoneid, "nfs", vers, "nfs_server");
126 		kmem_free(svstatp[vers], sizeof (svstat_tmpl));
127 	}
128 }
129 
130 /*
131  * NFSv2 client stats
132  */
133 static const kstat_named_t rfsreqcnt_v2_tmpl[] = {
134 	{ "null",	KSTAT_DATA_UINT64 },
135 	{ "getattr",	KSTAT_DATA_UINT64 },
136 	{ "setattr",	KSTAT_DATA_UINT64 },
137 	{ "root",	KSTAT_DATA_UINT64 },
138 	{ "lookup",	KSTAT_DATA_UINT64 },
139 	{ "readlink",	KSTAT_DATA_UINT64 },
140 	{ "read",	KSTAT_DATA_UINT64 },
141 	{ "wrcache",	KSTAT_DATA_UINT64 },
142 	{ "write",	KSTAT_DATA_UINT64 },
143 	{ "create",	KSTAT_DATA_UINT64 },
144 	{ "remove",	KSTAT_DATA_UINT64 },
145 	{ "rename",	KSTAT_DATA_UINT64 },
146 	{ "link",	KSTAT_DATA_UINT64 },
147 	{ "symlink",	KSTAT_DATA_UINT64 },
148 	{ "mkdir",	KSTAT_DATA_UINT64 },
149 	{ "rmdir",	KSTAT_DATA_UINT64 },
150 	{ "readdir",	KSTAT_DATA_UINT64 },
151 	{ "statfs",	KSTAT_DATA_UINT64 }
152 };
153 
154 static void
155 nfsstat_zone_init_rfsreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
156 {
157 	statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
158 	    "rfsreqcnt_v2", rfsreqcnt_v2_tmpl, sizeof (rfsreqcnt_v2_tmpl));
159 }
160 
161 static void
162 nfsstat_zone_fini_rfsreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
163 {
164 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v2");
165 	kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v2_tmpl));
166 }
167 
168 /*
169  * NFSv2 server stats
170  */
171 static const kstat_named_t rfsproccnt_v2_tmpl[] = {
172 	{ "null",	KSTAT_DATA_UINT64 },
173 	{ "getattr",	KSTAT_DATA_UINT64 },
174 	{ "setattr",	KSTAT_DATA_UINT64 },
175 	{ "root",	KSTAT_DATA_UINT64 },
176 	{ "lookup",	KSTAT_DATA_UINT64 },
177 	{ "readlink",	KSTAT_DATA_UINT64 },
178 	{ "read",	KSTAT_DATA_UINT64 },
179 	{ "wrcache",	KSTAT_DATA_UINT64 },
180 	{ "write",	KSTAT_DATA_UINT64 },
181 	{ "create",	KSTAT_DATA_UINT64 },
182 	{ "remove",	KSTAT_DATA_UINT64 },
183 	{ "rename",	KSTAT_DATA_UINT64 },
184 	{ "link",	KSTAT_DATA_UINT64 },
185 	{ "symlink",	KSTAT_DATA_UINT64 },
186 	{ "mkdir",	KSTAT_DATA_UINT64 },
187 	{ "rmdir",	KSTAT_DATA_UINT64 },
188 	{ "readdir",	KSTAT_DATA_UINT64 },
189 	{ "statfs",	KSTAT_DATA_UINT64 }
190 };
191 
192 kstat_named_t *rfsproccnt_v2_ptr;
193 
194 static void
195 nfsstat_zone_init_rfsproc_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
196 {
197 	kstat_named_t *ks_data;
198 
199 	ks_data = nfsstat_zone_init_common(zoneid, "nfs", 0, "rfsproccnt_v2",
200 	    rfsproccnt_v2_tmpl, sizeof (rfsproccnt_v2_tmpl));
201 	statsp->rfsproccnt_ptr = ks_data;
202 	if (zoneid == GLOBAL_ZONEID)
203 		rfsproccnt_v2_ptr = ks_data;
204 }
205 
206 static void
207 nfsstat_zone_fini_rfsproc_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
208 {
209 	if (zoneid == GLOBAL_ZONEID)
210 		rfsproccnt_v2_ptr = NULL;
211 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v2");
212 	kmem_free(statsp->rfsproccnt_ptr, sizeof (rfsproccnt_v2_tmpl));
213 }
214 
215 /*
216  * NFSv2 client ACL stats
217  */
218 static const kstat_named_t aclreqcnt_v2_tmpl[] = {
219 	{ "null",	KSTAT_DATA_UINT64 },
220 	{ "getacl",	KSTAT_DATA_UINT64 },
221 	{ "setacl",	KSTAT_DATA_UINT64 },
222 	{ "getattr",	KSTAT_DATA_UINT64 },
223 	{ "access",	KSTAT_DATA_UINT64 },
224 	{ "getxattrdir",	KSTAT_DATA_UINT64 }
225 };
226 
227 static void
228 nfsstat_zone_init_aclreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
229 {
230 	statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
231 	    "aclreqcnt_v2", aclreqcnt_v2_tmpl, sizeof (aclreqcnt_v2_tmpl));
232 }
233 
234 static void
235 nfsstat_zone_fini_aclreq_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
236 {
237 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v2");
238 	kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v2_tmpl));
239 }
240 
241 /*
242  * NFSv2 server ACL stats
243  */
244 static const kstat_named_t aclproccnt_v2_tmpl[] = {
245 	{ "null",	KSTAT_DATA_UINT64 },
246 	{ "getacl",	KSTAT_DATA_UINT64 },
247 	{ "setacl",	KSTAT_DATA_UINT64 },
248 	{ "getattr",	KSTAT_DATA_UINT64 },
249 	{ "access",	KSTAT_DATA_UINT64 },
250 	{ "getxattrdir",	KSTAT_DATA_UINT64 }
251 };
252 
253 kstat_named_t *aclproccnt_v2_ptr;
254 
255 static void
256 nfsstat_zone_init_aclproc_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
257 {
258 	kstat_named_t *ks_data;
259 
260 	ks_data = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
261 	    "aclproccnt_v2", aclproccnt_v2_tmpl,
262 	    sizeof (aclproccnt_v2_tmpl));
263 	statsp->aclproccnt_ptr = ks_data;
264 	if (zoneid == GLOBAL_ZONEID)
265 		aclproccnt_v2_ptr = ks_data;
266 }
267 
268 static void
269 nfsstat_zone_fini_aclproc_v2(zoneid_t zoneid, struct nfs_version_stats *statsp)
270 {
271 	if (zoneid == GLOBAL_ZONEID)
272 		aclproccnt_v2_ptr = NULL;
273 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclproccnt_v2");
274 	kmem_free(statsp->aclproccnt_ptr, sizeof (aclproccnt_v2_tmpl));
275 }
276 
277 /*
278  * NFSv3 client stats
279  */
280 static const kstat_named_t rfsreqcnt_v3_tmpl[] = {
281 	{ "null",	KSTAT_DATA_UINT64 },
282 	{ "getattr",	KSTAT_DATA_UINT64 },
283 	{ "setattr",	KSTAT_DATA_UINT64 },
284 	{ "lookup",	KSTAT_DATA_UINT64 },
285 	{ "access",	KSTAT_DATA_UINT64 },
286 	{ "readlink",	KSTAT_DATA_UINT64 },
287 	{ "read",	KSTAT_DATA_UINT64 },
288 	{ "write",	KSTAT_DATA_UINT64 },
289 	{ "create",	KSTAT_DATA_UINT64 },
290 	{ "mkdir",	KSTAT_DATA_UINT64 },
291 	{ "symlink",	KSTAT_DATA_UINT64 },
292 	{ "mknod",	KSTAT_DATA_UINT64 },
293 	{ "remove",	KSTAT_DATA_UINT64 },
294 	{ "rmdir",	KSTAT_DATA_UINT64 },
295 	{ "rename",	KSTAT_DATA_UINT64 },
296 	{ "link",	KSTAT_DATA_UINT64 },
297 	{ "readdir",	KSTAT_DATA_UINT64 },
298 	{ "readdirplus", KSTAT_DATA_UINT64 },
299 	{ "fsstat",	KSTAT_DATA_UINT64 },
300 	{ "fsinfo",	KSTAT_DATA_UINT64 },
301 	{ "pathconf",	KSTAT_DATA_UINT64 },
302 	{ "commit",	KSTAT_DATA_UINT64 }
303 };
304 
305 static void
306 nfsstat_zone_init_rfsreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
307 {
308 	statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
309 	    "rfsreqcnt_v3", rfsreqcnt_v3_tmpl, sizeof (rfsreqcnt_v3_tmpl));
310 }
311 
312 static void
313 nfsstat_zone_fini_rfsreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
314 {
315 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v3");
316 	kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v3_tmpl));
317 }
318 
319 /*
320  * NFSv3 server stats
321  */
322 static const kstat_named_t rfsproccnt_v3_tmpl[] = {
323 	{ "null",	KSTAT_DATA_UINT64 },
324 	{ "getattr",	KSTAT_DATA_UINT64 },
325 	{ "setattr",	KSTAT_DATA_UINT64 },
326 	{ "lookup",	KSTAT_DATA_UINT64 },
327 	{ "access",	KSTAT_DATA_UINT64 },
328 	{ "readlink",	KSTAT_DATA_UINT64 },
329 	{ "read",	KSTAT_DATA_UINT64 },
330 	{ "write",	KSTAT_DATA_UINT64 },
331 	{ "create",	KSTAT_DATA_UINT64 },
332 	{ "mkdir",	KSTAT_DATA_UINT64 },
333 	{ "symlink",	KSTAT_DATA_UINT64 },
334 	{ "mknod",	KSTAT_DATA_UINT64 },
335 	{ "remove",	KSTAT_DATA_UINT64 },
336 	{ "rmdir",	KSTAT_DATA_UINT64 },
337 	{ "rename",	KSTAT_DATA_UINT64 },
338 	{ "link",	KSTAT_DATA_UINT64 },
339 	{ "readdir",	KSTAT_DATA_UINT64 },
340 	{ "readdirplus", KSTAT_DATA_UINT64 },
341 	{ "fsstat",	KSTAT_DATA_UINT64 },
342 	{ "fsinfo",	KSTAT_DATA_UINT64 },
343 	{ "pathconf",	KSTAT_DATA_UINT64 },
344 	{ "commit",	KSTAT_DATA_UINT64 }
345 };
346 
347 kstat_named_t *rfsproccnt_v3_ptr;
348 
349 static void
350 nfsstat_zone_init_rfsproc_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
351 {
352 	kstat_named_t *ks_data;
353 
354 	ks_data = nfsstat_zone_init_common(zoneid, "nfs", 0, "rfsproccnt_v3",
355 	    rfsproccnt_v3_tmpl, sizeof (rfsproccnt_v3_tmpl));
356 	statsp->rfsproccnt_ptr = ks_data;
357 	if (zoneid == GLOBAL_ZONEID)
358 		rfsproccnt_v3_ptr = ks_data;
359 }
360 
361 static void
362 nfsstat_zone_fini_rfsproc_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
363 {
364 	if (zoneid == GLOBAL_ZONEID)
365 		rfsproccnt_v3_ptr = NULL;
366 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v3");
367 	kmem_free(statsp->rfsproccnt_ptr, sizeof (rfsproccnt_v3_tmpl));
368 }
369 
370 /*
371  * NFSv3 client ACL stats
372  */
373 static const kstat_named_t aclreqcnt_v3_tmpl[] = {
374 	{ "null",	KSTAT_DATA_UINT64 },
375 	{ "getacl",	KSTAT_DATA_UINT64 },
376 	{ "setacl",	KSTAT_DATA_UINT64 },
377 	{ "getxattrdir",	KSTAT_DATA_UINT64 }
378 };
379 
380 static void
381 nfsstat_zone_init_aclreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
382 {
383 	statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
384 	    "aclreqcnt_v3", aclreqcnt_v3_tmpl, sizeof (aclreqcnt_v3_tmpl));
385 }
386 
387 static void
388 nfsstat_zone_fini_aclreq_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
389 {
390 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v3");
391 	kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v3_tmpl));
392 }
393 
394 /*
395  * NFSv3 server ACL stats
396  */
397 static const kstat_named_t aclproccnt_v3_tmpl[] = {
398 	{ "null",	KSTAT_DATA_UINT64 },
399 	{ "getacl",	KSTAT_DATA_UINT64 },
400 	{ "setacl",	KSTAT_DATA_UINT64 },
401 	{ "getxattrdir",	KSTAT_DATA_UINT64 }
402 };
403 
404 kstat_named_t *aclproccnt_v3_ptr;
405 
406 static void
407 nfsstat_zone_init_aclproc_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
408 {
409 	kstat_named_t *ks_data;
410 
411 	ks_data = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
412 	    "aclproccnt_v3", aclproccnt_v3_tmpl,
413 	    sizeof (aclproccnt_v3_tmpl));
414 	statsp->aclproccnt_ptr = ks_data;
415 	if (zoneid == GLOBAL_ZONEID)
416 		aclproccnt_v3_ptr = ks_data;
417 }
418 
419 static void
420 nfsstat_zone_fini_aclproc_v3(zoneid_t zoneid, struct nfs_version_stats *statsp)
421 {
422 	if (zoneid == GLOBAL_ZONEID)
423 		aclproccnt_v3_ptr = NULL;
424 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclproccnt_v3");
425 	kmem_free(statsp->aclproccnt_ptr, sizeof (aclproccnt_v3_tmpl));
426 }
427 
428 /*
429  * NFSv4 client stats
430  */
431 static const kstat_named_t rfsreqcnt_v4_tmpl[] = {
432 	{ "null",	KSTAT_DATA_UINT64 },
433 	{ "compound",	KSTAT_DATA_UINT64 },
434 	{ "reserved",	KSTAT_DATA_UINT64 },
435 	{ "access",	KSTAT_DATA_UINT64 },
436 	{ "close",	KSTAT_DATA_UINT64 },
437 	{ "commit",	KSTAT_DATA_UINT64 },
438 	{ "create",	KSTAT_DATA_UINT64 },
439 	{ "delegpurge",	KSTAT_DATA_UINT64 },
440 	{ "delegreturn",	KSTAT_DATA_UINT64 },
441 	{ "getattr",	KSTAT_DATA_UINT64 },
442 	{ "getfh",	KSTAT_DATA_UINT64 },
443 	{ "link",	KSTAT_DATA_UINT64 },
444 	{ "lock",	KSTAT_DATA_UINT64 },
445 	{ "lockt",	KSTAT_DATA_UINT64 },
446 	{ "locku",	KSTAT_DATA_UINT64 },
447 	{ "lookup",	KSTAT_DATA_UINT64 },
448 	{ "lookupp",	KSTAT_DATA_UINT64 },
449 	{ "nverify",	KSTAT_DATA_UINT64 },
450 	{ "open",	KSTAT_DATA_UINT64 },
451 	{ "openattr",	KSTAT_DATA_UINT64 },
452 	{ "open_confirm",	KSTAT_DATA_UINT64 },
453 	{ "open_downgrade",	KSTAT_DATA_UINT64 },
454 	{ "putfh",	KSTAT_DATA_UINT64 },
455 	{ "putpubfh",	KSTAT_DATA_UINT64 },
456 	{ "putrootfh",	KSTAT_DATA_UINT64 },
457 	{ "read",	KSTAT_DATA_UINT64 },
458 	{ "readdir",	KSTAT_DATA_UINT64 },
459 	{ "readlink",	KSTAT_DATA_UINT64 },
460 	{ "remove",	KSTAT_DATA_UINT64 },
461 	{ "rename",	KSTAT_DATA_UINT64 },
462 	{ "renew",	KSTAT_DATA_UINT64 },
463 	{ "restorefh",	KSTAT_DATA_UINT64 },
464 	{ "savefh",	KSTAT_DATA_UINT64 },
465 	{ "secinfo",	KSTAT_DATA_UINT64 },
466 	{ "setattr",	KSTAT_DATA_UINT64 },
467 	{ "setclientid",	KSTAT_DATA_UINT64 },
468 	{ "setclientid_confirm",	KSTAT_DATA_UINT64 },
469 	{ "verify", KSTAT_DATA_UINT64 },
470 	{ "write",	KSTAT_DATA_UINT64 }
471 };
472 
473 static void
474 nfsstat_zone_init_rfsreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
475 {
476 	statsp->rfsreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs", 0,
477 	    "rfsreqcnt_v4", rfsreqcnt_v4_tmpl, sizeof (rfsreqcnt_v4_tmpl));
478 }
479 
480 static void
481 nfsstat_zone_fini_rfsreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
482 {
483 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsreqcnt_v4");
484 	kmem_free(statsp->rfsreqcnt_ptr, sizeof (rfsreqcnt_v4_tmpl));
485 }
486 
487 /*
488  * NFSv4 server stats
489  */
490 static const kstat_named_t rfsproccnt_v4_tmpl[] = {
491 	{ "null",	KSTAT_DATA_UINT64 },
492 	{ "compound",	KSTAT_DATA_UINT64 },
493 	{ "reserved",	KSTAT_DATA_UINT64 },
494 	{ "access",	KSTAT_DATA_UINT64 },
495 	{ "close",	KSTAT_DATA_UINT64 },
496 	{ "commit",	KSTAT_DATA_UINT64 },
497 	{ "create",	KSTAT_DATA_UINT64 },
498 	{ "delegpurge",	KSTAT_DATA_UINT64 },
499 	{ "delegreturn",	KSTAT_DATA_UINT64 },
500 	{ "getattr",	KSTAT_DATA_UINT64 },
501 	{ "getfh",	KSTAT_DATA_UINT64 },
502 	{ "link",	KSTAT_DATA_UINT64 },
503 	{ "lock",	KSTAT_DATA_UINT64 },
504 	{ "lockt",	KSTAT_DATA_UINT64 },
505 	{ "locku",	KSTAT_DATA_UINT64 },
506 	{ "lookup",	KSTAT_DATA_UINT64 },
507 	{ "lookupp",	KSTAT_DATA_UINT64 },
508 	{ "nverify",	KSTAT_DATA_UINT64 },
509 	{ "open",	KSTAT_DATA_UINT64 },
510 	{ "openattr",	KSTAT_DATA_UINT64 },
511 	{ "open_confirm",	KSTAT_DATA_UINT64 },
512 	{ "open_downgrade",	KSTAT_DATA_UINT64 },
513 	{ "putfh",	KSTAT_DATA_UINT64 },
514 	{ "putpubfh",	KSTAT_DATA_UINT64 },
515 	{ "putrootfh",	KSTAT_DATA_UINT64 },
516 	{ "read",	KSTAT_DATA_UINT64 },
517 	{ "readdir",	KSTAT_DATA_UINT64 },
518 	{ "readlink",	KSTAT_DATA_UINT64 },
519 	{ "remove",	KSTAT_DATA_UINT64 },
520 	{ "rename",	KSTAT_DATA_UINT64 },
521 	{ "renew",	KSTAT_DATA_UINT64 },
522 	{ "restorefh",	KSTAT_DATA_UINT64 },
523 	{ "savefh",	KSTAT_DATA_UINT64 },
524 	{ "secinfo",	KSTAT_DATA_UINT64 },
525 	{ "setattr",	KSTAT_DATA_UINT64 },
526 	{ "setclientid",	KSTAT_DATA_UINT64 },
527 	{ "setclientid_confirm",	KSTAT_DATA_UINT64 },
528 	{ "verify",	KSTAT_DATA_UINT64 },
529 	{ "write",	KSTAT_DATA_UINT64 },
530 	{ "release_lockowner",	KSTAT_DATA_UINT64 },
531 	{ "illegal",	KSTAT_DATA_UINT64 },
532 };
533 
534 kstat_named_t *rfsproccnt_v4_ptr;
535 
536 static void
537 nfsstat_zone_init_rfsproc_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
538 {
539 	kstat_named_t *ks_data;
540 
541 	ks_data = nfsstat_zone_init_common(zoneid, "nfs", 0, "rfsproccnt_v4",
542 	    rfsproccnt_v4_tmpl, sizeof (rfsproccnt_v4_tmpl));
543 	statsp->rfsproccnt_ptr = ks_data;
544 	if (zoneid == GLOBAL_ZONEID)
545 		rfsproccnt_v4_ptr = ks_data;
546 }
547 
548 static void
549 nfsstat_zone_fini_rfsproc_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
550 {
551 	if (zoneid == GLOBAL_ZONEID)
552 		rfsproccnt_v4_ptr = NULL;
553 	nfsstat_zone_fini_common(zoneid, "nfs", 0, "rfsproccnt_v4");
554 	kmem_free(statsp->rfsproccnt_ptr, sizeof (rfsproccnt_v4_tmpl));
555 }
556 
557 /*
558  * NFSv4 client ACL stats
559  */
560 static const kstat_named_t aclreqcnt_v4_tmpl[] = {
561 	{ "null",	KSTAT_DATA_UINT64 },
562 	{ "getacl",	KSTAT_DATA_UINT64 },
563 	{ "setacl",	KSTAT_DATA_UINT64 },
564 };
565 
566 static void
567 nfsstat_zone_init_aclreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
568 {
569 	statsp->aclreqcnt_ptr = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
570 	    "aclreqcnt_v4", aclreqcnt_v4_tmpl, sizeof (aclreqcnt_v4_tmpl));
571 }
572 
573 static void
574 nfsstat_zone_fini_aclreq_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
575 {
576 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclreqcnt_v4");
577 	kmem_free(statsp->aclreqcnt_ptr, sizeof (aclreqcnt_v4_tmpl));
578 }
579 
580 /*
581  * NFSv4 server ACL stats
582  */
583 static const kstat_named_t aclproccnt_v4_tmpl[] = {
584 	{ "null",	KSTAT_DATA_UINT64 },
585 	{ "getacl",	KSTAT_DATA_UINT64 },
586 	{ "setacl",	KSTAT_DATA_UINT64 }
587 };
588 
589 kstat_named_t *aclproccnt_v4_ptr;
590 
591 static void
592 nfsstat_zone_init_aclproc_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
593 {
594 	kstat_named_t *ks_data;
595 
596 	ks_data = nfsstat_zone_init_common(zoneid, "nfs_acl", 0,
597 	    "aclproccnt_v4", aclproccnt_v4_tmpl,
598 	    sizeof (aclproccnt_v4_tmpl));
599 	statsp->aclproccnt_ptr = ks_data;
600 	if (zoneid == GLOBAL_ZONEID)
601 		aclproccnt_v4_ptr = ks_data;
602 }
603 
604 static void
605 nfsstat_zone_fini_aclproc_v4(zoneid_t zoneid, struct nfs_version_stats *statsp)
606 {
607 	if (zoneid == GLOBAL_ZONEID)
608 		aclproccnt_v4_ptr = NULL;
609 	nfsstat_zone_fini_common(zoneid, "nfs_acl", 0, "aclproccnt_v4");
610 	kmem_free(statsp->aclproccnt_ptr, sizeof (aclproccnt_v4_tmpl));
611 }
612 
613 /*
614  * Zone initializer callback to setup the kstats.
615  */
616 void *
617 nfsstat_zone_init(zoneid_t zoneid)
618 {
619 	struct nfs_stats *nfs_stats_ptr;
620 
621 	nfs_stats_ptr = kmem_zalloc(sizeof (*nfs_stats_ptr), KM_SLEEP);
622 
623 	/*
624 	 * Initialize all versions of the nfs_server
625 	 */
626 	nfsstat_zone_init_server(zoneid, nfs_stats_ptr->nfs_stats_svstat_ptr);
627 
628 	/*
629 	 * Initialize v2 stats
630 	 */
631 	nfsstat_zone_init_rfsreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
632 	nfsstat_zone_init_rfsproc_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
633 	nfsstat_zone_init_aclreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
634 	nfsstat_zone_init_aclproc_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
635 	/*
636 	 * Initialize v3 stats
637 	 */
638 	nfsstat_zone_init_rfsreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
639 	nfsstat_zone_init_rfsproc_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
640 	nfsstat_zone_init_aclreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
641 	nfsstat_zone_init_aclproc_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
642 	/*
643 	 * Initialize v4 stats
644 	 */
645 	nfsstat_zone_init_rfsreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
646 	nfsstat_zone_init_rfsproc_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
647 	nfsstat_zone_init_aclreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
648 	nfsstat_zone_init_aclproc_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
649 
650 	return (nfs_stats_ptr);
651 }
652 
653 /*
654  * Zone destructor callback to tear down the various kstats.
655  */
656 void
657 nfsstat_zone_fini(zoneid_t zoneid, void *data)
658 {
659 	struct nfs_stats *nfs_stats_ptr = data;
660 
661 	/*
662 	 * Free nfs:0:nfs_server stats
663 	 */
664 	nfsstat_zone_fini_server(zoneid, nfs_stats_ptr->nfs_stats_svstat_ptr);
665 
666 	/*
667 	 * Free v2 stats
668 	 */
669 	nfsstat_zone_fini_rfsreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
670 	nfsstat_zone_fini_rfsproc_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
671 	nfsstat_zone_fini_aclreq_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
672 	nfsstat_zone_fini_aclproc_v2(zoneid, &nfs_stats_ptr->nfs_stats_v2);
673 	/*
674 	 * Free v3 stats
675 	 */
676 	nfsstat_zone_fini_rfsreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
677 	nfsstat_zone_fini_rfsproc_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
678 	nfsstat_zone_fini_aclreq_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
679 	nfsstat_zone_fini_aclproc_v3(zoneid, &nfs_stats_ptr->nfs_stats_v3);
680 	/*
681 	 * Free v4 stats
682 	 */
683 	nfsstat_zone_fini_rfsreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
684 	nfsstat_zone_fini_rfsproc_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
685 	nfsstat_zone_fini_aclreq_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
686 	nfsstat_zone_fini_aclproc_v4(zoneid, &nfs_stats_ptr->nfs_stats_v4);
687 
688 	kmem_free(nfs_stats_ptr, sizeof (*nfs_stats_ptr));
689 }
690