summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/exterror.9 3.html
blob: c28538a1e2b9783b8cc4eeab8405fabfc800926f (plain)
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
<table class="head">
  <tr>
    <td class="head-ltitle">EXTERROR(9)</td>
    <td class="head-vol">Kernel Developer's Manual</td>
    <td class="head-rtitle">EXTERROR(9)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">exterror</code> &#x2014; <span class="Nd">provide
    extended error information to userspace</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<div class="Bd Li">
<pre>#define	EXTERR_CATEGORY EXTERR_CAT_MYCATEGORY</pre>
</div>
<br/>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">sys/exterrvar.h</a>&gt;</code></p>
<p class="Pp"><var class="Vt">struct kexterr;</var></p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">exterr_clear</code>(<var class="Fa" style="white-space: nowrap;">struct
    kexterr *ke</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">exterr_set_from</code>(<var class="Fa" style="white-space: nowrap;">const
    struct kexterr *ke</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">EXTERROR</code>(<var class="Fa" style="white-space: nowrap;">int
    error</var>, <var class="Fa" style="white-space: nowrap;">const char
    *msg</var>, <var class="Fa" style="white-space: nowrap;">...</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">EXTERROR_KE</code>(<var class="Fa" style="white-space: nowrap;">struct
    kexterr *ke</var>, <var class="Fa" style="white-space: nowrap;">int
    error</var>, <var class="Fa" style="white-space: nowrap;">const char
    *msg</var>, <var class="Fa" style="white-space: nowrap;">...</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">exterror</code> framework allows the kernel
    to return additional information about an error along with the standard
    <a class="Xr">errno(3)</a> error code, which is terse and often lacking
    context.</p>
<p class="Pp">The terseness is especially visible with commonly overloaded error
    codes like <code class="Er">EINVAL</code> or <code class="Er">EIO</code>,
    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 <var class="Va">errno</var> 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.
    <code class="Nm">exterror</code> attaches additional data to the error
    itself and records the error category and the kernel source code file line
    number. The intent of <code class="Nm">exterror</code> is to make it easier
    for a user to identify the cause of the error.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="USAGE"><a class="permalink" href="#USAGE">USAGE</a></h1>
<p class="Pp">Before <code class="Nm">exterror</code> can be used in the given
    source .c file, the category of extended errors should be allocated in the
    <code class="In">&lt;<a class="In">sys/exterr_cat.h</a>&gt;</code> file. The
    category is the unique integer, that, together with the source line number,
    uniquely identifies the extended error occurrence. Then, the
    <var class="Va">EXTERR_CATEGORY</var> symbol should be defined as an alias
    for the allocated category, as shown in the summary.</p>
<p class="Pp">A typical code fragment to report an error is just</p>
<div class="Bd Bd-indent">return (EINVAL);</div>
An extended error can augment the error code with additional information:
<div class="Bd Bd-indent">return (EXTERROR(EINVAL, &quot;Invalid
  length&quot;));</div>
The error data and metadata is saved in the current thread storage. The metadata
  includes the category and the source file line number.
<p class="Pp" id="EXTERROR">Arguments to the
    <a class="permalink" href="#EXTERROR"><code class="Fn">EXTERROR</code></a>()
    macro:</p>
<ul class="Bl-dash">
  <li>The first argument to <code class="Fn">EXTERROR</code>() is the errno
      error code.</li>
  <li>The second argument is a constant string with the unbound lifetime, which
      should tersely provide enough human-readable details about the error.</li>
  <li>The <code class="Fn">EXTERROR</code>() macro can take two optional 64-bit
      integer arguments, whose meaning is specific to the subsystem. The format
      string may include up to two printf-like format specifiers to insert the
      optional argument values in the user output, which is done in userspace.
    <p class="Pp">The format specifier must be for an integer type, and include
        the &#x201C;j&#x201D; format modifier to accept only the types
        <var class="Vt">intmax_t</var> or <var class="Vt">uintmax_t</var>.</p>
  </li>
</ul>
<p class="Pp">The strings passed as the second argument are only retained in the
    kernel text if the <code class="Cd">option EXTERR_STRINGS</code> was enabled
    in the kernel config. Otherwise they are stripped at compile time and are
    not available to userspace at runtime.</p>
