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