1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 #include <libintl.h>
17 #include <sys/debug.h>
18 #include <string.h>
19 #include <stdarg.h>
20
21 #include <sys/krrp.h>
22 #include "krrp_error.h"
23 #include "libkrrp.h"
24 #include "libkrrp_impl.h"
25 #include "libkrrp_error.h"
26
27 /* Make lint happy */
28 #pragma error_messages(off, E_UNDEFINED_SYMBOL, E_YACC_ERROR, \
29 E_FUNC_VAR_UNUSED, E_BLOCK_DECL_UNUSED, E_RET_INT_IMPLICITLY, \
30 E_NOP_ELSE_STMT)
31
32 /* Taken from sys/zio.h */
33 #define ECKSUM EBADE
34
35 static struct {
36 krrp_errno_t krrp_errno;
37 libkrrp_errno_t libkrrp_errno;
38 } krrp_errs[] = {
39 {KRRP_ERRNO_OK, LIBKRRP_ERRNO_OK},
40 {KRRP_ERRNO_UNKNOWN, LIBKRRP_ERRNO_UNKNOWN},
41 #define LIBKRRP_ERRNO_EXPAND(enum_name) \
42 {KRRP_ERRNO_##enum_name, LIBKRRP_ERRNO_##enum_name},
43 KRNKRRP_ERRNO_MAP(LIBKRRP_ERRNO_EXPAND)
44 #undef LIBKRRP_ERRNO_EXPAND
45 };
46
47 static size_t krrp_errs_sz = sizeof (krrp_errs) / sizeof (krrp_errs[0]);
48
49 #define UNIX_ERRNO_EXPAND(enum_name) \
50 {enum_name, "UNIX_ERRNO_"#enum_name},
51 static struct {
52 int errno_num;
53 const char *errno_str;
54 } unix_errnos[] = {
55 {0, "UNIX_ERRNO_UNDEFINED"},
56 UNIX_ERRNO_MAP(UNIX_ERRNO_EXPAND)
57 };
58 #undef UNIX_ERRNO_EXPAND
59
60 static size_t unix_errnos_sz = sizeof (unix_errnos) / sizeof (unix_errnos[0]);
61
62 #define KRRP_ERRDESCR_SVC_ENABLE_MAP(X) \
63 X(BUSY, 0, LIBKRRP_EMSG_BUSY) \
64
65 #define KRRP_ERRDESCR_SVC_DISABLE_MAP(X) \
66 X(BUSY, 0, LIBKRRP_EMSG_BUSY) \
67
68 #define KRRP_ERRDESCR_SVC_GET_CONFIG_MAP(X) \
69 X(CFGTYPE, ENOENT, LIBKRRP_EMSG_CFGTYPE_NOENT) \
70 X(CFGTYPE, EINVAL, LIBKRRP_EMSG_CFGTYPE_INVAL) \
71 X(INVAL, 0, LIBKRRP_EMSG_SRVNOTRUN) \
72
73 #define KRRP_ERRDESCR_SVC_SET_CONFIG_MAP(X) \
74 X(CFGTYPE, ENOENT, LIBKRRP_EMSG_CFGTYPE_NOENT) \
75 X(CFGTYPE, EINVAL, LIBKRRP_EMSG_CFGTYPE_INVAL) \
76 X(ADDR, EINVAL, LIBKRRP_EMSG_ADDR_INVAL) \
77 X(CREATEFAIL, 0, LIBKRRP_EMSG_CREATEFAIL, strerror(unix_errno)) \
78 X(BINDFAIL, 0, LIBKRRP_EMSG_BINDFAIL, strerror(unix_errno)) \
79 X(LISTENFAIL, 0, LIBKRRP_EMSG_LISTENFAIL, strerror(unix_errno)) \
80 X(PORT, ENOENT, LIBKRRP_EMSG_LSTPORT_NOENT) \
81 X(PORT, EINVAL, LIBKRRP_EMSG_LSTPORT_INVAL, \
82 KRRP_MIN_PORT, KRRP_MAX_PORT) \
83 X(BUSY, 0, LIBKRRP_EMSG_SRVRECONF) \
84
85 #define KRRP_ERRDESCR_SESS_SET_PRIVATE_DATA_MAP(X) \
86 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
87 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
88 X(SESS, ENODATA, LIBKRRP_EMSG_SESS_NODATA1) \
89 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
90
91 #define KRRP_ERRDESCR_SESS_GET_PRIVATE_DATA_MAP(X) \
92 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
93 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
94 X(SESS, ENODATA, LIBKRRP_EMSG_SESS_NODATA2) \
95 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
96
97 #define KRRP_ERRDESCR_SESS_CREATE_MAP(X) \
98 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
99 X(SESSID, EINVAL, LIBKRRP_EMSG_SESSID_INVAL) \
100 X(KSTATID, ENOENT, LIBKRRP_EMSG_KSTATID_NOENT) \
101 X(KSTATID, EINVAL, LIBKRRP_EMSG_KSTATID_INVAL, \
102 KRRP_KSTAT_ID_STRING_LENGTH - 1) \
103 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_ALREADY) \
104 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_CREATE_INVAL) \
105 X(AUTH, EINVAL, LIBKRRP_EMSG_SESS_CREATE_AUTH_INVAL, \
106 KRRP_AUTH_DIGEST_MAX_LEN - 1) \
107
108 #define KRRP_ERRDESCR_SESS_CREATE_CONN_MAP(X) \
109 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
110 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
111 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_CREATE_CONN_INVAL) \
112 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_CONN_ALREADY) \
113 X(ADDR, ENOENT, LIBKRRP_EMSG_HOST_NOENT) \
114 X(ADDR, EINVAL, LIBKRRP_EMSG_HOST_INVAL) \
115 X(PORT, ENOENT, LIBKRRP_EMSG_PORT_NOENT) \
116 X(PORT, EINVAL, LIBKRRP_EMSG_PORT_INVAL, \
117 KRRP_MIN_PORT, KRRP_MAX_PORT) \
118 X(CREATEFAIL, 0, LIBKRRP_EMSG_CREATEFAIL, strerror(unix_errno)) \
119 X(SETSOCKOPTFAIL, 0, LIBKRRP_EMSG_SETSOCKOPTFAIL, \
120 strerror(unix_errno)) \
121 X(CONNFAIL, 0, LIBKRRP_EMSG_CONNFAIL, strerror(unix_errno)) \
122 X(SENDFAIL, 0, LIBKRRP_EMSG_SENDFAIL, strerror(unix_errno)) \
123 X(RECVFAIL, 0, LIBKRRP_EMSG_RECVFAIL, strerror(unix_errno)) \
124 X(UNEXPCLOSE, 0, LIBKRRP_EMSG_UNEXPCLOSE, strerror(unix_errno)) \
125 X(UNEXPEND, 0, LIBKRRP_EMSG_UNEXPEND, strerror(unix_errno)) \
126 X(AUTH, ENOENT, LIBKRRP_EMSG_AUTH_NOENT) \
127 X(AUTH, EINVAL, LIBKRRP_EMSG_SESS_CREATE_CONN_AUTH_INVAL) \
128 X(BADRESP, 0, LIBKRRP_EMSG_BADRESP) \
129 X(NOMEM, 0, LIBKRRP_EMSG_NOMEM) \
130 X(BIGPAYLOAD, 0, LIBKRRP_EMSG_BIGPAYLOAD) \
131 X(CONNTIMEOUT, 0, LIBKRRP_EMSG_CONNTIMEOUT_INVAL, \
132 KRRP_MIN_CONN_TIMEOUT, KRRP_MAX_CONN_TIMEOUT) \
133 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
134
135 #define KRRP_ERRDESCR_SESS_CONN_THROTTLE_MAP(X) \
136 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
137 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
138 X(CONN, ENOENT, LIBKRRP_EMSG_SESS_CONN_NOENT) \
139 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_THROTTLE_RECV) \
140 X(THROTTLE, ENOENT, LIBKRRP_EMSG_THROTTLE_NOENT) \
141 X(THROTTLE, EINVAL, LIBKRRP_EMSG_THROTTLE_INVAL, \
142 KRRP_MIN_CONN_THROTTLE) \
143 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
144
145 #define KRRP_ERRDESCR_SESS_CREATE_PDU_ENGINE_MAP(X) \
146 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
147 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
148 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_PDUENGINE_ALREADY) \
149 X(DBLKSZ, EINVAL, LIBKRRP_EMSG_DBLKSZ_INVAL, \
150 KRRP_MIN_SESS_PDU_DBLK_DATA_SZ, KRRP_MAX_SESS_PDU_DBLK_DATA_SZ) \
151 X(DBLKSZ, ENOENT, LIBKRRP_EMSG_DBLKSZ_NOENT) \
152 X(MAXMEMSZ, ENOENT, LIBKRRP_EMSG_MAXMEMSZ_NOENT) \
153 X(MAXMEMSZ, EINVAL, LIBKRRP_EMSG_MAXMEMSZ_INVAL, KRRP_MIN_MAXMEM) \
154 X(NOMEM, 0, LIBKRRP_EMSG_SESS_PDUENGINE_NOMEM) \
155 X(CONN, ENOENT, LIBKRRP_EMSG_SESS_CONN_NOENT) \
156 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
157
158 #define KRRP_ERRDESCR_SESS_CREATE_WRITE_STREAM_MAP(X) \
159 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
160 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
161 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_CREATE_WRITE_STREAM_FAIL) \
162 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_STREAM_ALREADY) \
163 X(ZFSGCTXFAIL, 0, LIBKRRP_EMSG_ZFSGCTXFAIL) \
164 X(CMNSNAP, EINVAL, LIBKRRP_EMSG_CMNSNAP_INVAL) \
165 X(DSTDS, ENOENT, LIBKRRP_EMSG_DSTDS_NOENT) \
166 X(DSTDS, EINVAL, LIBKRRP_EMSG_DSTDS_INVAL) \
167 X(RESUMETOKEN, EINVAL, LIBKRRP_EMSG_RESUMETOKEN_INVAL) \
168 X(RESUMETOKEN, ENOTSUP, LIBKRRP_EMSG_RESUMETOKEN_ENOTSUP) \
169 X(RESUMETOKEN, EBADMSG, LIBKRRP_EMSG_RESUMETOKEN_EBADMSG) \
170 X(RESUMETOKEN, ECKSUM, LIBKRRP_EMSG_RESUMETOKEN_ECKSUM) \
171 X(RESUMETOKEN, ENOSR, LIBKRRP_EMSG_RESUMETOKEN_ENOSR) \
172 X(RESUMETOKEN, ENODATA, LIBKRRP_EMSG_RESUMETOKEN_ENODATA) \
173 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
174 X(KEEPSNAPS, 0, LIBKRRP_EMSG_KEEPSNAPS_INVAL, \
175 KRRP_MIN_KEEP_SNAPS, KRRP_MAX_KEEP_SNAPS) \
176
177 #define KRRP_ERRDESCR_SESS_CREATE_READ_STREAM_MAP(X) \
178 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
179 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
180 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_CREATE_READ_STREAM_FAIL) \
181 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_STREAM_ALREADY) \
182 X(FAKEDSZ, ENOENT, LIBKRRP_EMSG_FAKEDSZ_NOENT) \
183 X(FAKEDSZ, EINVAL, LIBKRRP_EMSG_FAKEDSZ_INVAL) \
184 X(ZFSGCTXFAIL, 0, LIBKRRP_EMSG_ZFSGCTXFAIL) \
185 X(SRCDS, ENOENT, LIBKRRP_EMSG_SRCDS_NOENT) \
186 X(SRCDS, EINVAL, LIBKRRP_EMSG_SRCDS_INVAL) \
187 X(SRCSNAP, EINVAL, LIBKRRP_EMSG_SRCSNAP_INVAL) \
188 X(CMNSNAP, EINVAL, LIBKRRP_EMSG_CMNSNAP_INVAL) \
189 X(STREAM, EINVAL, LIBKRRP_EMSG_SNAP_NAMES_EQUAL) \
190 X(RESUMETOKEN, EINVAL, LIBKRRP_EMSG_RESUMETOKEN_INVAL) \
191 X(RESUMETOKEN, ENOTSUP, LIBKRRP_EMSG_RESUMETOKEN_ENOTSUP) \
192 X(RESUMETOKEN, EBADMSG, LIBKRRP_EMSG_RESUMETOKEN_EBADMSG) \
193 X(RESUMETOKEN, ECKSUM, LIBKRRP_EMSG_RESUMETOKEN_ECKSUM) \
194 X(RESUMETOKEN, ENOSR, LIBKRRP_EMSG_RESUMETOKEN_ENOSR) \
195 X(RESUMETOKEN, ENODATA, LIBKRRP_EMSG_RESUMETOKEN_ENODATA) \
196 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
197 X(KEEPSNAPS, 0, LIBKRRP_EMSG_KEEPSNAPS_INVAL, \
198 KRRP_MIN_KEEP_SNAPS, KRRP_MAX_KEEP_SNAPS) \
199 X(SKIP_SNAPS_MASK, EINVAL, \
200 LIBKRRP_EMSG_SKIP_SNAPS_MASK_EINVAL) \
201 X(SKIP_SNAPS_MASK, EMSGSIZE, \
202 LIBKRRP_EMSG_SKIP_SNAPS_MASK_EMSGSIZE) \
203 X(SKIP_SNAPS_MASK, ENAMETOOLONG, \
204 LIBKRRP_EMSG_SKIP_SNAPS_MASK_ENAMETOOLONG) \
205 X(SKIP_SNAPS_MASK, E2BIG, \
206 LIBKRRP_EMSG_SKIP_SNAPS_MASK_E2BIG) \
207
208 #define KRRP_ERRDESCR_SESS_COMMON_MAP(X) \
209 X(AUTOSNAP, EINVAL, LIBKRRP_EMSG_AUTOSNAP_INVAL) \
210 X(CMNSNAP, ENOENT, LIBKRRP_EMSG_CMNSNAP_NOTEXIST) \
211 X(SRCDS, ENOENT, LIBKRRP_EMSG_SRCDS_NOTEXIST) \
212 X(DSTDS, ENOENT, LIBKRRP_EMSG_DSTDS_NOTEXIST) \
213 X(SRCSNAP, ENOENT, LIBKRRP_EMSG_SRCSNAP_NOTEXIST) \
214 X(STREAM, ENXIO, LIBKRRP_EMSG_STREAM_POOL_FAULT) \
215
216 #define KRRP_ERRDESCR_SESS_RUN_MAP(X) \
217 KRRP_ERRDESCR_SESS_COMMON_MAP(X) \
218 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
219 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
220 X(SESS, EALREADY, LIBKRRP_EMSG_SESS_STARTED) \
221 X(SESS, EINVAL, LIBKRRP_EMSG_RUN_ONCE_RECV) \
222 X(CONN, ENOENT, LIBKRRP_EMSG_SESS_CONN_NOENT) \
223 X(PDUENGINE, ENOENT, LIBKRRP_EMSG_SESS_PDUENGINE_NOENT) \
224 X(STREAM, EOPNOTSUPP, LIBKRRP_EMSG_STREAM_EOPNOTSUPP) \
225 X(STREAM, ENOENT, LIBKRRP_EMSG_STREAM_NOENT) \
226 X(STREAM, EINVAL, LIBKRRP_EMSG_SESS_RUN_ONCE_INCOMPAT) \
227 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
228
229 #define KRRP_ERRDESCR_SESS_SEND_STOP_MAP(X) \
230 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
231 X(STREAM, EALREADY, LIBKRRP_EMSG_SESS_SEND_STOP_ALREADY) \
232 X(STREAM, EINVAL, LIBKRRP_EMSG_CANNOT_STOP_SESS) \
233 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
234 X(SESS, ENOTACTIVE, LIBKRRP_EMSG_SESS_NOTACTIVE) \
235 X(SESS, EINVAL, LIBKRRP_EMSG_SESS_SEND_STOP_RECV) \
236 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
237
238 #define KRRP_ERRDESCR_SESS_DESTROY_MAP(X) \
239 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
240 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
241 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
242
243 #define KRRP_ERRDESCR_SESS_STATUS_MAP(X) \
244 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
245 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
246
247 #define KRRP_ERRDESCR_SESS_GET_CONN_INFO_MAP(X) \
248 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
249 X(SESS, ENOENT, LIBKRRP_EMSG_SESS_NOENT) \
250 X(SESS, EBUSY, LIBKRRP_EMSG_SESS_BUSY) \
251 X(SESS, ENOTSUP, LIBKRRP_EMSG_SESS_ENOTSUP) \
252 X(CONN, ENOENT, LIBKRRP_EMSG_SESS_CONN_NOENT) \
253
254 #define KRRP_ERRDESCR_SVC_STATE_MAP(X)
255 #define KRRP_ERRDESCR_SESS_LIST_MAP(X)
256
257 #define LIBKRRP_ERRDESCR_SESS_ERROR_MAP(X) \
258 X(OK, 0, LIBKRRP_EMSG_OK) \
259 X(PINGTIMEOUT, 0, LIBKRRP_EMSG_SESSPINGTIMEOUT) \
260 X(WRITEFAIL, ENODEV, LIBKRRP_EMSG_SNAPMISMATCH) \
261 X(WRITEFAIL, ETXTBSY, LIBKRRP_EMSG_DESTMODIFIED) \
262 X(WRITEFAIL, EEXIST, LIBKRRP_EMSG_DESTEXISTS) \
263 X(WRITEFAIL, EINVAL, LIBKRRP_EMSG_WRITEINVAL) \
264 X(WRITEFAIL, ECKSUM, LIBKRRP_EMSG_CHKSUMMISMATCH) \
265 X(WRITEFAIL, ENOTSUP, LIBKRRP_EMSG_OLDPOOL) \
266 X(WRITEFAIL, EDQUOT, LIBKRRP_EMSG_DESTQUOTA) \
267 X(WRITEFAIL, ENOSPC, LIBKRRP_EMSG_DESTNOSPACE) \
268 X(WRITEFAIL, ENOLINK, LIBKRRP_EMSG_NOORIGIN) \
269 X(WRITEFAIL, 0, LIBKRRP_EMSG_WRITEFAIL, \
270 krrp_unix_errno_to_str(unix_errno)) \
271 X(READFAIL, EXDEV, LIBKRRP_EMSG_NOTEARLIERSNAP) \
272 X(READFAIL, EBUSY, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
273 X(READFAIL, EDQUOT, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
274 X(READFAIL, EFBIG, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
275 X(READFAIL, EIO, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
276 X(READFAIL, ENOLINK, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
277 X(READFAIL, ENOSPC, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
278 X(READFAIL, ENOSTR, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
279 X(READFAIL, ENXIO, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
280 X(READFAIL, EPIPE, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
281 X(READFAIL, ERANGE, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
282 X(READFAIL, EFAULT, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
283 X(READFAIL, EROFS, LIBKRRP_EMSG_READFAIL, strerror(unix_errno)) \
284 X(READFAIL, 0, LIBKRRP_EMSG_READFAIL, \
285 krrp_unix_errno_to_str(unix_errno)) \
286 X(SENDFAIL, 0, LIBKRRP_EMSG_SENDFAIL, strerror(unix_errno)) \
287 X(SENDMBLKFAIL, 0, LIBKRRP_EMSG_SENDMBLKFAIL, strerror(unix_errno)) \
288 X(RECVFAIL, 0, LIBKRRP_EMSG_RECVFAIL, strerror(unix_errno)) \
289 X(UNEXPEND, 0, LIBKRRP_EMSG_UNEXPEND) \
290 X(BIGPAYLOAD, 0, LIBKRRP_EMSG_BIGPAYLOAD) \
291 X(UNEXPCLOSE, 0, LIBKRRP_EMSG_UNEXPCLOSE) \
292 X(SNAPFAIL, ENAMETOOLONG, LIBKRRP_EMSG_DSNAMETOOLONG) \
293 X(SNAPFAIL, 0, LIBKRRP_EMSG_SNAPFAIL, \
294 krrp_unix_errno_to_str(unix_errno)) \
295
296 #define LIBKRRP_ERRDESCR_SESS_STATUS_ERROR_MAP(X) \
297 LIBKRRP_ERRDESCR_SESS_ERROR_MAP(X) \
298 KRRP_ERRDESCR_SESS_COMMON_MAP(X) \
299
300 #define LIBKRRP_ERRDESCR_SERVER_ERROR_MAP(X) \
301 X(CREATEFAIL, 0, LIBKRRP_EMSG_CREATEFAIL) \
302 X(BINDFAIL, 0, LIBKRRP_EMSG_BINDFAIL) \
303 X(LISTENFAIL, 0, LIBKRRP_EMSG_LISTENFAIL) \
304 X(ADDR, EINVAL, LIBKRRP_EMSG_ADDR_INVAL) \
305
306
307 static libkrrp_errno_t
308 krrp_errno_to_libkrrp_errno(krrp_errno_t krrp_errno)
309 {
310 size_t i;
311
312 for (i = 0; i < krrp_errs_sz; i++) {
313 if (krrp_errs[i].krrp_errno == krrp_errno)
314 return (krrp_errs[i].libkrrp_errno);
315 }
316
317 return (LIBKRRP_ERRNO_UNKNOWN);
318 }
319
320 void
321 libkrrp_error_set(libkrrp_error_t *error, libkrrp_errno_t libkrrp_errno,
322 int unix_errno, uint32_t flags)
323 {
324 VERIFY(error != NULL);
325
326 error->libkrrp_errno = libkrrp_errno;
327 error->unix_errno = unix_errno;
328 error->flags = flags;
329 }
330
331 int
332 libkrrp_error_from_nvl(nvlist_t *nvl, libkrrp_error_t *error)
333 {
334 krrp_errno_t krrp_errno;
335 int unix_errno;
336 uint32_t flags;
337
338 ASSERT(error != NULL);
339
340 if (krrp_param_get(KRRP_PARAM_ERROR_CODE, nvl, &krrp_errno) != 0)
341 return (-1);
342
343 if (krrp_param_get(KRRP_PARAM_ERROR_EXCODE, nvl, &unix_errno) != 0)
344 return (-1);
345
346 if (krrp_param_get(KRRP_PARAM_ERROR_FLAGS, nvl, &flags) != 0)
347 return (-1);
348
349 libkrrp_error_set(error, krrp_errno_to_libkrrp_errno(krrp_errno),
350 unix_errno, flags | LIBKRRP_ERRF_KERNEL);
351
352 return (0);
353 }
354
355 boolean_t
356 libkrrp_error_cmp(libkrrp_errno_t libkrrp_errno,
357 libkrrp_errno_t m_libkrrp_errno, int unix_errno, int m_unix_errno,
358 int flags, char *descr, char *m_descr, ...)
359 {
360 va_list ap;
361
362 if ((libkrrp_errno == m_libkrrp_errno) &&
363 (m_unix_errno == 0 || unix_errno == m_unix_errno)) {
364 va_start(ap, m_descr);
365 (void) vsnprintf(descr, sizeof (libkrrp_error_descr_t),
366 dgettext(TEXT_DOMAIN, m_descr), ap);
367
368 if (flags & LIBKRRP_ERRF_REMOTE) {
369 (void) strlcat(descr, " (",
370 sizeof (libkrrp_error_descr_t));
371 (void) strlcat(descr, dgettext(TEXT_DOMAIN,
372 LIBKRRP_EMSG_REMOTE_NODE_ERROR),
373 sizeof (libkrrp_error_descr_t));
374 (void) strlcat(descr, ")",
375 sizeof (libkrrp_error_descr_t));
376 }
377
378 va_end(ap);
379 return (B_TRUE);
380 }
381
382 return (B_FALSE);
383 }
384
385 const libkrrp_error_t *
386 libkrrp_error(libkrrp_handle_t *hdl)
387 {
388 VERIFY(hdl != NULL);
389 return (&hdl->libkrrp_error);
390 }
391
392 void
393 libkrrp_set_error_description(libkrrp_handle_t *hdl, const char *descr)
394 {
395 VERIFY(hdl != NULL && hdl->libkrrp_error.libkrrp_errno != 0);
396
397 (void) strlcpy(hdl->libkrrp_error_descr,
398 descr, sizeof (libkrrp_error_descr_t));
399 }
400
401 const char *
402 libkrrp_error_description(libkrrp_handle_t *hdl)
403 {
404 /* LINTED: E_FUNC_SET_NOT_USED */
405 libkrrp_errno_t libkrrp_errno;
406 /* LINTED: E_FUNC_SET_NOT_USED */
407 int unix_errno;
408 int flags;
409 krrp_ioctl_cmd_t cmd;
410 char *descr;
411
412 VERIFY(hdl != NULL);
413
414 descr = hdl->libkrrp_error_descr;
415 if (descr[0] != '\0')
416 return (descr);
417
418 libkrrp_errno = hdl->libkrrp_error.libkrrp_errno;
419 unix_errno = hdl->libkrrp_error.unix_errno;
420 flags = hdl->libkrrp_error.flags;
421 cmd = hdl->libkrrp_last_cmd;
422
423 if (flags & LIBKRRP_ERRF_KERNEL) {
424 switch (cmd) {
425 #define KRRP_IOCTL_EXPAND(cmd_m) \
426 case KRRP_IOCTL_##cmd_m: \
427 SET_ERROR_DESCR(KRRP_ERRDESCR_##cmd_m##_MAP); \
428 break;
429
430 KRRP_IOCTL_MAP(KRRP_IOCTL_EXPAND)
431 #undef KRRP_IOCTL_EXPAND
432 default:
433 break;
434 }
435 } else {
436 SET_ERROR_DESCR(LIBKRRP_ERRDESCR_MAP);
437 }
438
439 if (descr[0] == '\0') {
440 (void) snprintf(descr, sizeof (libkrrp_error_descr_t) - 1,
441 dgettext(TEXT_DOMAIN, LIBKRRP_EMSG_UNKNOWN));
442 }
443
444 return (descr);
445 }
446
447 const char
448 *krrp_unix_errno_to_str(int unix_errno)
449 {
450 size_t i;
451 for (i = 0; i < unix_errnos_sz; i++) {
452 if (unix_errnos[i].errno_num == unix_errno)
453 return (unix_errnos[i].errno_str);
454 }
455
456 return ("UNIX_ERRNO_UNKNOWN");
457 }
458
459 void
460 libkrrp_common_error_description(libkrrp_error_type_t error_type,
461 libkrrp_error_t *error, libkrrp_error_descr_t descr)
462 {
463 /* LINTED: E_FUNC_SET_NOT_USED */
464 libkrrp_errno_t libkrrp_errno;
465 /* LINTED: E_FUNC_SET_NOT_USED */
466 int unix_errno;
467 /* LINTED: E_FUNC_SET_NOT_USED */
468 int flags;
469
470 VERIFY(error != NULL);
471
472 descr[0] = '\0';
473 libkrrp_errno = error->libkrrp_errno;
474 unix_errno = error->unix_errno;
475 flags = error->flags;
476
477 switch (error_type) {
478 case LIBKRRP_SRV_ERROR:
479 SET_ERROR_DESCR(LIBKRRP_ERRDESCR_SERVER_ERROR_MAP);
480 break;
481 case LIBKRRP_SESS_ERROR:
482 SET_ERROR_DESCR(LIBKRRP_ERRDESCR_SESS_ERROR_MAP);
483 break;
484 case LIBKRRP_SESS_STATUS_ERROR:
485 SET_ERROR_DESCR(LIBKRRP_ERRDESCR_SESS_STATUS_ERROR_MAP);
486 break;
487 default:
488 break;
489 }
490
491 if (descr[0] == '\0') {
492 (void) snprintf(descr,
493 sizeof (libkrrp_error_descr_t) - 1,
494 dgettext(TEXT_DOMAIN, LIBKRRP_EMSG_UNKNOWN));
495 }
496 }
497
498 void
499 libkrrp_sess_error_description(libkrrp_error_t *error,
500 libkrrp_error_descr_t descr)
501 {
502 libkrrp_common_error_description(LIBKRRP_SESS_STATUS_ERROR,
503 error, descr);
504 }