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