xref: /freebsd/share/man/man9/exterror.9 (revision 8ccc0d235c226d84112561d453c49904398d085c)
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.
93.El
94.Pp
95The strings passed as the second argument are only retained
96in the kernel text if the
97.Cd option EXTERR_STRINGS
98was enabled in the kernel config.
99Otherwise they are stripped at compile time and are not available
100to userspace at runtime.
101.Pp
102The
103.Fn EXTERROR
104macro can be used in any context where the current thread is defined.
105Specifically,
106.Fn EXTERROR
107cannot be used in interrupt contexts and context switch code.
108Additionally, use of
109.Fn EXTERROR
110in kernel threads is not sensible as there is no userspace to retrieve
111the extended error data.
112.Pp
113The
114.Fn EXTERROR_KE
115macro is similar to
116.Fn EXTERROR ,
117but it takes an explicit pointer
118.Fa kep
119to the
120.Vt struct kexterr
121to fill with the extended error information.
122The macro expression value is
123.Vt void .
124See below for description of the asynchronous i/o error facilities.
125.Pp
126The
127.Fn exterr_clear
128function clears the content of the
129.Vt struct kexterr
130pointed to by the argument
131.Fa ke .
132.Pp
133The
134.Fn exterr_set_from
135function sets the current thread extended error data from the
136.Fa struct kexterr
137pointed to by the argument
138.Fa ke .
139.Sh USERSPACE ACCESS TO EXTENDED ERROR DATA
140There is no syscall overhead for using
141.Nm
142in the non-error case.
143When an error occurs that has supplied extended information,
144the kernel copies out that information into the userspace
145per-thread area that was registered with the kernel, typically on
146image activation, or later at thread startup.
147The area is controlled by the
148.Xr exterrctl 2
149internal syscall, normally done by the userspace C runtime.
150.Pp
151Userspace programs do not need to access the extended information
152area directly.
153There is no field that is stable for the specific error condition.
154Instead, the base
155.Lb c
156functions
157.Xr err 3
158and
159.Xr warn 3
160were modified to print the extended information if it is available
161in addition to the usual
162.Va errno
163decoding.
164.Sh ASYNCHRONOUS INPUT/OUTPUT
165Due to the nature of the
166.Fx
167i/o subsystem, most input/output requests, presented as buffers (as in
168.Vt struct buf )
169and geom bio's (
170.Vt struct bio )
171are processed asynchronously in filesystem- and geom-private threads.
172This makes it challenging to pass any extended error information
173from the geom providers and drivers, where an error typically occurs,
174back to the thread that initiated the request, and is the consumer of
175the result.
176.Pp
177To alleviate the mismatch, both
178.Vt struct buf
179and
180.Vt struct bio
181have member of the
182.Vt struct kexterr
183type.
184For buffers, the
185.Va b_exterr
186for
187.Vt struct buf ,
188and
189.Va bio_exterr
190for
191.Vt struct bio .
192Asynchronous i/o code can use the
193.Fn EXTERROR_KE
194macro, passing the pointer to the current request's embedded
195.Vt struct kexterr ,
196to record the extended error.
197In both cases, the
198.Va BIO_EXTERR
199flag should be set to indicate that whole extended error is valid,
200not only the
201.Va b_error
202or
203.Va bio_error
204values.
205.Pp
206Both VFS and geom generic layers, and several geom providers that generate
207subordinate bio's from the original request, are aware of the extended
208errors.
209They pass
210.Vt kexterr
211from the failed request back to the thread that create the request.
212.Sh SEE ALSO
213.Xr errno 3 ,
214.Xr err 3
215.Sh HISTORY
216The
217.Nm
218facility was introduced in
219.Fx 15.0 .
220