xref: /illumos-gate/usr/src/uts/common/io/ktest/ktest.c (revision 08855964b9970604433f7b19dcd71cf5af5e5f14)
1*08855964SRyan Zezeski /*
2*08855964SRyan Zezeski  * This file and its contents are supplied under the terms of the
3*08855964SRyan Zezeski  * Common Development and Distribution License ("CDDL"), version 1.0.
4*08855964SRyan Zezeski  * You may only use this file in accordance with the terms of version
5*08855964SRyan Zezeski  * 1.0 of the CDDL.
6*08855964SRyan Zezeski  *
7*08855964SRyan Zezeski  * A full copy of the text of the CDDL should have accompanied this
8*08855964SRyan Zezeski  * source.  A copy of the CDDL is also available via the Internet at
9*08855964SRyan Zezeski  * http://www.illumos.org/license/CDDL.
10*08855964SRyan Zezeski  */
11*08855964SRyan Zezeski 
12*08855964SRyan Zezeski /*
13*08855964SRyan Zezeski  * Copyright 2023 Oxide Computer Company
14*08855964SRyan Zezeski  * Copyright 2024 Ryan Zezeski
15*08855964SRyan Zezeski  */
16*08855964SRyan Zezeski 
17*08855964SRyan Zezeski /*
18*08855964SRyan Zezeski  * The Kernel Test Facility
19*08855964SRyan Zezeski  * ------------------------
20*08855964SRyan Zezeski  *
21*08855964SRyan Zezeski  * The kernel test facility, otherwise known as "ktest", provides a
22*08855964SRyan Zezeski  * means for in situ kernel testing. It allows one to write kernel
23*08855964SRyan Zezeski  * modules whose purpose is to test other kernel modules (or the
24*08855964SRyan Zezeski  * kernel at large). While much can be tested from userland, there are
25*08855964SRyan Zezeski  * some cases where there is no substitute for running the test code
26*08855964SRyan Zezeski  * in kernel context, right next to the code it's testing. In many
27*08855964SRyan Zezeski  * cases it's the only way to efficiently test specific execution
28*08855964SRyan Zezeski  * paths, by avoiding the brittleness of action from afar which relies
29*08855964SRyan Zezeski  * on subtle interactions between userland and kernel. For these
30*08855964SRyan Zezeski  * cases, and many more, ktest gives you the best chance at directly
31*08855964SRyan Zezeski  * testing kernel code (short of injecting DEBUG invariant checks
32*08855964SRyan Zezeski  * inline with the code itself).
33*08855964SRyan Zezeski  *
34*08855964SRyan Zezeski  * The kernel test facility provides the following.
35*08855964SRyan Zezeski  *
36*08855964SRyan Zezeski  * - The ktest kernel module (this file), which acts as a central
37*08855964SRyan Zezeski  *   location for all administration and execution of test modules.
38*08855964SRyan Zezeski  *
39*08855964SRyan Zezeski  * - The ktest(9) API, which provides the tools to write tests and
40*08855964SRyan Zezeski  *   register them with the ktest module.
41*08855964SRyan Zezeski  *
42*08855964SRyan Zezeski  * - The ktest pseudo device, which presents a control surface to
43*08855964SRyan Zezeski  *   userspace in the form of your typical ioctl interface.
44*08855964SRyan Zezeski  *
45*08855964SRyan Zezeski  * - A ktest(8) user command, which provides a user interface to the
46*08855964SRyan Zezeski  *   ktest facility.
47*08855964SRyan Zezeski  *
48*08855964SRyan Zezeski  * Ktest Architecture
49*08855964SRyan Zezeski  * ------------------
50*08855964SRyan Zezeski  *
51*08855964SRyan Zezeski  * ## The Test Triple
52*08855964SRyan Zezeski  *
53*08855964SRyan Zezeski  * Ktest provides a three-level namespace for organizing tests,
54*08855964SRyan Zezeski  * referred to as the "test triple". It consists of the module name,
55*08855964SRyan Zezeski  * suite name, and test name, written as '<module>:<suite>:<test>'.
56*08855964SRyan Zezeski  *
57*08855964SRyan Zezeski  * - Module: The top of the namespace, typically named after the
58*08855964SRyan Zezeski  *   module-under-test (MUT). The convention is to append the '_test'
59*08855964SRyan Zezeski  *   suffix to the module-under-test. For example, the 'mac' module
60*08855964SRyan Zezeski  *   might have a 'mac_test' test module. However, there is no hard
61*08855964SRyan Zezeski  *   rule that a test module must be named after its
62*08855964SRyan Zezeski  *   module-under-test, it’s merely a suggestion. Such a convention is
63*08855964SRyan Zezeski  *   a bit unwieldy for large modules like genunix. In those cases it
64*08855964SRyan Zezeski  *   makes sense to break from the norm.
65*08855964SRyan Zezeski  *
66*08855964SRyan Zezeski  * - Suite: Each module consists of one or more suites. A suite groups
67*08855964SRyan Zezeski  *   tests of related functionality. For example, you may have several
68*08855964SRyan Zezeski  *   tests that verify checksum routines for which you might name the
69*08855964SRyan Zezeski  *   suite 'checksum'.
70*08855964SRyan Zezeski  *
71*08855964SRyan Zezeski  * - Test: Each suite consists of one of more tests. The name of the
72*08855964SRyan Zezeski  *   test can be any string which you find descriptive of the test. A
73*08855964SRyan Zezeski  *   unit test for a single, small function will often use the name of
74*08855964SRyan Zezeski  *   the function-under-test with a _test suffix added. But for
75*08855964SRyan Zezeski  *   testing a series of function calls, or a larger function, it may
76*08855964SRyan Zezeski  *   make sense to abandon this convention.
77*08855964SRyan Zezeski  *
78*08855964SRyan Zezeski  * A test triple can be fully or partially-qualified, depending on the
79*08855964SRyan Zezeski  * context. A fully-qualified triple is one that names one test by
80*08855964SRyan Zezeski  * specifying each level of the namespace and using no glob characters
81*08855964SRyan Zezeski  * -- it’s unambiguous. A partially-qualified triple, on the other
82*08855964SRyan Zezeski  * hand, can be ambiguous; it only names some of the namespace or
83*08855964SRyan Zezeski  * makes use of glob characters.
84*08855964SRyan Zezeski  *
85*08855964SRyan Zezeski  * Fully qualified:
86*08855964SRyan Zezeski  *
87*08855964SRyan Zezeski  *   'mac:checksum:mac_sw_cksum_ipv4_tcp_test'
88*08855964SRyan Zezeski  *
89*08855964SRyan Zezeski  * Partially qualified
90*08855964SRyan Zezeski  *
91*08855964SRyan Zezeski  *   '*'
92*08855964SRyan Zezeski  *   '*:*:*'
93*08855964SRyan Zezeski  *   'mac:'
94*08855964SRyan Zezeski  *   'mac:checksum'
95*08855964SRyan Zezeski  *   'mac:*:mac_sw*'
96*08855964SRyan Zezeski  *
97*08855964SRyan Zezeski  * ## The Context Handle
98*08855964SRyan Zezeski  *
99*08855964SRyan Zezeski  * All communication between ktest and the individual test happens via
100*08855964SRyan Zezeski  * the "context object". This object cannot be accessed directly.
101*08855964SRyan Zezeski  * Instead, ktest provides a context handle to be accessed via its
102*08855964SRyan Zezeski  * ktest(9) API. A test must conform to the ktest_fn_t prototype.
103*08855964SRyan Zezeski  *
104*08855964SRyan Zezeski  * ## Setting Test Results
105*08855964SRyan Zezeski  *
106*08855964SRyan Zezeski  * A test conveys its result using one of the result ktest(9) APIs. A
107*08855964SRyan Zezeski  * result is typically pass or fail, but a test may also be skipped or
108*08855964SRyan Zezeski  * may encounter an unforeseen error. See ktest_result_type_t for a
109*08855964SRyan Zezeski  * description of the types of results. All test results should
110*08855964SRyan Zezeski  * include the associated source line by way of the __LINE__ macro.
111*08855964SRyan Zezeski  * The fail, error, and skip results should also include a message
112*08855964SRyan Zezeski  * giving further context on the result.
113*08855964SRyan Zezeski  *
114*08855964SRyan Zezeski  * ktest_result_pass(ktest_ctx_hdl_t *, int)
115*08855964SRyan Zezeski  *
116*08855964SRyan Zezeski  *   The test ran as expected and all conditions were met. The result
117*08855964SRyan Zezeski  *   value is set to KTEST_RESULT_PASS.
118*08855964SRyan Zezeski  *
119*08855964SRyan Zezeski  * ktest_result_fail(ktest_ctx_hdl_t *, int, const char *, ...)
120*08855964SRyan Zezeski  *
121*08855964SRyan Zezeski  *   One of the test conditions was violated. The test should use the
122*08855964SRyan Zezeski  *   format string and arguments to create a message describing which
123*08855964SRyan Zezeski  *   condition failed and why. The result value is set to KTEST_RESULT_FAIL.
124*08855964SRyan Zezeski  *
125*08855964SRyan Zezeski  * ktest_result_error(ktest_ctx_hdl_t *, int, const char *, ...)
126*08855964SRyan Zezeski  *
127*08855964SRyan Zezeski  *   The test encountered an unexpected error, one that is not
128*08855964SRyan Zezeski  *   directly related to the logic under test. For example, failure to
129*08855964SRyan Zezeski  *   acquire memory is often outside of the test parameters for most
130*08855964SRyan Zezeski  *   tests. These types of errors are often encountered when
131*08855964SRyan Zezeski  *   interacting with the kernel at large and when acquiring resources
132*08855964SRyan Zezeski  *   for test setup. Perhaps most importantly, it indicates the lack
133*08855964SRyan Zezeski  *   of a pass/fail determination for this test. The result value is
134*08855964SRyan Zezeski  *   set to KTEST_RESULT_ERROR.
135*08855964SRyan Zezeski  *
136*08855964SRyan Zezeski  * ktest_result_skip(ktest_ctx_hdl_t *, int, const char *, ...)
137*08855964SRyan Zezeski  *
138*08855964SRyan Zezeski  *   The test lacks the required context to execute, typically for
139*08855964SRyan Zezeski  *   lack of resources or specific hardware under test. Like the error
140*08855964SRyan Zezeski  *   result, this lacks a pass/fail determination. The result value is
141*08855964SRyan Zezeski  *   set to KTEST_RESULT_SKIP.
142*08855964SRyan Zezeski  *
143*08855964SRyan Zezeski  * ## Result Macros
144*08855964SRyan Zezeski  *
145*08855964SRyan Zezeski  * Using the API above is cumbersome, requiring the repetitive use of
146*08855964SRyan Zezeski  * the __LINE__ macro. The following macros are provided for ease of
147*08855964SRyan Zezeski  * use.
148*08855964SRyan Zezeski  *
149*08855964SRyan Zezeski  *     - KT_PASS(ktest_ctx_hdl_t *ctx)
150*08855964SRyan Zezeski  *     - KT_FAIL(ktest_ctx_hdl_t *ctx, char *msg, ...)
151*08855964SRyan Zezeski  *     - KT_ERROR(ktest_ctx_hdl_t *ctx, char *msg, ...)
152*08855964SRyan Zezeski  *     - KT_SKIP(ktest_ctx_hdl_t *ctx, char *msg, ...)
153*08855964SRyan Zezeski  *
154*08855964SRyan Zezeski  * ## KTest ASSERT Macros
155*08855964SRyan Zezeski  *
156*08855964SRyan Zezeski  * Even with the help of the result macros, writing test assertions
157*08855964SRyan Zezeski  * requires quite a bit of verbosity and boilerplate; requiring an if
158*08855964SRyan Zezeski  * statement, a KT_* call, and the failure message arguments. The
159*08855964SRyan Zezeski  * KTest ASSERT macros provide an ASSERT3-like family of macros to
160*08855964SRyan Zezeski  * reduce the boilerplate and make test writing feel more natural.
161*08855964SRyan Zezeski  * However, they are different from the ASSERT3 family in two major
162*08855964SRyan Zezeski  * ways.
163*08855964SRyan Zezeski  *
164*08855964SRyan Zezeski  * 1. They don't panic. The point is to report test failure, not
165*08855964SRyan Zezeski  *    preserve system state leading up to an invalid condition.
166*08855964SRyan Zezeski  *    However, for particularly difficult-to-debug test failures you
167*08855964SRyan Zezeski  *    could use DTrace to invoke a panic upon entry to
168*08855964SRyan Zezeski  *    ktest_result_error.
169*08855964SRyan Zezeski  *
170*08855964SRyan Zezeski  * 2. Following from (1), there may be test state to cleanup such as
171*08855964SRyan Zezeski  *    freeing memory or other resources. This cleanup needs to happen
172*08855964SRyan Zezeski  *    as a consequence of the assertion triggering, before returning
173*08855964SRyan Zezeski  *    from the test function.
174*08855964SRyan Zezeski  *
175*08855964SRyan Zezeski  * There are three types of KT_ASSERT macros: KTest ASSERT, KTest
176*08855964SRyan Zezeski  * ASSERT Goto, and KTest ASSERT Block. The first type of assert is
177*08855964SRyan Zezeski  * the closest match to the standard ASSERT macros: they provide no
178*08855964SRyan Zezeski  * state cleanup, but require the context handle is passed as final
179*08855964SRyan Zezeski  * argument. The goto versions allow for cleanup via a jump to a
180*08855964SRyan Zezeski  * label. The block versions allow for cleanup via an attached block,
181*08855964SRyan Zezeski  * much like an if statement, but requires an additional
182*08855964SRyan Zezeski  * KT_ASSERTB_END to indicate the end of the block. What follows is a
183*08855964SRyan Zezeski  * list of the various KT_ASSERT macros and their arguments. For each
184*08855964SRyan Zezeski  * macro listed below, there is a corresponding KTEST_EASSERT macro.
185*08855964SRyan Zezeski  * These later macros set a KTEST_ERROR result when tripped.
186*08855964SRyan Zezeski  *
187*08855964SRyan Zezeski  * KTest ASSERT (no cleanup)
188*08855964SRyan Zezeski  *
189*08855964SRyan Zezeski  *   KTEST_ASSERT3S(left, op, right, ctx)
190*08855964SRyan Zezeski  *   KTEST_ASSERT3U(left, op, right, ctx)
191*08855964SRyan Zezeski  *   KTEST_ASSERT3P(left, op, right, ctx)
192*08855964SRyan Zezeski  *   KTEST_ASSERT(exp, ctx)
193*08855964SRyan Zezeski  *   KTEST_ASSERT0(exp, ctx)
194*08855964SRyan Zezeski  *
195*08855964SRyan Zezeski  * KTest ASSERT Goto (cleanup via label)
196*08855964SRyan Zezeski  *
197*08855964SRyan Zezeski  *   KT_ASSERT3SG(left, op, right, ctx, label)
198*08855964SRyan Zezeski  *   KT_ASSERT3UG(left, op, right, ctx, label)
199*08855964SRyan Zezeski  *   KT_ASSERT3PG(left, op, right, ctx, label)
200*08855964SRyan Zezeski  *   KT_ASSERTG(exp, ctx, label)
201*08855964SRyan Zezeski  *   KT_ASSERT0G(exp, ctx, label)
202*08855964SRyan Zezeski  *
203*08855964SRyan Zezeski  * KTest ASSERT Block (cleanup via block)
204*08855964SRyan Zezeski  *
205*08855964SRyan Zezeski  *   KT_ASSERT*B(left, op, right, ctx) {
206*08855964SRyan Zezeski  *      <... cleanup goes here ...>
207*08855964SRyan Zezeski  *   }
208*08855964SRyan Zezeski  *   KT_ASSERTB_END
209*08855964SRyan Zezeski  *
210*08855964SRyan Zezeski  * ## Additional Failure/Error Context
211*08855964SRyan Zezeski  *
212*08855964SRyan Zezeski  * Sometimes the failure message generated by the KT_ASSERT macro is
213*08855964SRyan Zezeski  * not enough. You might want to prepend some information to the
214*08855964SRyan Zezeski  * message to provide additional context about the failure. This would
215*08855964SRyan Zezeski  * require using the ktest result API manually, which defeats the
216*08855964SRyan Zezeski  * purpose of the KT_ASSERT macros. Instead, ktest offers the
217*08855964SRyan Zezeski  * ktest_msg_{prepend,clear}(9F) API; allowing you to prepend
218*08855964SRyan Zezeski  * additional context to the failure message (if the assertion should
219*08855964SRyan Zezeski  * trip) while still using the KT_ASSERT macros.
220*08855964SRyan Zezeski  *
221*08855964SRyan Zezeski  * For example, if you were asserting an invariant on an array of
222*08855964SRyan Zezeski  * objects, and you wanted the failure message to include the index of
223*08855964SRyan Zezeski  * the object which tripped the assert, you could write something like
224*08855964SRyan Zezeski  * the following.
225*08855964SRyan Zezeski  *
226*08855964SRyan Zezeski  * ----
227*08855964SRyan Zezeski  * for (int i = 0; i < num_objs; i++) {
228*08855964SRyan Zezeski  *         obj_t *obj = &objs[i];
229*08855964SRyan Zezeski  *
230*08855964SRyan Zezeski  *         ktest_msg_prepend(ctx, "objs[%d]: ", i);
231*08855964SRyan Zezeski  *         KT_ASSERT3P(obj->o_state, !=, NULL, ctx);
232*08855964SRyan Zezeski  * }
233*08855964SRyan Zezeski  *
234*08855964SRyan Zezeski  * ktest_msg_clear(ctx);
235*08855964SRyan Zezeski  * ----
236*08855964SRyan Zezeski  *
237*08855964SRyan Zezeski  * The ktest_msg_prepend() call is not additive; it always overwrites
238*08855964SRyan Zezeski  * the contents of the prepend buffer.
239*08855964SRyan Zezeski  *
240*08855964SRyan Zezeski  * ## Test Input
241*08855964SRyan Zezeski  *
242*08855964SRyan Zezeski  * A test has the option to require input. The input is always in the
243*08855964SRyan Zezeski  * form of a byte stream. The interpretation of those bytes is left to
244*08855964SRyan Zezeski  * the test; the ktest facility at large treats the input stream as
245*08855964SRyan Zezeski  * opaque. It is legal to have an input stream of zero bytes. The test
246*08855964SRyan Zezeski  * retrieves its byte stream with the ktest_get_input(9F) API.
247*08855964SRyan Zezeski  *
248*08855964SRyan Zezeski  * ## Testing Private Functions
249*08855964SRyan Zezeski  *
250*08855964SRyan Zezeski  * A test module often needs to test static (private) functions.
251*08855964SRyan Zezeski  * However, as the test module and module-under-test are two different
252*08855964SRyan Zezeski  * modules, and a static function's linkage is local, there is no way
253*08855964SRyan Zezeski  * to easily access them. Ktest works around this by offering a set of
254*08855964SRyan Zezeski  * APIs to dynamically load the the function object into the test module.
255*08855964SRyan Zezeski  *
256*08855964SRyan Zezeski  *   ktest_hold_mod(9F)
257*08855964SRyan Zezeski  *   ktest_get_fn(9F)
258*08855964SRyan Zezeski  *   ktest_release_mod(9F)
259*08855964SRyan Zezeski  *
260*08855964SRyan Zezeski  * The test modules must perform four steps when accessing a static
261*08855964SRyan Zezeski  * function.
262*08855964SRyan Zezeski  *
263*08855964SRyan Zezeski  *   1. Recreate the function prototype, typically in the form of a
264*08855964SRyan Zezeski  *      typedef. This is then used to declare the function pointer to
265*08855964SRyan Zezeski  *      the static function.
266*08855964SRyan Zezeski  *
267*08855964SRyan Zezeski  *   2. Get a handle to the module-under-test via ktest_hold_mod(9F).
268*08855964SRyan Zezeski  *
269*08855964SRyan Zezeski  *   3. Fill in the function pointer with ktest_get_fn(9F), after
270*08855964SRyan Zezeski  *      which it can be called just as it would in the
271*08855964SRyan Zezeski  *      module-under-test.
272*08855964SRyan Zezeski  *
273*08855964SRyan Zezeski  *   4. At completion of the test release the module handle via
274*08855964SRyan Zezeski  *      ktest_release_mod(9F).
275*08855964SRyan Zezeski  *
276*08855964SRyan Zezeski  * ## Registering Tests
277*08855964SRyan Zezeski  *
278*08855964SRyan Zezeski  * For a test to be run it first needs to be registered with the ktest
279*08855964SRyan Zezeski  * facility. This is done via the ktest(9) APIs described below. The
280*08855964SRyan Zezeski  * test module should be a 'modlmisc' module and perform all test
281*08855964SRyan Zezeski  * registration/unregistration in its '_init' and '_fini' callbacks.
282*08855964SRyan Zezeski  * Internally, ktest tracks all registered tests via the ktest_modules
283*08855964SRyan Zezeski  * list.
284*08855964SRyan Zezeski  *
285*08855964SRyan Zezeski  * ktest_create_module(9F)
286*08855964SRyan Zezeski  * ktest_add_test(9F)
287*08855964SRyan Zezeski  * ktest_add_suite(9F)
288*08855964SRyan Zezeski  * ktest_register_module(9F)
289*08855964SRyan Zezeski  * ktest_unregister_module(9F)
290*08855964SRyan Zezeski  *
291*08855964SRyan Zezeski  * The creation and registration of tests is typically done in the
292*08855964SRyan Zezeski  * following order.
293*08855964SRyan Zezeski  *
294*08855964SRyan Zezeski  *   1. Create a new module with ktest_create_module(9F).
295*08855964SRyan Zezeski  *
296*08855964SRyan Zezeski  *   2. Add a new suite with ktest_add_suite(9F).
297*08855964SRyan Zezeski  *
298*08855964SRyan Zezeski  *   3. Add one or more tests to the suite with ktest_add_test(9F).
299*08855964SRyan Zezeski  *
300*08855964SRyan Zezeski  *   4. Go back to step (2) if more suites are needed.
301*08855964SRyan Zezeski  *
302*08855964SRyan Zezeski  *   5. Register the module with ktest_register_module(9F).
303*08855964SRyan Zezeski  *
304*08855964SRyan Zezeski  * For unregistering your test module it's a simple matter of calling
305*08855964SRyan Zezeski  * ktest_unregister_module(9F).
306*08855964SRyan Zezeski  *
307*08855964SRyan Zezeski  * The ktest_add_test(9F) API does provide a flags argument for
308*08855964SRyan Zezeski  * providing additional information about the test, see
309*08855964SRyan Zezeski  * ktest_test_flags_t for more information.
310*08855964SRyan Zezeski  */
311*08855964SRyan Zezeski #include <sys/stddef.h>
312*08855964SRyan Zezeski #include <sys/conf.h>
313*08855964SRyan Zezeski #include <sys/file.h>
314*08855964SRyan Zezeski #include <sys/stat.h>
315*08855964SRyan Zezeski #include <sys/modctl.h>
316*08855964SRyan Zezeski #include <sys/ktest_impl.h>
317*08855964SRyan Zezeski #include <sys/ddi.h>
318*08855964SRyan Zezeski #include <sys/sunddi.h>
319*08855964SRyan Zezeski 
320*08855964SRyan Zezeski #define	KTEST_CTL_MINOR	0
321*08855964SRyan Zezeski 
322*08855964SRyan Zezeski dev_info_t	*ktest_dip;
323*08855964SRyan Zezeski kmutex_t	ktest_lock;
324*08855964SRyan Zezeski 
325*08855964SRyan Zezeski /*
326*08855964SRyan Zezeski  * The global list of registered ktest modules. A module must call
327*08855964SRyan Zezeski  * ktest_register_module() to register itself with the ktest framework.
328*08855964SRyan Zezeski  *
329*08855964SRyan Zezeski  * Protected by ktest_lock.
330*08855964SRyan Zezeski  *
331*08855964SRyan Zezeski  * List modules in MDB
332*08855964SRyan Zezeski  * -------------------
333*08855964SRyan Zezeski  *
334*08855964SRyan Zezeski  * > ktest_modules::walk list |::print ktest_module_t
335*08855964SRyan Zezeski  */
336*08855964SRyan Zezeski list_t ktest_modules;
337*08855964SRyan Zezeski 
338*08855964SRyan Zezeski /*
339*08855964SRyan Zezeski  * Determine if the name is valid. This is probably overly
340*08855964SRyan Zezeski  * restrictive, but it's easier to add additional characters later
341*08855964SRyan Zezeski  * than to remove them. We want to avoid:
342*08855964SRyan Zezeski  *
343*08855964SRyan Zezeski  * - KTEST_SEPARATOR and KTEST_GMATCH_CHARS, as it causes ambiguity.
344*08855964SRyan Zezeski  *
345*08855964SRyan Zezeski  * - Characters that make it harder to use the ktest command in an
346*08855964SRyan Zezeski  *   interactive shell, such as whitespace and special characters like '&'.
347*08855964SRyan Zezeski  */
348*08855964SRyan Zezeski static int
ktest_valid_name(const char * name)349*08855964SRyan Zezeski ktest_valid_name(const char *name)
350*08855964SRyan Zezeski {
351*08855964SRyan Zezeski 	size_t len = strnlen(name, KTEST_MAX_NAME_LEN);
352*08855964SRyan Zezeski 
353*08855964SRyan Zezeski 	if (len >= KTEST_MAX_NAME_LEN) {
354*08855964SRyan Zezeski 		return (EOVERFLOW);
355*08855964SRyan Zezeski 	}
356*08855964SRyan Zezeski 
357*08855964SRyan Zezeski 	for (uint_t i = 0; i < len; i++) {
358*08855964SRyan Zezeski 		char c = name[i];
359*08855964SRyan Zezeski 		boolean_t good_char = c == '.' || c == '_' ||
360*08855964SRyan Zezeski 		    (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
361*08855964SRyan Zezeski 		    (c >= '0' && c <= '9');
362*08855964SRyan Zezeski 
363*08855964SRyan Zezeski 		if (!good_char) {
364*08855964SRyan Zezeski 			return (EINVAL);
365*08855964SRyan Zezeski 		}
366*08855964SRyan Zezeski 	}
367*08855964SRyan Zezeski 
368*08855964SRyan Zezeski 	return (0);
369*08855964SRyan Zezeski }
370*08855964SRyan Zezeski 
371*08855964SRyan Zezeski static ktest_module_t *
ktest_find_module(const char * module)372*08855964SRyan Zezeski ktest_find_module(const char *module)
373*08855964SRyan Zezeski {
374*08855964SRyan Zezeski 	ktest_module_t *km = NULL;
375*08855964SRyan Zezeski 
376*08855964SRyan Zezeski 	VERIFY(MUTEX_HELD(&ktest_lock));
377*08855964SRyan Zezeski 
378*08855964SRyan Zezeski 	for (km = list_head(&ktest_modules); km != NULL;
379*08855964SRyan Zezeski 	    km = list_next(&ktest_modules, km)) {
380*08855964SRyan Zezeski 		if (strncmp(km->km_name, module, KTEST_MAX_NAME_LEN) == 0) {
381*08855964SRyan Zezeski 			return (km);
382*08855964SRyan Zezeski 		}
383*08855964SRyan Zezeski 	}
384*08855964SRyan Zezeski 
385*08855964SRyan Zezeski 	return (NULL);
386*08855964SRyan Zezeski }
387*08855964SRyan Zezeski 
388*08855964SRyan Zezeski static ktest_suite_t *
ktest_find_suite(ktest_module_t * km,const char * suite)389*08855964SRyan Zezeski ktest_find_suite(ktest_module_t *km, const char *suite)
390*08855964SRyan Zezeski {
391*08855964SRyan Zezeski 	ktest_suite_t *ks = NULL;
392*08855964SRyan Zezeski 
393*08855964SRyan Zezeski 	for (ks = list_head(&km->km_suites); ks != NULL;
394*08855964SRyan Zezeski 	    ks = list_next(&km->km_suites, ks)) {
395*08855964SRyan Zezeski 		if (strncmp(ks->ks_name, suite, KTEST_MAX_NAME_LEN) == 0) {
396*08855964SRyan Zezeski 			return (ks);
397*08855964SRyan Zezeski 		}
398*08855964SRyan Zezeski 	}
399*08855964SRyan Zezeski 
400*08855964SRyan Zezeski 	return (NULL);
401*08855964SRyan Zezeski }
402*08855964SRyan Zezeski 
403*08855964SRyan Zezeski static ktest_test_t *
ktest_find_test(ktest_suite_t * ks,const char * test)404*08855964SRyan Zezeski ktest_find_test(ktest_suite_t *ks, const char *test)
405*08855964SRyan Zezeski {
406*08855964SRyan Zezeski 	ktest_test_t *kt = NULL;
407*08855964SRyan Zezeski 
408*08855964SRyan Zezeski 	for (kt = list_head(&ks->ks_tests); kt != NULL;
409*08855964SRyan Zezeski 	    kt = list_next(&ks->ks_tests, kt)) {
410*08855964SRyan Zezeski 		if (strncmp(kt->kt_name, test, KTEST_MAX_NAME_LEN) == 0) {
411*08855964SRyan Zezeski 			return (kt);
412*08855964SRyan Zezeski 		}
413*08855964SRyan Zezeski 	}
414*08855964SRyan Zezeski 
415*08855964SRyan Zezeski 	return (NULL);
416*08855964SRyan Zezeski }
417*08855964SRyan Zezeski 
418*08855964SRyan Zezeski /*
419*08855964SRyan Zezeski  * Return a pointer to the test that matches the fully-qualified
420*08855964SRyan Zezeski  * triple. Return NULL if no match is found.
421*08855964SRyan Zezeski  */
422*08855964SRyan Zezeski static ktest_test_t *
ktest_get_test(const char * module,const char * suite,const char * test)423*08855964SRyan Zezeski ktest_get_test(const char *module, const char *suite, const char *test)
424*08855964SRyan Zezeski {
425*08855964SRyan Zezeski 	ktest_module_t *km = NULL;
426*08855964SRyan Zezeski 	ktest_suite_t *ks = NULL;
427*08855964SRyan Zezeski 
428*08855964SRyan Zezeski 	VERIFY(module != NULL);
429*08855964SRyan Zezeski 	VERIFY(suite != NULL);
430*08855964SRyan Zezeski 	VERIFY(test != NULL);
431*08855964SRyan Zezeski 	VERIFY(MUTEX_HELD(&ktest_lock));
432*08855964SRyan Zezeski 
433*08855964SRyan Zezeski 	if ((km = ktest_find_module(module)) == NULL) {
434*08855964SRyan Zezeski 		return (NULL);
435*08855964SRyan Zezeski 	}
436*08855964SRyan Zezeski 
437*08855964SRyan Zezeski 	if ((ks = ktest_find_suite(km, suite)) == NULL) {
438*08855964SRyan Zezeski 		return (NULL);
439*08855964SRyan Zezeski 	}
440*08855964SRyan Zezeski 
441*08855964SRyan Zezeski 	return (ktest_find_test(ks, test));
442*08855964SRyan Zezeski }
443*08855964SRyan Zezeski 
444*08855964SRyan Zezeski /*
445*08855964SRyan Zezeski  * Create a new test module object named 'name'. The test module name
446*08855964SRyan Zezeski  * may be the same as the module-under-test, but this isn't required.
447*08855964SRyan Zezeski  *
448*08855964SRyan Zezeski  * Zero indicates success and a handle to the module object is
449*08855964SRyan Zezeski  * returned via 'km_hdl'.
450*08855964SRyan Zezeski  *
451*08855964SRyan Zezeski  * See ktest_create_module(9F).
452*08855964SRyan Zezeski  */
453*08855964SRyan Zezeski int
ktest_create_module(const char * name,ktest_module_hdl_t ** km_hdl)454*08855964SRyan Zezeski ktest_create_module(const char *name, ktest_module_hdl_t **km_hdl)
455*08855964SRyan Zezeski {
456*08855964SRyan Zezeski 	int ret = 0;
457*08855964SRyan Zezeski 	ktest_module_t *km = NULL;
458*08855964SRyan Zezeski 
459*08855964SRyan Zezeski 	if ((ret = ktest_valid_name(name)) != 0) {
460*08855964SRyan Zezeski 		return (ret);
461*08855964SRyan Zezeski 	}
462*08855964SRyan Zezeski 
463*08855964SRyan Zezeski 	if ((km = kmem_zalloc(sizeof (*km), KM_NOSLEEP)) == NULL) {
464*08855964SRyan Zezeski 		return (ENOMEM);
465*08855964SRyan Zezeski 	}
466*08855964SRyan Zezeski 
467*08855964SRyan Zezeski 	list_create(&km->km_suites, sizeof (ktest_suite_t),
468*08855964SRyan Zezeski 	    offsetof(ktest_suite_t, ks_node));
469*08855964SRyan Zezeski 	/* The length was already checked by ktest_valid_name(). */
470*08855964SRyan Zezeski 	(void) strlcpy(km->km_name, name, sizeof (km->km_name));
471*08855964SRyan Zezeski 	*km_hdl = (ktest_module_hdl_t *)km;
472*08855964SRyan Zezeski 	return (0);
473*08855964SRyan Zezeski }
474*08855964SRyan Zezeski 
475*08855964SRyan Zezeski /*
476*08855964SRyan Zezeski  * Create a new suite object named 'name' and add it to the module.
477*08855964SRyan Zezeski  *
478*08855964SRyan Zezeski  * Zero indicates success and a handle to the suite object is returned
479*08855964SRyan Zezeski  * via 'ks_hdl'.
480*08855964SRyan Zezeski  *
481*08855964SRyan Zezeski  * See ktest_add_suite(9F).
482*08855964SRyan Zezeski  */
483*08855964SRyan Zezeski int
ktest_add_suite(ktest_module_hdl_t * km_hdl,const char * name,ktest_suite_hdl_t ** ks_hdl)484*08855964SRyan Zezeski ktest_add_suite(ktest_module_hdl_t *km_hdl, const char *name,
485*08855964SRyan Zezeski     ktest_suite_hdl_t **ks_hdl)
486*08855964SRyan Zezeski {
487*08855964SRyan Zezeski 	int ret = 0;
488*08855964SRyan Zezeski 	ktest_module_t *km = (ktest_module_t *)km_hdl;
489*08855964SRyan Zezeski 	ktest_suite_t *ks = NULL;
490*08855964SRyan Zezeski 
491*08855964SRyan Zezeski 	if ((ret = ktest_valid_name(name)) != 0) {
492*08855964SRyan Zezeski 		return (ret);
493*08855964SRyan Zezeski 	}
494*08855964SRyan Zezeski 
495*08855964SRyan Zezeski 	if (ktest_find_suite(km, name) != NULL) {
496*08855964SRyan Zezeski 		return (EEXIST);
497*08855964SRyan Zezeski 	}
498*08855964SRyan Zezeski 
499*08855964SRyan Zezeski 	if ((ks = kmem_zalloc(sizeof (*ks), KM_NOSLEEP)) == NULL) {
500*08855964SRyan Zezeski 		return (ENOMEM);
501*08855964SRyan Zezeski 	}
502*08855964SRyan Zezeski 
503*08855964SRyan Zezeski 	list_create(&ks->ks_tests, sizeof (ktest_test_t),
504*08855964SRyan Zezeski 	    offsetof(ktest_test_t, kt_node));
505*08855964SRyan Zezeski 	/* The length was already checked by ktest_valid_name(). */
506*08855964SRyan Zezeski 	(void) strlcpy(ks->ks_name, name, sizeof (ks->ks_name));
507*08855964SRyan Zezeski 	ks->ks_module = km;
508*08855964SRyan Zezeski 	list_insert_tail(&km->km_suites, ks);
509*08855964SRyan Zezeski 	km->km_num_suites++;
510*08855964SRyan Zezeski 	km->km_num_tests += ks->ks_num_tests;
511*08855964SRyan Zezeski 	*ks_hdl = (ktest_suite_hdl_t *)ks;
512*08855964SRyan Zezeski 	return (0);
513*08855964SRyan Zezeski }
514*08855964SRyan Zezeski 
515*08855964SRyan Zezeski static int
ktest_create_test(ktest_test_t ** test_out,ktest_suite_t * ks,const char * name,ktest_fn_t fn,ktest_test_flags_t flags)516*08855964SRyan Zezeski ktest_create_test(ktest_test_t **test_out, ktest_suite_t *ks, const char *name,
517*08855964SRyan Zezeski     ktest_fn_t fn, ktest_test_flags_t flags)
518*08855964SRyan Zezeski {
519*08855964SRyan Zezeski 	int ret = 0;
520*08855964SRyan Zezeski 	ktest_test_t *kt = NULL;
521*08855964SRyan Zezeski 	boolean_t requires_input = B_FALSE;
522*08855964SRyan Zezeski 
523*08855964SRyan Zezeski 	if ((ret = ktest_valid_name(name)) != 0) {
524*08855964SRyan Zezeski 		return (ret);
525*08855964SRyan Zezeski 	}
526*08855964SRyan Zezeski 
527*08855964SRyan Zezeski 	if ((kt = kmem_zalloc(sizeof (*kt), KM_NOSLEEP)) == NULL) {
528*08855964SRyan Zezeski 		return (ENOMEM);
529*08855964SRyan Zezeski 	}
530*08855964SRyan Zezeski 
531*08855964SRyan Zezeski 	if ((flags & KTEST_FLAG_INPUT) != 0) {
532*08855964SRyan Zezeski 		requires_input = B_TRUE;
533*08855964SRyan Zezeski 	}
534*08855964SRyan Zezeski 
535*08855964SRyan Zezeski 	/* The length was already checked by ktest_valid_name(). */
536*08855964SRyan Zezeski 	(void) strlcpy(kt->kt_name, name, sizeof (kt->kt_name));
537*08855964SRyan Zezeski 	kt->kt_fn = fn;
538*08855964SRyan Zezeski 	kt->kt_suite = ks;
539*08855964SRyan Zezeski 	kt->kt_requires_input = requires_input;
540*08855964SRyan Zezeski 	*test_out = kt;
541*08855964SRyan Zezeski 	return (0);
542*08855964SRyan Zezeski }
543*08855964SRyan Zezeski 
544*08855964SRyan Zezeski /*
545*08855964SRyan Zezeski  * Add a test function to the suite specified by 'ks_hdl'. The test is
546*08855964SRyan Zezeski  * registered under the 'name' pseudonym and refers to the 'fn'
547*08855964SRyan Zezeski  * function. While the name is often the same as the function symbol,
548*08855964SRyan Zezeski  * this is merely a convention and not enforced. The 'flags' argument
549*08855964SRyan Zezeski  * may specify additional information about the function -- see the
550*08855964SRyan Zezeski  * ktest_test_flags_t definition.
551*08855964SRyan Zezeski  *
552*08855964SRyan Zezeski  * This function creates a new test object on the caller's behalf and
553*08855964SRyan Zezeski  * registers it with the specified suite. Zero indicates success.
554*08855964SRyan Zezeski  *
555*08855964SRyan Zezeski  * See ktest_add_test(9F).
556*08855964SRyan Zezeski  */
557*08855964SRyan Zezeski int
ktest_add_test(ktest_suite_hdl_t * ks_hdl,const char * name,ktest_fn_t fn,ktest_test_flags_t flags)558*08855964SRyan Zezeski ktest_add_test(ktest_suite_hdl_t *ks_hdl, const char *name, ktest_fn_t fn,
559*08855964SRyan Zezeski     ktest_test_flags_t flags)
560*08855964SRyan Zezeski {
561*08855964SRyan Zezeski 	ktest_suite_t *ks = (ktest_suite_t *)ks_hdl;
562*08855964SRyan Zezeski 	ktest_test_t *test;
563*08855964SRyan Zezeski 	int ret;
564*08855964SRyan Zezeski 
565*08855964SRyan Zezeski 	if (ktest_find_test(ks, name) != NULL) {
566*08855964SRyan Zezeski 		return (EEXIST);
567*08855964SRyan Zezeski 	}
568*08855964SRyan Zezeski 
569*08855964SRyan Zezeski 	if ((ret = ktest_create_test(&test, ks, name, fn, flags)) != 0) {
570*08855964SRyan Zezeski 		return (ret);
571*08855964SRyan Zezeski 	}
572*08855964SRyan Zezeski 
573*08855964SRyan Zezeski 	list_insert_tail(&ks->ks_tests, test);
574*08855964SRyan Zezeski 	ks->ks_num_tests++;
575*08855964SRyan Zezeski 	return (0);
576*08855964SRyan Zezeski }
577*08855964SRyan Zezeski 
578*08855964SRyan Zezeski /*
579*08855964SRyan Zezeski  * Register the test module specified by 'km_hdl' with the ktest
580*08855964SRyan Zezeski  * facility.
581*08855964SRyan Zezeski  *
582*08855964SRyan Zezeski  * See ktest_register_module(9F).
583*08855964SRyan Zezeski  */
584*08855964SRyan Zezeski int
ktest_register_module(ktest_module_hdl_t * km_hdl)585*08855964SRyan Zezeski ktest_register_module(ktest_module_hdl_t *km_hdl)
586*08855964SRyan Zezeski {
587*08855964SRyan Zezeski 	ktest_module_t *km = (ktest_module_t *)km_hdl;
588*08855964SRyan Zezeski 
589*08855964SRyan Zezeski 	mutex_enter(&ktest_lock);
590*08855964SRyan Zezeski 
591*08855964SRyan Zezeski 	if (ktest_find_module(km->km_name) != NULL) {
592*08855964SRyan Zezeski 		mutex_exit(&ktest_lock);
593*08855964SRyan Zezeski 		cmn_err(CE_NOTE, "test module already exists: %s", km->km_name);
594*08855964SRyan Zezeski 		return (EEXIST);
595*08855964SRyan Zezeski 	}
596*08855964SRyan Zezeski 
597*08855964SRyan Zezeski 	list_insert_tail(&ktest_modules, km);
598*08855964SRyan Zezeski 	mutex_exit(&ktest_lock);
599*08855964SRyan Zezeski 	return (0);
600*08855964SRyan Zezeski }
601*08855964SRyan Zezeski 
602*08855964SRyan Zezeski static void
ktest_free_test(ktest_test_t * test)603*08855964SRyan Zezeski ktest_free_test(ktest_test_t *test)
604*08855964SRyan Zezeski {
605*08855964SRyan Zezeski 	kmem_free(test, sizeof (*test));
606*08855964SRyan Zezeski }
607*08855964SRyan Zezeski 
608*08855964SRyan Zezeski static void
ktest_free_suite(ktest_suite_t * ks)609*08855964SRyan Zezeski ktest_free_suite(ktest_suite_t *ks)
610*08855964SRyan Zezeski {
611*08855964SRyan Zezeski 	ktest_test_t *kt = NULL;
612*08855964SRyan Zezeski 
613*08855964SRyan Zezeski 	while ((kt = list_remove_head(&ks->ks_tests)) != NULL) {
614*08855964SRyan Zezeski 		ktest_free_test(kt);
615*08855964SRyan Zezeski 	}
616*08855964SRyan Zezeski 
617*08855964SRyan Zezeski 	list_destroy(&ks->ks_tests);
618*08855964SRyan Zezeski 	kmem_free(ks, sizeof (*ks));
619*08855964SRyan Zezeski }
620*08855964SRyan Zezeski 
621*08855964SRyan Zezeski void
ktest_free_module(ktest_module_hdl_t * km_hdl)622*08855964SRyan Zezeski ktest_free_module(ktest_module_hdl_t *km_hdl)
623*08855964SRyan Zezeski {
624*08855964SRyan Zezeski 	ktest_module_t *km = (ktest_module_t *)km_hdl;
625*08855964SRyan Zezeski 	ktest_suite_t *ks = NULL;
626*08855964SRyan Zezeski 
627*08855964SRyan Zezeski 	while ((ks = list_remove_head(&km->km_suites)) != NULL) {
628*08855964SRyan Zezeski 		ktest_free_suite(ks);
629*08855964SRyan Zezeski 	}
630*08855964SRyan Zezeski 
631*08855964SRyan Zezeski 	list_destroy(&km->km_suites);
632*08855964SRyan Zezeski 	kmem_free(km, sizeof (*km));
633*08855964SRyan Zezeski }
634*08855964SRyan Zezeski 
635*08855964SRyan Zezeski /*
636*08855964SRyan Zezeski  * Unregister the test module named by 'name'. This walks all suites
637*08855964SRyan Zezeski  * and tests registered under this module, removing them and freeing
638*08855964SRyan Zezeski  * their resources.
639*08855964SRyan Zezeski  *
640*08855964SRyan Zezeski  * See ktest_unregister_module(9F).
641*08855964SRyan Zezeski  */
642*08855964SRyan Zezeski void
ktest_unregister_module(const char * name)643*08855964SRyan Zezeski ktest_unregister_module(const char *name)
644*08855964SRyan Zezeski {
645*08855964SRyan Zezeski 	mutex_enter(&ktest_lock);
646*08855964SRyan Zezeski 
647*08855964SRyan Zezeski 	for (ktest_module_t *km = list_head(&ktest_modules);
648*08855964SRyan Zezeski 	    km != NULL;
649*08855964SRyan Zezeski 	    km = list_next(&ktest_modules, km)) {
650*08855964SRyan Zezeski 		if (strncmp(name, km->km_name, KTEST_MAX_NAME_LEN) == 0) {
651*08855964SRyan Zezeski 			list_remove(&ktest_modules, km);
652*08855964SRyan Zezeski 			ktest_free_module((ktest_module_hdl_t *)km);
653*08855964SRyan Zezeski 			break;
654*08855964SRyan Zezeski 		}
655*08855964SRyan Zezeski 	}
656*08855964SRyan Zezeski 
657*08855964SRyan Zezeski 	mutex_exit(&ktest_lock);
658*08855964SRyan Zezeski }
659*08855964SRyan Zezeski 
660*08855964SRyan Zezeski static void
ktest_unregister_all()661*08855964SRyan Zezeski ktest_unregister_all()
662*08855964SRyan Zezeski {
663*08855964SRyan Zezeski 	ktest_module_t *km;
664*08855964SRyan Zezeski 	mutex_enter(&ktest_lock);
665*08855964SRyan Zezeski 
666*08855964SRyan Zezeski 	while ((km = list_remove_head(&ktest_modules)) != NULL) {
667*08855964SRyan Zezeski 		ktest_free_module((ktest_module_hdl_t *)km);
668*08855964SRyan Zezeski 	}
669*08855964SRyan Zezeski 
670*08855964SRyan Zezeski 	mutex_exit(&ktest_lock);
671*08855964SRyan Zezeski }
672*08855964SRyan Zezeski 
673*08855964SRyan Zezeski /*
674*08855964SRyan Zezeski  * Get a function pointer to the function with symbol 'fn_name'. This
675*08855964SRyan Zezeski  * function must be a symbol in the module referenced by 'hdl',
676*08855964SRyan Zezeski  * otherwise an error is returned. It's up to the caller to make sure
677*08855964SRyan Zezeski  * that the 'fn' pointer is declared correctly.
678*08855964SRyan Zezeski  *
679*08855964SRyan Zezeski  * Zero indicates success.
680*08855964SRyan Zezeski  *
681*08855964SRyan Zezeski  * See ktest_get_fn(9F).
682*08855964SRyan Zezeski  */
683*08855964SRyan Zezeski int
ktest_get_fn(ddi_modhandle_t hdl,const char * fn_name,void ** fn)684*08855964SRyan Zezeski ktest_get_fn(ddi_modhandle_t hdl, const char *fn_name, void **fn)
685*08855964SRyan Zezeski {
686*08855964SRyan Zezeski 	int err;
687*08855964SRyan Zezeski 
688*08855964SRyan Zezeski 	if ((*fn = ddi_modsym(hdl, fn_name, &err)) == NULL) {
689*08855964SRyan Zezeski 		return (err);
690*08855964SRyan Zezeski 	}
691*08855964SRyan Zezeski 
692*08855964SRyan Zezeski 	return (0);
693*08855964SRyan Zezeski }
694*08855964SRyan Zezeski 
695*08855964SRyan Zezeski /*
696*08855964SRyan Zezeski  * Get the input stream from the context handle. The contract for this
697*08855964SRyan Zezeski  * API guarantees that if it is called, then there MUST be an input
698*08855964SRyan Zezeski  * stream. It does this by VERIFYing that a) the test's
699*08855964SRyan Zezeski  * 'kt_requires_input' flag is set, and b) that the 'ktc_input' is
700*08855964SRyan Zezeski  * non-NULL. This means that failure to set an input stream on a test
701*08855964SRyan Zezeski  * which requires it will result in a kernel panic. That may seem
702*08855964SRyan Zezeski  * extreme, however, consider that this is meant to be discovered
703*08855964SRyan Zezeski  * during development, and that the ktest cmd also takes steps to
704*08855964SRyan Zezeski  * ensure that any test which requires input has an input stream
705*08855964SRyan Zezeski  * specified. The impetus for this contract is to avoid checking for
706*08855964SRyan Zezeski  * valid input in every test -- it allows the test to assume the input
707*08855964SRyan Zezeski  * is there and categorically catch any case where it is not.
708*08855964SRyan Zezeski  *
709*08855964SRyan Zezeski  * This contract does not preclude the possibility of a 0-byte stream,
710*08855964SRyan Zezeski  * which may be a valid test case for some tests. It only precludes a
711*08855964SRyan Zezeski  * non-existent stream.
712*08855964SRyan Zezeski  *
713*08855964SRyan Zezeski  * See ktest_get_input(9F).
714*08855964SRyan Zezeski  */
715*08855964SRyan Zezeski void
ktest_get_input(const ktest_ctx_hdl_t * hdl,uchar_t ** input,size_t * len)716*08855964SRyan Zezeski ktest_get_input(const ktest_ctx_hdl_t *hdl, uchar_t **input, size_t *len)
717*08855964SRyan Zezeski {
718*08855964SRyan Zezeski 	ktest_ctx_t *ctx = (ktest_ctx_t *)hdl;
719*08855964SRyan Zezeski 	VERIFY(ctx->ktc_test->kt_requires_input == B_TRUE);
720*08855964SRyan Zezeski 	VERIFY3P(ctx->ktc_input, !=, NULL);
721*08855964SRyan Zezeski 	*len = ctx->ktc_input_len;
722*08855964SRyan Zezeski 	*input = ctx->ktc_input;
723*08855964SRyan Zezeski }
724*08855964SRyan Zezeski 
725*08855964SRyan Zezeski /*
726*08855964SRyan Zezeski  * Grab a hold on 'module' and return it in 'hdl'. Meant to be used
727*08855964SRyan Zezeski  * with ktest_get_fn(). Zero indicates success.
728*08855964SRyan Zezeski  *
729*08855964SRyan Zezeski  * Remember, 'ddi_modhandle_t' is a pointer, so 'hdl' is pointer to
730*08855964SRyan Zezeski  * pointer.
731*08855964SRyan Zezeski  *
732*08855964SRyan Zezeski  * See ktest_hold_mod(9F).
733*08855964SRyan Zezeski  */
734*08855964SRyan Zezeski int
ktest_hold_mod(const char * module,ddi_modhandle_t * hdl)735*08855964SRyan Zezeski ktest_hold_mod(const char *module, ddi_modhandle_t *hdl)
736*08855964SRyan Zezeski {
737*08855964SRyan Zezeski 	int err;
738*08855964SRyan Zezeski 
739*08855964SRyan Zezeski 	if ((*hdl = ddi_modopen(module, KRTLD_MODE_FIRST, &err)) == NULL) {
740*08855964SRyan Zezeski 		return (err);
741*08855964SRyan Zezeski 	}
742*08855964SRyan Zezeski 
743*08855964SRyan Zezeski 	return (0);
744*08855964SRyan Zezeski }
745*08855964SRyan Zezeski 
746*08855964SRyan Zezeski /*
747*08855964SRyan Zezeski  * The opposite of ktest_hold_mod().
748*08855964SRyan Zezeski  *
749*08855964SRyan Zezeski  * See ktest_release_mod(9F).
750*08855964SRyan Zezeski  */
751*08855964SRyan Zezeski void
ktest_release_mod(ddi_modhandle_t hdl)752*08855964SRyan Zezeski ktest_release_mod(ddi_modhandle_t hdl)
753*08855964SRyan Zezeski {
754*08855964SRyan Zezeski 	(void) ddi_modclose(hdl);
755*08855964SRyan Zezeski }
756*08855964SRyan Zezeski 
757*08855964SRyan Zezeski /*
758*08855964SRyan Zezeski  * Check if the result is already set. Setting the result more than
759*08855964SRyan Zezeski  * once is a bug in the test. This check catches the bug and produces
760*08855964SRyan Zezeski  * an error result with a message indicating the line number of the
761*08855964SRyan Zezeski  * original result which was overwritten. It replaces 'ktc_res_line'
762*08855964SRyan Zezeski  * with the line number of the overwriting result.
763*08855964SRyan Zezeski  *
764*08855964SRyan Zezeski  * Return true when an existing result was found.
765*08855964SRyan Zezeski  */
766*08855964SRyan Zezeski static boolean_t
ktest_result_check(ktest_ctx_t * ctx,int line)767*08855964SRyan Zezeski ktest_result_check(ktest_ctx_t *ctx, int line)
768*08855964SRyan Zezeski {
769*08855964SRyan Zezeski 	if (ctx->ktc_res->kr_type != KTEST_RESULT_NONE) {
770*08855964SRyan Zezeski 		char *msg = ctx->ktc_res->kr_msg;
771*08855964SRyan Zezeski 		int first_line = ctx->ktc_res->kr_line;
772*08855964SRyan Zezeski 
773*08855964SRyan Zezeski 		ctx->ktc_res->kr_type = KTEST_RESULT_ERROR;
774*08855964SRyan Zezeski 		ctx->ktc_res->kr_line = line;
775*08855964SRyan Zezeski 
776*08855964SRyan Zezeski 		/* We know the string is within max length. */
777*08855964SRyan Zezeski 		(void) snprintf(msg, KTEST_MAX_LOG_LEN, "multiple results: "
778*08855964SRyan Zezeski 		    "prev result at line %d", first_line);
779*08855964SRyan Zezeski 
780*08855964SRyan Zezeski 		return (B_TRUE);
781*08855964SRyan Zezeski 	}
782*08855964SRyan Zezeski 
783*08855964SRyan Zezeski 	return (B_FALSE);
784*08855964SRyan Zezeski }
785*08855964SRyan Zezeski 
786*08855964SRyan Zezeski /*
787*08855964SRyan Zezeski  * Set result if and only if one has not already been set. Return true
788*08855964SRyan Zezeski  * if the result was set. Return false if it was already set.
789*08855964SRyan Zezeski  */
790*08855964SRyan Zezeski static boolean_t
ktest_set_result(ktest_ctx_hdl_t * hdl,ktest_result_type_t rt,int line)791*08855964SRyan Zezeski ktest_set_result(ktest_ctx_hdl_t *hdl, ktest_result_type_t rt, int line)
792*08855964SRyan Zezeski {
793*08855964SRyan Zezeski 	ktest_ctx_t *ctx = (ktest_ctx_t *)hdl;
794*08855964SRyan Zezeski 
795*08855964SRyan Zezeski 	/* Overwriting a previous result is not allowed. */
796*08855964SRyan Zezeski 	if (ktest_result_check(ctx, line)) {
797*08855964SRyan Zezeski 		return (B_FALSE);
798*08855964SRyan Zezeski 	}
799*08855964SRyan Zezeski 
800*08855964SRyan Zezeski 	ctx->ktc_res->kr_type = rt;
801*08855964SRyan Zezeski 	ctx->ktc_res->kr_line = line;
802*08855964SRyan Zezeski 	return (B_TRUE);
803*08855964SRyan Zezeski }
804*08855964SRyan Zezeski 
805*08855964SRyan Zezeski static void
ktest_set_msg(ktest_ctx_hdl_t * hdl,const char * format,va_list args)806*08855964SRyan Zezeski ktest_set_msg(ktest_ctx_hdl_t *hdl, const char *format, va_list args)
807*08855964SRyan Zezeski {
808*08855964SRyan Zezeski 	ktest_ctx_t *ctx = (ktest_ctx_t *)hdl;
809*08855964SRyan Zezeski 	char *msg = ctx->ktc_res->kr_msg;
810*08855964SRyan Zezeski 	size_t written = 0;
811*08855964SRyan Zezeski 
812*08855964SRyan Zezeski 	written = vsnprintf(msg, KTEST_MAX_LOG_LEN, format, args);
813*08855964SRyan Zezeski 
814*08855964SRyan Zezeski 	/* Subtract one to account for the implicit NULL byte. */
815*08855964SRyan Zezeski 	if (written > (KTEST_MAX_LOG_LEN - 1)) {
816*08855964SRyan Zezeski 		const ktest_test_t *test = ctx->ktc_test;
817*08855964SRyan Zezeski 		ktest_suite_t *suite = test->kt_suite;
818*08855964SRyan Zezeski 		ktest_module_t *mod = suite->ks_module;
819*08855964SRyan Zezeski 
820*08855964SRyan Zezeski 		cmn_err(CE_NOTE, "result message truncated: %s:%s:%s [%d]",
821*08855964SRyan Zezeski 		    mod->km_name, suite->ks_name, test->kt_name,
822*08855964SRyan Zezeski 		    ctx->ktc_res->kr_line);
823*08855964SRyan Zezeski 	}
824*08855964SRyan Zezeski }
825*08855964SRyan Zezeski 
826*08855964SRyan Zezeski void
ktest_result_skip(ktest_ctx_hdl_t * hdl,int line,const char * format,...)827*08855964SRyan Zezeski ktest_result_skip(ktest_ctx_hdl_t *hdl, int line, const char *format, ...)
828*08855964SRyan Zezeski {
829*08855964SRyan Zezeski 	if (ktest_set_result(hdl, KTEST_RESULT_SKIP, line)) {
830*08855964SRyan Zezeski 		va_list adx;
831*08855964SRyan Zezeski 
832*08855964SRyan Zezeski 		va_start(adx, format);
833*08855964SRyan Zezeski 		ktest_set_msg(hdl, format, adx);
834*08855964SRyan Zezeski 		va_end(adx);
835*08855964SRyan Zezeski 	}
836*08855964SRyan Zezeski }
837*08855964SRyan Zezeski 
838*08855964SRyan Zezeski void
ktest_result_fail(ktest_ctx_hdl_t * hdl,int line,const char * format,...)839*08855964SRyan Zezeski ktest_result_fail(ktest_ctx_hdl_t *hdl, int line, const char *format, ...)
840*08855964SRyan Zezeski {
841*08855964SRyan Zezeski 	if (ktest_set_result(hdl, KTEST_RESULT_FAIL, line)) {
842*08855964SRyan Zezeski 		va_list adx;
843*08855964SRyan Zezeski 
844*08855964SRyan Zezeski 		va_start(adx, format);
845*08855964SRyan Zezeski 		ktest_set_msg(hdl, format, adx);
846*08855964SRyan Zezeski 		va_end(adx);
847*08855964SRyan Zezeski 	}
848*08855964SRyan Zezeski }
849*08855964SRyan Zezeski 
850*08855964SRyan Zezeski void
ktest_result_error(ktest_ctx_hdl_t * hdl,int line,const char * format,...)851*08855964SRyan Zezeski ktest_result_error(ktest_ctx_hdl_t *hdl, int line, const char *format, ...)
852*08855964SRyan Zezeski {
853*08855964SRyan Zezeski 	if (ktest_set_result(hdl, KTEST_RESULT_ERROR, line)) {
854*08855964SRyan Zezeski 		va_list adx;
855*08855964SRyan Zezeski 
856*08855964SRyan Zezeski 		va_start(adx, format);
857*08855964SRyan Zezeski 		ktest_set_msg(hdl, format, adx);
858*08855964SRyan Zezeski 		va_end(adx);
859*08855964SRyan Zezeski 	}
860*08855964SRyan Zezeski }
861*08855964SRyan Zezeski 
862*08855964SRyan Zezeski void
ktest_result_pass(ktest_ctx_hdl_t * hdl,int line)863*08855964SRyan Zezeski ktest_result_pass(ktest_ctx_hdl_t *hdl, int line)
864*08855964SRyan Zezeski {
865*08855964SRyan Zezeski 	(void) ktest_set_result(hdl, KTEST_RESULT_PASS, line);
866*08855964SRyan Zezeski }
867*08855964SRyan Zezeski 
868*08855964SRyan Zezeski /*
869*08855964SRyan Zezeski  * Clear the prepend message, undoing any message set by ktest_msg_prepend().
870*08855964SRyan Zezeski  *
871*08855964SRyan Zezeski  * See ktest_msg_clear(9F).
872*08855964SRyan Zezeski  */
873*08855964SRyan Zezeski void
ktest_msg_clear(ktest_ctx_hdl_t * hdl)874*08855964SRyan Zezeski ktest_msg_clear(ktest_ctx_hdl_t *hdl)
875*08855964SRyan Zezeski {
876*08855964SRyan Zezeski 	ktest_ctx_t *ctx = (ktest_ctx_t *)hdl;
877*08855964SRyan Zezeski 	ctx->ktc_res->kr_msg_prepend[0] = '\0';
878*08855964SRyan Zezeski }
879*08855964SRyan Zezeski 
880*08855964SRyan Zezeski /*
881*08855964SRyan Zezeski  * Prepend formatted text to the result message. This is useful in
882*08855964SRyan Zezeski  * cases where the KT_ASSERT macro's generated message doesn't convey
883*08855964SRyan Zezeski  * enough context to determine the precise cause of the failure. By
884*08855964SRyan Zezeski  * prepending the formatted text you can add additional context while
885*08855964SRyan Zezeski  * still using the KT_ASSERT macros (and not having to reimplement
886*08855964SRyan Zezeski  * them yourself). This overwrites any existing prepend text.
887*08855964SRyan Zezeski  *
888*08855964SRyan Zezeski  * See ktest_msg_prepend(9F).
889*08855964SRyan Zezeski  */
890*08855964SRyan Zezeski void
ktest_msg_prepend(ktest_ctx_hdl_t * hdl,const char * format,...)891*08855964SRyan Zezeski ktest_msg_prepend(ktest_ctx_hdl_t *hdl, const char *format, ...)
892*08855964SRyan Zezeski {
893*08855964SRyan Zezeski 	ktest_ctx_t *ctx = (ktest_ctx_t *)hdl;
894*08855964SRyan Zezeski 	char *msg = ctx->ktc_res->kr_msg_prepend;
895*08855964SRyan Zezeski 	size_t written;
896*08855964SRyan Zezeski 	va_list adx;
897*08855964SRyan Zezeski 
898*08855964SRyan Zezeski 	va_start(adx, format);
899*08855964SRyan Zezeski 	written = vsnprintf(msg, KTEST_MAX_LOG_LEN, format, adx);
900*08855964SRyan Zezeski 	/* Subtract one to account for the implicit NULL byte. */
901*08855964SRyan Zezeski 	if (written > (KTEST_MAX_LOG_LEN - 1)) {
902*08855964SRyan Zezeski 		const ktest_test_t *test = ctx->ktc_test;
903*08855964SRyan Zezeski 		ktest_suite_t *suite = test->kt_suite;
904*08855964SRyan Zezeski 		ktest_module_t *mod = suite->ks_module;
905*08855964SRyan Zezeski 
906*08855964SRyan Zezeski 		cmn_err(CE_NOTE, "prepend message truncated: %s:%s:%s",
907*08855964SRyan Zezeski 		    mod->km_name, suite->ks_name, test->kt_name);
908*08855964SRyan Zezeski 	}
909*08855964SRyan Zezeski 	va_end(adx);
910*08855964SRyan Zezeski }
911*08855964SRyan Zezeski 
912*08855964SRyan Zezeski /*
913*08855964SRyan Zezeski  * Each `{:}` represents an nvpair, each `[,]` represents an nvlist.
914*08855964SRyan Zezeski  *
915*08855964SRyan Zezeski  * Test nvlist
916*08855964SRyan Zezeski  * -----------
917*08855964SRyan Zezeski  *
918*08855964SRyan Zezeski  * [{"name":"<test_name>"},
919*08855964SRyan Zezeski  *  {"input_required":boolean_t}]
920*08855964SRyan Zezeski  *
921*08855964SRyan Zezeski  * Tests nvlist
922*08855964SRyan Zezeski  * ------------
923*08855964SRyan Zezeski  *
924*08855964SRyan Zezeski  * [{"test1":<test1_nvlist>},
925*08855964SRyan Zezeski  *  {"test2":<test2_nvlist>"},
926*08855964SRyan Zezeski  *  ...]
927*08855964SRyan Zezeski  *
928*08855964SRyan Zezeski  * Suite nvlist
929*08855964SRyan Zezeski  * ------------
930*08855964SRyan Zezeski  *
931*08855964SRyan Zezeski  * [{"name":"<ks->ks_name>"},
932*08855964SRyan Zezeski  *  {"tests":<tests_nvlist>}]
933*08855964SRyan Zezeski  *
934*08855964SRyan Zezeski  * Suites nvlist
935*08855964SRyan Zezeski  * -------------
936*08855964SRyan Zezeski  *
937*08855964SRyan Zezeski  * [{"suite1":<suite1_nvlist>},
938*08855964SRyan Zezeski  *  {"suite2":<suite2_nvlist>},
939*08855964SRyan Zezeski  *  ...]
940*08855964SRyan Zezeski  *
941*08855964SRyan Zezeski  * Module nvlist
942*08855964SRyan Zezeski  * -------------
943*08855964SRyan Zezeski  *
944*08855964SRyan Zezeski  * [{"name":"<km->km_name>"},
945*08855964SRyan Zezeski  *  {"suites":<suites_nvlist>}]
946*08855964SRyan Zezeski  *
947*08855964SRyan Zezeski  * Modules nvlist
948*08855964SRyan Zezeski  * --------------
949*08855964SRyan Zezeski  *
950*08855964SRyan Zezeski  * [{"ser_fmt_version":1},
951*08855964SRyan Zezeski  *  {"module1":<module1_nvlist>},
952*08855964SRyan Zezeski  *  {"module2":<module2_nvlist>},
953*08855964SRyan Zezeski  *  ...]
954*08855964SRyan Zezeski  *
955*08855964SRyan Zezeski  */
956*08855964SRyan Zezeski int
ktest_list_tests(ktest_list_op_t * klo,int mode)957*08855964SRyan Zezeski ktest_list_tests(ktest_list_op_t *klo, int mode)
958*08855964SRyan Zezeski {
959*08855964SRyan Zezeski 	nvlist_t *modules = fnvlist_alloc();
960*08855964SRyan Zezeski 	char *buf = NULL;
961*08855964SRyan Zezeski 	size_t len = 0;
962*08855964SRyan Zezeski 	int ret = 0;
963*08855964SRyan Zezeski 
964*08855964SRyan Zezeski 	/*
965*08855964SRyan Zezeski 	 * The first thing we add is a uint64_t ser_fmt_version field.
966*08855964SRyan Zezeski 	 * This field allows any consumer of this nvlist (namely the
967*08855964SRyan Zezeski 	 * ktest cmd) to know which serialization format it is in.
968*08855964SRyan Zezeski 	 * Specifically, the format version tells the consumer which
969*08855964SRyan Zezeski 	 * fields to expect and how they are laid out. Given that the
970*08855964SRyan Zezeski 	 * ktest kernel facility and its user command are delivered in
971*08855964SRyan Zezeski 	 * gate, this should never be needed. However, including a
972*08855964SRyan Zezeski 	 * versioned format now keeps the future flexible, and costs
973*08855964SRyan Zezeski 	 * us little.
974*08855964SRyan Zezeski 	 */
975*08855964SRyan Zezeski 	fnvlist_add_uint64(modules, "ser_fmt_version", KTEST_SER_FMT_VSN);
976*08855964SRyan Zezeski 	mutex_enter(&ktest_lock);
977*08855964SRyan Zezeski 
978*08855964SRyan Zezeski 	for (ktest_module_t *km = list_head(&ktest_modules);
979*08855964SRyan Zezeski 	    km != NULL;
980*08855964SRyan Zezeski 	    km = list_next(&ktest_modules, km)) {
981*08855964SRyan Zezeski 		nvlist_t *module = fnvlist_alloc();
982*08855964SRyan Zezeski 		nvlist_t *suites = fnvlist_alloc();
983*08855964SRyan Zezeski 
984*08855964SRyan Zezeski 		for (ktest_suite_t *ks = list_head(&km->km_suites);
985*08855964SRyan Zezeski 		    ks != NULL;
986*08855964SRyan Zezeski 		    ks = list_next(&km->km_suites, ks)) {
987*08855964SRyan Zezeski 			nvlist_t *suite = fnvlist_alloc();
988*08855964SRyan Zezeski 			nvlist_t *tests = fnvlist_alloc();
989*08855964SRyan Zezeski 
990*08855964SRyan Zezeski 			for (ktest_test_t *kt = list_head(&ks->ks_tests);
991*08855964SRyan Zezeski 			    kt != NULL;
992*08855964SRyan Zezeski 			    kt = list_next(&ks->ks_tests, kt)) {
993*08855964SRyan Zezeski 				nvlist_t *test = fnvlist_alloc();
994*08855964SRyan Zezeski 
995*08855964SRyan Zezeski 				fnvlist_add_string(test, KTEST_NAME_KEY,
996*08855964SRyan Zezeski 				    kt->kt_name);
997*08855964SRyan Zezeski 				fnvlist_add_boolean_value(test,
998*08855964SRyan Zezeski 				    KTEST_TEST_INPUT_KEY,
999*08855964SRyan Zezeski 				    kt->kt_requires_input);
1000*08855964SRyan Zezeski 				fnvlist_add_nvlist(tests, kt->kt_name, test);
1001*08855964SRyan Zezeski 				nvlist_free(test);
1002*08855964SRyan Zezeski 			}
1003*08855964SRyan Zezeski 
1004*08855964SRyan Zezeski 			if (nvlist_empty(tests)) {
1005*08855964SRyan Zezeski 				nvlist_free(tests);
1006*08855964SRyan Zezeski 				nvlist_free(suite);
1007*08855964SRyan Zezeski 				continue;
1008*08855964SRyan Zezeski 			}
1009*08855964SRyan Zezeski 
1010*08855964SRyan Zezeski 			fnvlist_add_string(suite, KTEST_NAME_KEY, ks->ks_name);
1011*08855964SRyan Zezeski 			fnvlist_add_nvlist(suite, KTEST_SUITE_TESTS_KEY, tests);
1012*08855964SRyan Zezeski 			fnvlist_add_nvlist(suites, ks->ks_name, suite);
1013*08855964SRyan Zezeski 			nvlist_free(tests);
1014*08855964SRyan Zezeski 			nvlist_free(suite);
1015*08855964SRyan Zezeski 		}
1016*08855964SRyan Zezeski 
1017*08855964SRyan Zezeski 		if (nvlist_empty(suites)) {
1018*08855964SRyan Zezeski 			nvlist_free(suites);
1019*08855964SRyan Zezeski 			nvlist_free(module);
1020*08855964SRyan Zezeski 			continue;
1021*08855964SRyan Zezeski 		}
1022*08855964SRyan Zezeski 
1023*08855964SRyan Zezeski 		fnvlist_add_string(module, KTEST_NAME_KEY, km->km_name);
1024*08855964SRyan Zezeski 		fnvlist_add_nvlist(module, KTEST_MODULE_SUITES_KEY, suites);
1025*08855964SRyan Zezeski 		fnvlist_add_nvlist(modules, km->km_name, module);
1026*08855964SRyan Zezeski 		nvlist_free(suites);
1027*08855964SRyan Zezeski 		nvlist_free(module);
1028*08855964SRyan Zezeski 	}
1029*08855964SRyan Zezeski 
1030*08855964SRyan Zezeski 	mutex_exit(&ktest_lock);
1031*08855964SRyan Zezeski 	buf = fnvlist_pack(modules, &len);
1032*08855964SRyan Zezeski 
1033*08855964SRyan Zezeski 	/*
1034*08855964SRyan Zezeski 	 * The userspace response buffer is not large enough. Fill in
1035*08855964SRyan Zezeski 	 * the amount needed and return ENOBUFS so that the command
1036*08855964SRyan Zezeski 	 * may retry.
1037*08855964SRyan Zezeski 	 */
1038*08855964SRyan Zezeski 	if (klo->klo_resp_len < len) {
1039*08855964SRyan Zezeski 		klo->klo_resp_len = len;
1040*08855964SRyan Zezeski 		nvlist_free(modules);
1041*08855964SRyan Zezeski 		ret = ENOBUFS;
1042*08855964SRyan Zezeski 		goto out;
1043*08855964SRyan Zezeski 	}
1044*08855964SRyan Zezeski 
1045*08855964SRyan Zezeski 	klo->klo_resp_len = len;
1046*08855964SRyan Zezeski 
1047*08855964SRyan Zezeski 	if (ddi_copyout(buf, klo->klo_resp, len, mode) != 0) {
1048*08855964SRyan Zezeski 		ret = EFAULT;
1049*08855964SRyan Zezeski 		goto out;
1050*08855964SRyan Zezeski 	}
1051*08855964SRyan Zezeski 
1052*08855964SRyan Zezeski out:
1053*08855964SRyan Zezeski 	nvlist_free(modules);
1054*08855964SRyan Zezeski 	kmem_free(buf, len);
1055*08855964SRyan Zezeski 	return (ret);
1056*08855964SRyan Zezeski }
1057*08855964SRyan Zezeski 
1058*08855964SRyan Zezeski static void
ktest_run_test(const ktest_test_t * kt,uchar_t * input,uint64_t input_len,ktest_result_t * res)1059*08855964SRyan Zezeski ktest_run_test(const ktest_test_t *kt, uchar_t *input, uint64_t input_len,
1060*08855964SRyan Zezeski     ktest_result_t *res)
1061*08855964SRyan Zezeski {
1062*08855964SRyan Zezeski 	ktest_ctx_t ctx;
1063*08855964SRyan Zezeski 
1064*08855964SRyan Zezeski 	bzero(&ctx, sizeof (ctx));
1065*08855964SRyan Zezeski 	res->kr_type = KTEST_RESULT_NONE;
1066*08855964SRyan Zezeski 	ctx.ktc_test = kt;
1067*08855964SRyan Zezeski 	ctx.ktc_res = res;
1068*08855964SRyan Zezeski 	ctx.ktc_input = input;
1069*08855964SRyan Zezeski 	ctx.ktc_input_len = input_len;
1070*08855964SRyan Zezeski 	kt->kt_fn((ktest_ctx_hdl_t *)&ctx);
1071*08855964SRyan Zezeski }
1072*08855964SRyan Zezeski 
1073*08855964SRyan Zezeski static int
ktest_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** resultp)1074*08855964SRyan Zezeski ktest_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
1075*08855964SRyan Zezeski {
1076*08855964SRyan Zezeski 	switch (cmd) {
1077*08855964SRyan Zezeski 	case DDI_INFO_DEVT2DEVINFO:
1078*08855964SRyan Zezeski 		*resultp = ktest_dip;
1079*08855964SRyan Zezeski 		break;
1080*08855964SRyan Zezeski 	case DDI_INFO_DEVT2INSTANCE:
1081*08855964SRyan Zezeski 		*resultp = (void *)0;
1082*08855964SRyan Zezeski 		break;
1083*08855964SRyan Zezeski 	default:
1084*08855964SRyan Zezeski 		return (DDI_FAILURE);
1085*08855964SRyan Zezeski 	}
1086*08855964SRyan Zezeski 
1087*08855964SRyan Zezeski 	return (DDI_SUCCESS);
1088*08855964SRyan Zezeski }
1089*08855964SRyan Zezeski 
1090*08855964SRyan Zezeski static int
ktest_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)1091*08855964SRyan Zezeski ktest_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1092*08855964SRyan Zezeski {
1093*08855964SRyan Zezeski 	if (cmd != DDI_ATTACH) {
1094*08855964SRyan Zezeski 		return (DDI_FAILURE);
1095*08855964SRyan Zezeski 	}
1096*08855964SRyan Zezeski 
1097*08855964SRyan Zezeski 	if (ddi_create_minor_node(dip, "ktest", S_IFCHR, KTEST_CTL_MINOR,
1098*08855964SRyan Zezeski 	    DDI_PSEUDO, 0) != DDI_SUCCESS) {
1099*08855964SRyan Zezeski 		return (DDI_FAILURE);
1100*08855964SRyan Zezeski 	}
1101*08855964SRyan Zezeski 
1102*08855964SRyan Zezeski 	ktest_dip = dip;
1103*08855964SRyan Zezeski 	ddi_report_dev(dip);
1104*08855964SRyan Zezeski 	return (DDI_SUCCESS);
1105*08855964SRyan Zezeski }
1106*08855964SRyan Zezeski 
1107*08855964SRyan Zezeski static int
ktest_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)1108*08855964SRyan Zezeski ktest_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1109*08855964SRyan Zezeski {
1110*08855964SRyan Zezeski 	if (cmd != DDI_DETACH) {
1111*08855964SRyan Zezeski 		return (DDI_FAILURE);
1112*08855964SRyan Zezeski 	}
1113*08855964SRyan Zezeski 
1114*08855964SRyan Zezeski 	ddi_remove_minor_node(dip, NULL);
1115*08855964SRyan Zezeski 	ktest_dip = NULL;
1116*08855964SRyan Zezeski 	return (DDI_SUCCESS);
1117*08855964SRyan Zezeski }
1118*08855964SRyan Zezeski 
1119*08855964SRyan Zezeski static int
ktest_open(dev_t * devp,int flag,int otype,cred_t * credp)1120*08855964SRyan Zezeski ktest_open(dev_t *devp, int flag, int otype, cred_t *credp)
1121*08855964SRyan Zezeski {
1122*08855964SRyan Zezeski 	if (otype != OTYP_CHR) {
1123*08855964SRyan Zezeski 		return (EINVAL);
1124*08855964SRyan Zezeski 	}
1125*08855964SRyan Zezeski 
1126*08855964SRyan Zezeski 	/* Make sure attach(9E) has completed. */
1127*08855964SRyan Zezeski 	if (ktest_dip == NULL) {
1128*08855964SRyan Zezeski 		return (ENXIO);
1129*08855964SRyan Zezeski 	}
1130*08855964SRyan Zezeski 
1131*08855964SRyan Zezeski 	if (getminor(*devp) != KTEST_CTL_MINOR) {
1132*08855964SRyan Zezeski 		return (ENXIO);
1133*08855964SRyan Zezeski 	}
1134*08855964SRyan Zezeski 
1135*08855964SRyan Zezeski 	if (flag & FWRITE) {
1136*08855964SRyan Zezeski 		return (EACCES);
1137*08855964SRyan Zezeski 	}
1138*08855964SRyan Zezeski 
1139*08855964SRyan Zezeski 	if (flag & FEXCL) {
1140*08855964SRyan Zezeski 		return (ENOTSUP);
1141*08855964SRyan Zezeski 	}
1142*08855964SRyan Zezeski 
1143*08855964SRyan Zezeski 	/*
1144*08855964SRyan Zezeski 	 * Access to the ktest facility requires the utmost respect:
1145*08855964SRyan Zezeski 	 * test modules have full access to the kernel address space
1146*08855964SRyan Zezeski 	 * and the user executing ktest can pipe in any arbitrary
1147*08855964SRyan Zezeski 	 * stream of bytes to any test which takes an input stream.
1148*08855964SRyan Zezeski 	 * Given this liability, and the fact the test facility should
1149*08855964SRyan Zezeski 	 * mostly be used for development quality assurance or
1150*08855964SRyan Zezeski 	 * production pre-flight checklists or healthchecks, it makes
1151*08855964SRyan Zezeski 	 * sense to restrict the loading, listing, and execution of
1152*08855964SRyan Zezeski 	 * tests to those with the highest of privilege: the root
1153*08855964SRyan Zezeski 	 * role/user in the Global Zone.
1154*08855964SRyan Zezeski 	 */
1155*08855964SRyan Zezeski 	if (drv_priv(credp) != 0 || crgetzoneid(credp) != GLOBAL_ZONEID) {
1156*08855964SRyan Zezeski 		return (EPERM);
1157*08855964SRyan Zezeski 	}
1158*08855964SRyan Zezeski 
1159*08855964SRyan Zezeski 	return (0);
1160*08855964SRyan Zezeski }
1161*08855964SRyan Zezeski 
1162*08855964SRyan Zezeski static int
ktest_close(dev_t dev,int flags,int otype,cred_t * credp)1163*08855964SRyan Zezeski ktest_close(dev_t dev, int flags, int otype, cred_t *credp)
1164*08855964SRyan Zezeski {
1165*08855964SRyan Zezeski 	return (0);
1166*08855964SRyan Zezeski }
1167*08855964SRyan Zezeski 
1168*08855964SRyan Zezeski static int
ktest_ioctl_run_test(intptr_t arg,int mode)1169*08855964SRyan Zezeski ktest_ioctl_run_test(intptr_t arg, int mode)
1170*08855964SRyan Zezeski {
1171*08855964SRyan Zezeski 	int ret = 0;
1172*08855964SRyan Zezeski 	ktest_run_op_t kro;
1173*08855964SRyan Zezeski 	uchar_t *input_bytes = NULL;
1174*08855964SRyan Zezeski 	ktest_test_t *kt = NULL;
1175*08855964SRyan Zezeski 
1176*08855964SRyan Zezeski 	bzero(&kro, sizeof (kro));
1177*08855964SRyan Zezeski 	if (ddi_copyin((void *)arg, &kro, sizeof (kro), mode) != 0) {
1178*08855964SRyan Zezeski 		return (EFAULT);
1179*08855964SRyan Zezeski 	}
1180*08855964SRyan Zezeski 
1181*08855964SRyan Zezeski 	if (kro.kro_input_len > KTEST_IOCTL_MAX_LEN) {
1182*08855964SRyan Zezeski 		return (EINVAL);
1183*08855964SRyan Zezeski 	}
1184*08855964SRyan Zezeski 
1185*08855964SRyan Zezeski 	/*
1186*08855964SRyan Zezeski 	 * If there is input, copy it into KAS.
1187*08855964SRyan Zezeski 	 */
1188*08855964SRyan Zezeski 	if (kro.kro_input_len > 0) {
1189*08855964SRyan Zezeski 		input_bytes = kmem_zalloc(kro.kro_input_len, KM_SLEEP);
1190*08855964SRyan Zezeski 		ret = ddi_copyin((void *)kro.kro_input_bytes, input_bytes,
1191*08855964SRyan Zezeski 		    kro.kro_input_len, mode);
1192*08855964SRyan Zezeski 
1193*08855964SRyan Zezeski 		if (ret != 0) {
1194*08855964SRyan Zezeski 			ret = EFAULT;
1195*08855964SRyan Zezeski 			goto done;
1196*08855964SRyan Zezeski 		}
1197*08855964SRyan Zezeski 	}
1198*08855964SRyan Zezeski 
1199*08855964SRyan Zezeski 	mutex_enter(&ktest_lock);
1200*08855964SRyan Zezeski 	kt = ktest_get_test(kro.kro_module, kro.kro_suite, kro.kro_test);
1201*08855964SRyan Zezeski 
1202*08855964SRyan Zezeski 	/*
1203*08855964SRyan Zezeski 	 * We failed to find a matching test. The ktest command should
1204*08855964SRyan Zezeski 	 * always send down a valid fully-qualified triple; but it's
1205*08855964SRyan Zezeski 	 * good hygiene to check for this case.
1206*08855964SRyan Zezeski 	 */
1207*08855964SRyan Zezeski 	if (kt == NULL) {
1208*08855964SRyan Zezeski 		ret = ENOENT;
1209*08855964SRyan Zezeski 		goto done;
1210*08855964SRyan Zezeski 	}
1211*08855964SRyan Zezeski 
1212*08855964SRyan Zezeski 	/*
1213*08855964SRyan Zezeski 	 * The test requires input but none was provided. The ktest
1214*08855964SRyan Zezeski 	 * command should not send down such a request; but it's good
1215*08855964SRyan Zezeski 	 * hygiene to check for it.
1216*08855964SRyan Zezeski 	 */
1217*08855964SRyan Zezeski 	if (kt->kt_requires_input && kro.kro_input_len == 0) {
1218*08855964SRyan Zezeski 		ret = EINVAL;
1219*08855964SRyan Zezeski 		goto done;
1220*08855964SRyan Zezeski 	}
1221*08855964SRyan Zezeski 
1222*08855964SRyan Zezeski 	ktest_run_test(kt, input_bytes, kro.kro_input_len, &kro.kro_result);
1223*08855964SRyan Zezeski 
1224*08855964SRyan Zezeski done:
1225*08855964SRyan Zezeski 	mutex_exit(&ktest_lock);
1226*08855964SRyan Zezeski 	kmem_free(input_bytes, kro.kro_input_len);
1227*08855964SRyan Zezeski 
1228*08855964SRyan Zezeski 	if (ret == 0 &&
1229*08855964SRyan Zezeski 	    ddi_copyout(&kro, (void *)arg, sizeof (kro), mode) != 0) {
1230*08855964SRyan Zezeski 		ret = EFAULT;
1231*08855964SRyan Zezeski 	}
1232*08855964SRyan Zezeski 
1233*08855964SRyan Zezeski 	return (ret);
1234*08855964SRyan Zezeski }
1235*08855964SRyan Zezeski 
1236*08855964SRyan Zezeski static int
ktest_ioctl_list_tests(intptr_t arg,int mode)1237*08855964SRyan Zezeski ktest_ioctl_list_tests(intptr_t arg, int mode)
1238*08855964SRyan Zezeski {
1239*08855964SRyan Zezeski 	int ret = 0;
1240*08855964SRyan Zezeski 	ktest_list_op_t klo;
1241*08855964SRyan Zezeski 
1242*08855964SRyan Zezeski 	bzero(&klo, sizeof (klo));
1243*08855964SRyan Zezeski 	if (ddi_copyin((void *)arg, &klo, sizeof (klo), mode) != 0) {
1244*08855964SRyan Zezeski 		return (EFAULT);
1245*08855964SRyan Zezeski 	}
1246*08855964SRyan Zezeski 
1247*08855964SRyan Zezeski 	if ((ret = ktest_list_tests(&klo, mode)) == 0) {
1248*08855964SRyan Zezeski 		if (ddi_copyout(&klo, (void *)arg, sizeof (klo), mode) != 0) {
1249*08855964SRyan Zezeski 			return (EFAULT);
1250*08855964SRyan Zezeski 		}
1251*08855964SRyan Zezeski 	}
1252*08855964SRyan Zezeski 
1253*08855964SRyan Zezeski 	return (ret);
1254*08855964SRyan Zezeski }
1255*08855964SRyan Zezeski 
1256*08855964SRyan Zezeski static int
ktest_ioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)1257*08855964SRyan Zezeski ktest_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
1258*08855964SRyan Zezeski     int *rvalp)
1259*08855964SRyan Zezeski {
1260*08855964SRyan Zezeski 	int ret = 0;
1261*08855964SRyan Zezeski 
1262*08855964SRyan Zezeski 	/*
1263*08855964SRyan Zezeski 	 * We make two assumptions:
1264*08855964SRyan Zezeski 	 *
1265*08855964SRyan Zezeski 	 *  1. That only the ktest command interacts with the ktest driver.
1266*08855964SRyan Zezeski 	 *
1267*08855964SRyan Zezeski 	 *  2. The the ktest command is 64-bit.
1268*08855964SRyan Zezeski 	 */
1269*08855964SRyan Zezeski 	if (ddi_model_convert_from(mode) != DDI_MODEL_NONE) {
1270*08855964SRyan Zezeski 		return (ENOSYS);
1271*08855964SRyan Zezeski 	}
1272*08855964SRyan Zezeski 
1273*08855964SRyan Zezeski 	switch (cmd) {
1274*08855964SRyan Zezeski 	case KTEST_IOCTL_RUN_TEST:
1275*08855964SRyan Zezeski 		ret = ktest_ioctl_run_test(arg, mode);
1276*08855964SRyan Zezeski 		break;
1277*08855964SRyan Zezeski 
1278*08855964SRyan Zezeski 	case KTEST_IOCTL_LIST_TESTS:
1279*08855964SRyan Zezeski 		ret = ktest_ioctl_list_tests(arg, mode);
1280*08855964SRyan Zezeski 		break;
1281*08855964SRyan Zezeski 
1282*08855964SRyan Zezeski 	default:
1283*08855964SRyan Zezeski 		ret = EINVAL;
1284*08855964SRyan Zezeski 		break;
1285*08855964SRyan Zezeski 	}
1286*08855964SRyan Zezeski 
1287*08855964SRyan Zezeski 	return (ret);
1288*08855964SRyan Zezeski }
1289*08855964SRyan Zezeski 
1290*08855964SRyan Zezeski static struct cb_ops ktest_cb_ops = {
1291*08855964SRyan Zezeski 	.cb_open = ktest_open,
1292*08855964SRyan Zezeski 	.cb_close = ktest_close,
1293*08855964SRyan Zezeski 	.cb_strategy = nodev,
1294*08855964SRyan Zezeski 	.cb_print = nodev,
1295*08855964SRyan Zezeski 	.cb_dump = nodev,
1296*08855964SRyan Zezeski 	.cb_read = nodev,
1297*08855964SRyan Zezeski 	.cb_write = nodev,
1298*08855964SRyan Zezeski 	.cb_ioctl = ktest_ioctl,
1299*08855964SRyan Zezeski 	.cb_devmap = nodev,
1300*08855964SRyan Zezeski 	.cb_mmap = nodev,
1301*08855964SRyan Zezeski 	.cb_segmap = nodev,
1302*08855964SRyan Zezeski 	.cb_chpoll = nochpoll,
1303*08855964SRyan Zezeski 	.cb_prop_op = ddi_prop_op,
1304*08855964SRyan Zezeski 	.cb_flag = D_MP | D_64BIT,
1305*08855964SRyan Zezeski 	.cb_rev = CB_REV,
1306*08855964SRyan Zezeski 	.cb_aread = nodev,
1307*08855964SRyan Zezeski 	.cb_awrite = nodev,
1308*08855964SRyan Zezeski 	.cb_str = NULL
1309*08855964SRyan Zezeski };
1310*08855964SRyan Zezeski 
1311*08855964SRyan Zezeski static struct dev_ops ktest_dev_ops = {
1312*08855964SRyan Zezeski 	.devo_rev = DEVO_REV,
1313*08855964SRyan Zezeski 	.devo_refcnt = 0,
1314*08855964SRyan Zezeski 	.devo_getinfo = ktest_getinfo,
1315*08855964SRyan Zezeski 	.devo_identify = nulldev,
1316*08855964SRyan Zezeski 	.devo_probe = nulldev,
1317*08855964SRyan Zezeski 	.devo_attach = ktest_attach,
1318*08855964SRyan Zezeski 	.devo_detach = ktest_detach,
1319*08855964SRyan Zezeski 	.devo_reset = nodev,
1320*08855964SRyan Zezeski 	.devo_power = NULL,
1321*08855964SRyan Zezeski 	.devo_quiesce = ddi_quiesce_not_supported,
1322*08855964SRyan Zezeski 	.devo_cb_ops = &ktest_cb_ops,
1323*08855964SRyan Zezeski 	.devo_bus_ops = NULL
1324*08855964SRyan Zezeski };
1325*08855964SRyan Zezeski 
1326*08855964SRyan Zezeski static struct modldrv ktest_modldrv = {
1327*08855964SRyan Zezeski 	.drv_modops = &mod_driverops,
1328*08855964SRyan Zezeski 	.drv_linkinfo = "Kernel Test Driver v1",
1329*08855964SRyan Zezeski 	.drv_dev_ops = &ktest_dev_ops
1330*08855964SRyan Zezeski };
1331*08855964SRyan Zezeski 
1332*08855964SRyan Zezeski static struct modlinkage ktest_modlinkage = {
1333*08855964SRyan Zezeski 	.ml_rev = MODREV_1,
1334*08855964SRyan Zezeski 	.ml_linkage = { &ktest_modldrv, NULL }
1335*08855964SRyan Zezeski };
1336*08855964SRyan Zezeski 
1337*08855964SRyan Zezeski static void
ktest_fini()1338*08855964SRyan Zezeski ktest_fini()
1339*08855964SRyan Zezeski {
1340*08855964SRyan Zezeski 	ktest_unregister_all();
1341*08855964SRyan Zezeski 	list_destroy(&ktest_modules);
1342*08855964SRyan Zezeski 	mutex_destroy(&ktest_lock);
1343*08855964SRyan Zezeski }
1344*08855964SRyan Zezeski 
1345*08855964SRyan Zezeski /*
1346*08855964SRyan Zezeski  * This is a pseudo device driver with a single instance, therefore
1347*08855964SRyan Zezeski  * all state is allocated/freed during init/fini. We delay the
1348*08855964SRyan Zezeski  * creation of the taskq until attach, since tests cannot be executed
1349*08855964SRyan Zezeski  * until the driver is attached.
1350*08855964SRyan Zezeski  */
1351*08855964SRyan Zezeski int
_init(void)1352*08855964SRyan Zezeski _init(void)
1353*08855964SRyan Zezeski {
1354*08855964SRyan Zezeski 	int ret;
1355*08855964SRyan Zezeski 
1356*08855964SRyan Zezeski 	mutex_init(&ktest_lock, NULL, MUTEX_DRIVER, NULL);
1357*08855964SRyan Zezeski 	list_create(&ktest_modules, sizeof (ktest_module_t),
1358*08855964SRyan Zezeski 	    offsetof(ktest_module_t, km_node));
1359*08855964SRyan Zezeski 	ret = mod_install(&ktest_modlinkage);
1360*08855964SRyan Zezeski 
1361*08855964SRyan Zezeski 	if (ret != DDI_SUCCESS) {
1362*08855964SRyan Zezeski 		ktest_fini();
1363*08855964SRyan Zezeski 	}
1364*08855964SRyan Zezeski 
1365*08855964SRyan Zezeski 	return (ret);
1366*08855964SRyan Zezeski }
1367*08855964SRyan Zezeski 
1368*08855964SRyan Zezeski int
_fini(void)1369*08855964SRyan Zezeski _fini(void)
1370*08855964SRyan Zezeski {
1371*08855964SRyan Zezeski 	int ret = mod_remove(&ktest_modlinkage);
1372*08855964SRyan Zezeski 
1373*08855964SRyan Zezeski 	if (ret == DDI_SUCCESS) {
1374*08855964SRyan Zezeski 		ktest_fini();
1375*08855964SRyan Zezeski 	}
1376*08855964SRyan Zezeski 
1377*08855964SRyan Zezeski 	return (ret);
1378*08855964SRyan Zezeski }
1379*08855964SRyan Zezeski 
1380*08855964SRyan Zezeski int
_info(struct modinfo * modinfop)1381*08855964SRyan Zezeski _info(struct modinfo *modinfop)
1382*08855964SRyan Zezeski {
1383*08855964SRyan Zezeski 	return (mod_info(&ktest_modlinkage, modinfop));
1384*08855964SRyan Zezeski }
1385