xref: /src/share/man/man9/exterror.9 (revision b1bebaaba9b9c0ddfe503c43ca8e9e3917ee2c57)
1.\" SPDX-License-Identifier: BSD-2-Clause
2.\"
3.\" Copyright (c) 2025 The FreeBSD Foundation
4.\"
5.\" This documentation was written by
6.\" Konstantin Belousov <kib@FreeBSD.org> under sponsorship
7.\" from the FreeBSD Foundation.
8.\"
9.Dd November 5, 2025
10.Dt EXTERROR 9
11.Os
12.Sh NAME
13.Nm exterror
14.Nd provide extended error information to userspace
15.Sh SYNOPSIS
16.Bd -literal -offset left -compact
17#define	EXTERR_CATEGORY EXTERR_CAT_MYCATEGORY
18.Ed
19.In sys/exterrvar.h
20.Vt struct kexterr;
21.Ft void
22.Fn exterr_clear "struct kexterr *ke"
23.Ft int
24.Fn exterr_set_from "const struct kexterr *ke"
25.Ft int
26.Fn EXTERROR "int error" "const char *msg" ...
27.Ft void
28.Fn EXTERROR_KE "struct kexterr *ke" "int error" "const char *msg" ...
29.Sh DESCRIPTION
30The
31.Nm
32framework allows the kernel to return additional information about an error
33along with the standard
34.Xr errno 3
35error code, which is terse and often lacking context.
36.Pp
37The terseness is especially visible with commonly overloaded error codes like
38.Er EINVAL
39or
40.Er EIO ,
41which occur at many places for a given syscall, or even
42outside the context of the current kernel call.
43Identifying the specific cause for the returned error using only the
44.Va errno
45value requires searching for all instances that the error is returned
46in the kernel and trying to guess which is the most likely code path
47to have returned the error.
48.Nm
49attaches additional data to the error itself
50and records the error category and
51the kernel source code file line number.
52The intent of
53.Nm
54is to make it easier for a user to identify the cause of the error.
55.Sh USAGE
56Before
57.Nm
58can be used in the given source .c file, the category of extended errors
59should be allocated in the
60.In sys/exterr_cat.h
61file.
62The category is the unique integer, that, together with the source
63line number, uniquely identifies the extended error occurrence.
64Then, the
65.Va EXTERR_CATEGORY
66symbol should be defined as an alias for the allocated category, as
67shown in the summary.
68.Pp
69A typical code fragment to report an error is just
70.D1 return (EINVAL);
71An extended error can augment the error code with additional information:
72.D1 return (EXTERROR(EINVAL, \[dq]Invalid length\[dq]));
73The error data and metadata is saved in the current thread storage.
74The metadata includes the category and the source file line number.
75.Pp
76Arguments to the
77.Fn EXTERROR
78macro:
79.Bl -dash
80.It
81The first argument to
82.Fn EXTERROR
83is the errno error code.
84.It
85The second argument is a constant string with the unbound lifetime,
86which should tersely provide enough human-readable details about
87the error.
88.It
89The
90.Fn EXTERROR
91macro can take two optional 64-bit integer arguments,
92whose meaning is specific to the subsystem.
93The format string may include up to two printf-like format
94specifiers to insert the optional argument values in the
95user output, which is done in userspace.
96.Pp
97The format specifier must be for an integer type, and include the
98.Dq j
99format modifier to accept only the types
100.Vt intmax_t
101or
102.Vt uintmax_t .
103.El
104.Pp
105The strings passed as the second argument are only retained
106in the kernel text if the
107.Cd option EXTERR_STRINGS
108was enabled in the kernel config.
109Otherwise they are stripped at compile time and are not available
110to userspace at runtime.
111.Pp
112The
113.Fn EXTERROR
114macro can be used in any context where the current thread is defined.
115Specifically,
116.Fn EXTERROR
117cannot be used in interrupt contexts and context switch code.
118Additionally, use of
119.Fn EXTERROR
120in kernel threads is not sensible as there is no userspace to retrieve
121the extended error data.
122.Pp
123The
124.Fn EXTERROR_KE
125macro is similar to
126.Fn EXTERROR ,
127but it takes an explicit pointer
128.Fa kep
129to the
130.Vt struct kexterr
131to fill with the extended error information.
132The macro expression value is
133.Vt void .
134See below for description of the asynchronous i/o error facilities.
135.Pp
136The
137.Fn exterr_clear
138function clears the content of the
139.Vt struct kexterr
140pointed to by the argument
141.Fa ke .
142.Pp
143The
144.Fn exterr_set_from
145function sets the current thread extended error data from the
146.Fa struct kexterr
147pointed to by the argument
148.Fa ke .
149.Sh USERSPACE ACCESS TO EXTENDED ERROR DATA
150There is no syscall overhead for using
151.Nm
152in the non-error case.
153When an error occurs that has supplied extended information,
154the kernel copies out that information into the userspace
155per-thread area that was registered with the kernel, typically on
156image activation, or later at thread startup.
157The area is controlled by the
158.Xr exterrctl 2
159internal syscall, normally done by the userspace C runtime.
160.Pp
161Userspace programs do not need to access the extended information
162area directly.
163There is no field that is stable for the specific error condition.
164Instead, the base
165.Lb c
166functions
167.Xr err 3
168and
169.Xr warn 3
170were modified to print the extended information if it is available
171in addition to the usual
172.Va errno
173decoding.
174.Sh ASYNCHRONOUS INPUT/OUTPUT
175Due to the nature of the
176.Fx
177i/o subsystem, most input/output requests, presented as buffers (as in
178.Vt struct buf )
179and geom bio's (
180.Vt struct bio )
181are processed asynchronously in filesystem- and geom-private threads.
182This makes it challenging to pass any extended error information
183from the geom providers and drivers, where an error typically occurs,
184back to the thread that initiated the request, and is the consumer of
185the result.
186.Pp
187To alleviate the mismatch, both
188.Vt struct buf
189and
190.Vt struct bio
191have member of the
192.Vt struct kexterr
193type.
194For buffers, the
195.Va b_exterr
196for
197.Vt struct buf ,
198and
199.Va bio_exterr
200for
201.Vt struct bio .
202Asynchronous i/o code can use the
203.Fn EXTERROR_KE
204macro, passing the pointer to the current request's embedded
205.Vt struct kexterr ,
206to record the extended error.
207In both cases, the
208.Va BIO_EXTERR
209flag should be set to indicate that whole extended error is valid,
210not only the
211.Va b_error
212or
213.Va bio_error
214values.
215.Pp
216Both VFS and geom generic layers, and several geom providers that generate
217subordinate bio's from the original request, are aware of the extended
218errors.
219They pass
220.Vt kexterr
221from the failed request back to the thread that create the request.
222.Sh SEE ALSO
223.Xr errno 3 ,
224.Xr err 3
225.Sh HISTORY
226The
227.Nm
228facility was introduced in
229.Fx 15.0 .
230