<p class="Pp" id="EXTERROR~2">The
    <a class="permalink" href="#EXTERROR~2"><code class="Fn">EXTERROR</code></a>()
    macro can be used in any context where the current thread is defined.
    Specifically, <code class="Fn">EXTERROR</code>() cannot be used in interrupt
    contexts and context switch code. Additionally, use of
    <code class="Fn">EXTERROR</code>() in kernel threads is not sensible as
    there is no userspace to retrieve the extended error data.</p>
<p class="Pp" id="EXTERROR_KE">The
    <a class="permalink" href="#EXTERROR_KE"><code class="Fn">EXTERROR_KE</code></a>()
    macro is similar to <code class="Fn">EXTERROR</code>(), but it takes an
    explicit pointer <var class="Fa">kep</var> to the <var class="Vt">struct
    kexterr</var> to fill with the extended error information. The macro
    expression value is <var class="Vt">void</var>. See below for description of
    the asynchronous i/o error facilities.</p>
<p class="Pp" id="exterr_clear">The
    <a class="permalink" href="#exterr_clear"><code class="Fn">exterr_clear</code></a>()
    function clears the content of the <var class="Vt">struct kexterr</var>
    pointed to by the argument <var class="Fa">ke</var>.</p>
<p class="Pp" id="exterr_set_from">The
    <a class="permalink" href="#exterr_set_from"><code class="Fn">exterr_set_from</code></a>()
    function sets the current thread extended error data from the
    <var class="Fa">struct kexterr</var> pointed to by the argument
    <var class="Fa">ke</var>.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="USERSPACE_ACCESS_TO_EXTENDED_ERROR_DATA"><a class="permalink" href="#USERSPACE_ACCESS_TO_EXTENDED_ERROR_DATA">USERSPACE
  ACCESS TO EXTENDED ERROR DATA</a></h1>
<p class="Pp">There is no syscall overhead for using
    <code class="Nm">exterror</code> 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 <a class="Xr">exterrctl(2)</a> internal syscall,
    normally done by the userspace C runtime.</p>
<p class="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 <span class="Lb">library
    &#x201C;c&#x201D;</span> functions <a class="Xr">err(3)</a> and
    <a class="Xr">warn(3)</a> were modified to print the extended information if
    it is available in addition to the usual <var class="Va">errno</var>
    decoding.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="ASYNCHRONOUS_INPUT/OUTPUT"><a class="permalink" href="#ASYNCHRONOUS_INPUT/OUTPUT">ASYNCHRONOUS
  INPUT/OUTPUT</a></h1>
<p class="Pp">Due to the nature of the <span class="Ux">FreeBSD</span> i/o
    subsystem, most input/output requests, presented as buffers (as in
    <var class="Vt">struct buf</var>) and geom bio's ( <var class="Vt">struct
    bio</var>) 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.</p>
<p class="Pp" id="EXTERROR_KE~2">To alleviate the mismatch, both
    <var class="Vt">struct buf</var> and <var class="Vt">struct bio</var> have
    member of the <var class="Vt">struct kexterr</var> type. For buffers, the
    <var class="Va">b_exterr</var> for <var class="Vt">struct buf</var>, and
    <var class="Va">bio_exterr</var> for <var class="Vt">struct bio</var>.
    Asynchronous i/o code can use the
    <a class="permalink" href="#EXTERROR_KE~2"><code class="Fn">EXTERROR_KE</code></a>()
    macro, passing the pointer to the current request's embedded
    <var class="Vt">struct kexterr</var>, to record the extended error. In both
    cases, the <var class="Va">BIO_EXTERR</var> flag should be set to indicate
    that whole extended error is valid, not only the
    <var class="Va">b_error</var> or <var class="Va">bio_error</var> values.</p>
<p class="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 <var class="Vt">kexterr</var> from the failed
    request back to the thread that create the request.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">errno(3)</a>, <a class="Xr">err(3)</a>,
    <a class="Xr">uexterr_gettext(3)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">The <code class="Nm">exterror</code> facility was introduced in
    <span class="Ux">FreeBSD 15.0</span>.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">November 5, 2025</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>