Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/fs/nfsclient/nfs_clkdtrace.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2009 Robert N. M. Watson
5
* All rights reserved.
6
*
7
* This software was developed at the University of Cambridge Computer
8
* Laboratory with support from a grant from Google, Inc.
9
*
10
* Redistribution and use in source and binary forms, with or without
11
* modification, are permitted provided that the following conditions
12
* are met:
13
* 1. Redistributions of source code must retain the above copyright
14
* notice, this list of conditions and the following disclaimer.
15
* 2. Redistributions in binary form must reproduce the above copyright
16
* notice, this list of conditions and the following disclaimer in the
17
* documentation and/or other materials provided with the distribution.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#include <sys/param.h>
33
#include <sys/systm.h>
34
#include <sys/conf.h>
35
#include <sys/kernel.h>
36
#include <sys/malloc.h>
37
#include <sys/module.h>
38
39
#include <sys/dtrace.h>
40
#include <sys/dtrace_bsd.h>
41
42
#include <fs/nfs/nfsproto.h>
43
44
#include <fs/nfsclient/nfs_kdtrace.h>
45
46
/*
47
* dtnfscl is a DTrace provider that tracks the intent to perform RPCs
48
* in the NFS client, as well as access to and maintenance of the access and
49
* attribute caches. This is not quite the same as RPCs, because NFS may
50
* issue multiple RPC transactions in the event that authentication fails,
51
* there's a jukebox error, or none at all if the access or attribute cache
52
* hits. However, it cleanly represents the logical layer between RPC
53
* transmission and vnode/vfs operations, providing access to state linking
54
* the two.
55
*/
56
57
static int dtnfsclient_unload(void);
58
static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *,
59
dtrace_argdesc_t *);
60
static void dtnfsclient_provide(void *, dtrace_probedesc_t *);
61
static void dtnfsclient_destroy(void *, dtrace_id_t, void *);
62
static void dtnfsclient_enable(void *, dtrace_id_t, void *);
63
static void dtnfsclient_disable(void *, dtrace_id_t, void *);
64
static void dtnfsclient_load(void *);
65
66
static dtrace_pattr_t dtnfsclient_attr = {
67
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
68
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
69
{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
70
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
71
{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
72
};
73
74
/*
75
* Description of NFSv4, NFSv3 and (optional) NFSv2 probes for a procedure.
76
*/
77
struct dtnfsclient_rpc {
78
char *nr_v4_name;
79
char *nr_v3_name; /* Or NULL if none. */
80
char *nr_v2_name; /* Or NULL if none. */
81
82
/*
83
* IDs for the start and done cases, for NFSv2, NFSv3 and NFSv4.
84
*/
85
uint32_t nr_v2_id_start, nr_v2_id_done;
86
uint32_t nr_v3_id_start, nr_v3_id_done;
87
uint32_t nr_v4_id_start, nr_v4_id_done;
88
};
89
90
/*
91
* This table is indexed by NFSv3 procedure number, but also used for NFSv2
92
* procedure names and NFSv4 operations.
93
*/
94
static struct dtnfsclient_rpc dtnfsclient_rpcs[NFSV41_NPROCS + 1] = {
95
{ "null", "null", "null" },
96
{ "getattr", "getattr", "getattr" },
97
{ "setattr", "setattr", "setattr" },
98
{ "lookup", "lookup", "lookup" },
99
{ "access", "access", "noop" },
100
{ "readlink", "readlink", "readlink" },
101
{ "read", "read", "read" },
102
{ "write", "write", "write" },
103
{ "create", "create", "create" },
104
{ "mkdir", "mkdir", "mkdir" },
105
{ "symlink", "symlink", "symlink" },
106
{ "mknod", "mknod" },
107
{ "remove", "remove", "remove" },
108
{ "rmdir", "rmdir", "rmdir" },
109
{ "rename", "rename", "rename" },
110
{ "link", "link", "link" },
111
{ "readdir", "readdir", "readdir" },
112
{ "readdirplus", "readdirplus" },
113
{ "fsstat", "fsstat", "statfs" },
114
{ "fsinfo", "fsinfo" },
115
{ "pathconf", "pathconf" },
116
{ "commit", "commit" },
117
{ "lookupp" },
118
{ "setclientid" },
119
{ "setclientidcfrm" },
120
{ "lock" },
121
{ "locku" },
122
{ "open" },
123
{ "close" },
124
{ "openconfirm" },
125
{ "lockt" },
126
{ "opendowngrade" },
127
{ "renew" },
128
{ "putrootfh" },
129
{ "releaselckown" },
130
{ "delegreturn" },
131
{ "retdelegremove" },
132
{ "retdelegrename1" },
133
{ "retdelegrename2" },
134
{ "getacl" },
135
{ "setacl" },
136
{ "noop", "noop", "noop" }
137
};
138
139
/*
140
* Module name strings.
141
*/
142
static char *dtnfsclient_accesscache_str = "accesscache";
143
static char *dtnfsclient_attrcache_str = "attrcache";
144
static char *dtnfsclient_nfs2_str = "nfs2";
145
static char *dtnfsclient_nfs3_str = "nfs3";
146
static char *dtnfsclient_nfs4_str = "nfs4";
147
148
/*
149
* Function name strings.
150
*/
151
static char *dtnfsclient_flush_str = "flush";
152
static char *dtnfsclient_load_str = "load";
153
static char *dtnfsclient_get_str = "get";
154
155
/*
156
* Name strings.
157
*/
158
static char *dtnfsclient_done_str = "done";
159
static char *dtnfsclient_hit_str = "hit";
160
static char *dtnfsclient_miss_str = "miss";
161
static char *dtnfsclient_start_str = "start";
162
163
static dtrace_pops_t dtnfsclient_pops = {
164
.dtps_provide = dtnfsclient_provide,
165
.dtps_provide_module = NULL,
166
.dtps_enable = dtnfsclient_enable,
167
.dtps_disable = dtnfsclient_disable,
168
.dtps_suspend = NULL,
169
.dtps_resume = NULL,
170
.dtps_getargdesc = dtnfsclient_getargdesc,
171
.dtps_getargval = NULL,
172
.dtps_usermode = NULL,
173
.dtps_destroy = dtnfsclient_destroy
174
};
175
176
static dtrace_provider_id_t dtnfsclient_id;
177
178
/*
179
* When tracing on a procedure is enabled, the DTrace ID for an RPC event is
180
* stored in one of these two NFS client-allocated arrays; 0 indicates that
181
* the event is not being traced so probes should not be called.
182
*
183
* For simplicity, we allocate both v2, v3 and v4 arrays as NFSV41_NPROCS + 1,
184
* and the v2, v3 arrays are simply sparse.
185
*/
186
extern uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1];
187
extern uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1];
188
189
extern uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1];
190
extern uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1];
191
192
extern uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1];
193
extern uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1];
194
195
/*
196
* Look up a DTrace probe ID to see if it's associated with a "done" event --
197
* if so, we will return a fourth argument type of "int".
198
*/
199
static int
200
dtnfs234_isdoneprobe(dtrace_id_t id)
201
{
202
int i;
203
204
for (i = 0; i < NFSV41_NPROCS + 1; i++) {
205
if (dtnfsclient_rpcs[i].nr_v4_id_done == id ||
206
dtnfsclient_rpcs[i].nr_v3_id_done == id ||
207
dtnfsclient_rpcs[i].nr_v2_id_done == id)
208
return (1);
209
}
210
return (0);
211
}
212
213
static void
214
dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg,
215
dtrace_argdesc_t *desc)
216
{
217
const char *p = NULL;
218
219
if (id == nfscl_accesscache_flush_done_id ||
220
id == nfscl_attrcache_flush_done_id ||
221
id == nfscl_attrcache_get_miss_id) {
222
switch (desc->dtargd_ndx) {
223
case 0:
224
p = "struct vnode *";
225
break;
226
default:
227
desc->dtargd_ndx = DTRACE_ARGNONE;
228
break;
229
}
230
} else if (id == nfscl_accesscache_get_hit_id ||
231
id == nfscl_accesscache_get_miss_id) {
232
switch (desc->dtargd_ndx) {
233
case 0:
234
p = "struct vnode *";
235
break;
236
case 1:
237
p = "uid_t";
238
break;
239
case 2:
240
p = "uint32_t";
241
break;
242
default:
243
desc->dtargd_ndx = DTRACE_ARGNONE;
244
break;
245
}
246
} else if (id == nfscl_accesscache_load_done_id) {
247
switch (desc->dtargd_ndx) {
248
case 0:
249
p = "struct vnode *";
250
break;
251
case 1:
252
p = "uid_t";
253
break;
254
case 2:
255
p = "uint32_t";
256
break;
257
case 3:
258
p = "int";
259
break;
260
default:
261
desc->dtargd_ndx = DTRACE_ARGNONE;
262
break;
263
}
264
} else if (id == nfscl_attrcache_get_hit_id) {
265
switch (desc->dtargd_ndx) {
266
case 0:
267
p = "struct vnode *";
268
break;
269
case 1:
270
p = "struct vattr *";
271
break;
272
default:
273
desc->dtargd_ndx = DTRACE_ARGNONE;
274
break;
275
}
276
} else if (id == nfscl_attrcache_load_done_id) {
277
switch (desc->dtargd_ndx) {
278
case 0:
279
p = "struct vnode *";
280
break;
281
case 1:
282
p = "struct vattr *";
283
break;
284
case 2:
285
p = "int";
286
break;
287
default:
288
desc->dtargd_ndx = DTRACE_ARGNONE;
289
break;
290
}
291
} else {
292
switch (desc->dtargd_ndx) {
293
case 0:
294
p = "struct vnode *";
295
break;
296
case 1:
297
p = "struct mbuf *";
298
break;
299
case 2:
300
p = "struct ucred *";
301
break;
302
case 3:
303
p = "int";
304
break;
305
case 4:
306
if (dtnfs234_isdoneprobe(id)) {
307
p = "int";
308
break;
309
}
310
/* FALLSTHROUGH */
311
default:
312
desc->dtargd_ndx = DTRACE_ARGNONE;
313
break;
314
}
315
}
316
if (p != NULL)
317
strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
318
}
319
320
static void
321
dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc)
322
{
323
int i;
324
325
if (desc != NULL)
326
return;
327
328
/*
329
* Register access cache probes.
330
*/
331
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
332
dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
333
nfscl_accesscache_flush_done_id = dtrace_probe_create(
334
dtnfsclient_id, dtnfsclient_accesscache_str,
335
dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
336
}
337
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
338
dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
339
nfscl_accesscache_get_hit_id = dtrace_probe_create(
340
dtnfsclient_id, dtnfsclient_accesscache_str,
341
dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
342
}
343
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
344
dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
345
nfscl_accesscache_get_miss_id = dtrace_probe_create(
346
dtnfsclient_id, dtnfsclient_accesscache_str,
347
dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
348
}
349
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
350
dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
351
nfscl_accesscache_load_done_id = dtrace_probe_create(
352
dtnfsclient_id, dtnfsclient_accesscache_str,
353
dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
354
}
355
356
/*
357
* Register attribute cache probes.
358
*/
359
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
360
dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
361
nfscl_attrcache_flush_done_id = dtrace_probe_create(
362
dtnfsclient_id, dtnfsclient_attrcache_str,
363
dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
364
}
365
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
366
dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
367
nfscl_attrcache_get_hit_id = dtrace_probe_create(
368
dtnfsclient_id, dtnfsclient_attrcache_str,
369
dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
370
}
371
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
372
dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
373
nfscl_attrcache_get_miss_id = dtrace_probe_create(
374
dtnfsclient_id, dtnfsclient_attrcache_str,
375
dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
376
}
377
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
378
dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
379
nfscl_attrcache_load_done_id = dtrace_probe_create(
380
dtnfsclient_id, dtnfsclient_attrcache_str,
381
dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
382
}
383
384
/*
385
* Register NFSv2 RPC procedures; note sparseness check for each slot
386
* in the NFSv3, NFSv4 procnum-indexed array.
387
*/
388
for (i = 0; i < NFSV41_NPROCS + 1; i++) {
389
if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
390
dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
391
dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) ==
392
0) {
393
dtnfsclient_rpcs[i].nr_v2_id_start =
394
dtrace_probe_create(dtnfsclient_id,
395
dtnfsclient_nfs2_str,
396
dtnfsclient_rpcs[i].nr_v2_name,
397
dtnfsclient_start_str, 0,
398
&nfscl_nfs2_start_probes[i]);
399
}
400
if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
401
dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
402
dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) ==
403
0) {
404
dtnfsclient_rpcs[i].nr_v2_id_done =
405
dtrace_probe_create(dtnfsclient_id,
406
dtnfsclient_nfs2_str,
407
dtnfsclient_rpcs[i].nr_v2_name,
408
dtnfsclient_done_str, 0,
409
&nfscl_nfs2_done_probes[i]);
410
}
411
}
412
413
/*
414
* Register NFSv3 RPC procedures; note sparseness check for each slot
415
* in the NFSv4 procnum-indexed array.
416
*/
417
for (i = 0; i < NFSV41_NPROCS + 1; i++) {
418
if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
419
dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
420
dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) ==
421
0) {
422
dtnfsclient_rpcs[i].nr_v3_id_start =
423
dtrace_probe_create(dtnfsclient_id,
424
dtnfsclient_nfs3_str,
425
dtnfsclient_rpcs[i].nr_v3_name,
426
dtnfsclient_start_str, 0,
427
&nfscl_nfs3_start_probes[i]);
428
}
429
if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
430
dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
431
dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) ==
432
0) {
433
dtnfsclient_rpcs[i].nr_v3_id_done =
434
dtrace_probe_create(dtnfsclient_id,
435
dtnfsclient_nfs3_str,
436
dtnfsclient_rpcs[i].nr_v3_name,
437
dtnfsclient_done_str, 0,
438
&nfscl_nfs3_done_probes[i]);
439
}
440
}
441
442
/*
443
* Register NFSv4 RPC procedures.
444
*/
445
for (i = 0; i < NFSV41_NPROCS + 1; i++) {
446
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
447
dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_start_str) ==
448
0) {
449
dtnfsclient_rpcs[i].nr_v4_id_start =
450
dtrace_probe_create(dtnfsclient_id,
451
dtnfsclient_nfs4_str,
452
dtnfsclient_rpcs[i].nr_v4_name,
453
dtnfsclient_start_str, 0,
454
&nfscl_nfs4_start_probes[i]);
455
}
456
if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
457
dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_done_str) ==
458
0) {
459
dtnfsclient_rpcs[i].nr_v4_id_done =
460
dtrace_probe_create(dtnfsclient_id,
461
dtnfsclient_nfs4_str,
462
dtnfsclient_rpcs[i].nr_v4_name,
463
dtnfsclient_done_str, 0,
464
&nfscl_nfs4_done_probes[i]);
465
}
466
}
467
}
468
469
static void
470
dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg)
471
{
472
}
473
474
static void
475
dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg)
476
{
477
uint32_t *p = parg;
478
void *f = dtrace_probe;
479
480
if (id == nfscl_accesscache_flush_done_id)
481
dtrace_nfscl_accesscache_flush_done_probe = f;
482
else if (id == nfscl_accesscache_get_hit_id)
483
dtrace_nfscl_accesscache_get_hit_probe = f;
484
else if (id == nfscl_accesscache_get_miss_id)
485
dtrace_nfscl_accesscache_get_miss_probe = f;
486
else if (id == nfscl_accesscache_load_done_id)
487
dtrace_nfscl_accesscache_load_done_probe = f;
488
else if (id == nfscl_attrcache_flush_done_id)
489
dtrace_nfscl_attrcache_flush_done_probe = f;
490
else if (id == nfscl_attrcache_get_hit_id)
491
dtrace_nfscl_attrcache_get_hit_probe = f;
492
else if (id == nfscl_attrcache_get_miss_id)
493
dtrace_nfscl_attrcache_get_miss_probe = f;
494
else if (id == nfscl_attrcache_load_done_id)
495
dtrace_nfscl_attrcache_load_done_probe = f;
496
else
497
*p = id;
498
}
499
500
static void
501
dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg)
502
{
503
uint32_t *p = parg;
504
505
if (id == nfscl_accesscache_flush_done_id)
506
dtrace_nfscl_accesscache_flush_done_probe = NULL;
507
else if (id == nfscl_accesscache_get_hit_id)
508
dtrace_nfscl_accesscache_get_hit_probe = NULL;
509
else if (id == nfscl_accesscache_get_miss_id)
510
dtrace_nfscl_accesscache_get_miss_probe = NULL;
511
else if (id == nfscl_accesscache_load_done_id)
512
dtrace_nfscl_accesscache_load_done_probe = NULL;
513
else if (id == nfscl_attrcache_flush_done_id)
514
dtrace_nfscl_attrcache_flush_done_probe = NULL;
515
else if (id == nfscl_attrcache_get_hit_id)
516
dtrace_nfscl_attrcache_get_hit_probe = NULL;
517
else if (id == nfscl_attrcache_get_miss_id)
518
dtrace_nfscl_attrcache_get_miss_probe = NULL;
519
else if (id == nfscl_attrcache_load_done_id)
520
dtrace_nfscl_attrcache_load_done_probe = NULL;
521
else
522
*p = 0;
523
}
524
525
static void
526
dtnfsclient_load(void *dummy)
527
{
528
529
if (dtrace_register("nfscl", &dtnfsclient_attr,
530
DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL,
531
&dtnfsclient_id) != 0)
532
return;
533
534
dtrace_nfscl_nfs234_start_probe =
535
(dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe;
536
dtrace_nfscl_nfs234_done_probe =
537
(dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe;
538
}
539
540
static int
541
dtnfsclient_unload(void)
542
{
543
544
dtrace_nfscl_nfs234_start_probe = NULL;
545
dtrace_nfscl_nfs234_done_probe = NULL;
546
547
return (dtrace_unregister(dtnfsclient_id));
548
}
549
550
static int
551
dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused)
552
{
553
int error = 0;
554
555
switch (type) {
556
case MOD_LOAD:
557
break;
558
559
case MOD_UNLOAD:
560
break;
561
562
case MOD_SHUTDOWN:
563
break;
564
565
default:
566
error = EOPNOTSUPP;
567
break;
568
}
569
570
return (error);
571
}
572
573
SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
574
dtnfsclient_load, NULL);
575
SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
576
dtnfsclient_unload, NULL);
577
578
DEV_MODULE(dtnfscl, dtnfsclient_modevent, NULL);
579
MODULE_VERSION(dtnfscl, 1);
580
MODULE_DEPEND(dtnfscl, dtrace, 1, 1, 1);
581
MODULE_DEPEND(dtnfscl, opensolaris, 1, 1, 1);
582
MODULE_DEPEND(dtnfscl, nfscl, 1, 1, 1);
583
MODULE_DEPEND(dtnfscl, nfscommon, 1, 1, 1);
584
585