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 #ifndef _LIBKRRP_ERROR_H
17 #define _LIBKRRP_ERROR_H
18
19 #include <sys/nvpair.h>
20
21 #include "libkrrp.h"
22 #include "krrp_error.h"
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 typedef enum {
29 LIBKRRP_SESS_ERROR,
30 LIBKRRP_SRV_ERROR,
31 LIBKRRP_SESS_STATUS_ERROR
32 } libkrrp_error_type_t;
33
34 #define LIBKRRP_ERRDESCR_EXPAND(m_libkrrp_errno, m_unix_errno, m_descr, ...) \
35 libkrrp_error_cmp(libkrrp_errno, LIBKRRP_ERRNO_##m_libkrrp_errno, \
36 unix_errno, m_unix_errno, flags, (char *)descr, \
37 m_descr, ##__VA_ARGS__) ||
38
39 #define SET_ERROR_DESCR(X) (void) (X(LIBKRRP_ERRDESCR_EXPAND) B_FALSE)
40
41 #define LIBKRRP_EMSG_IOCTLFAIL "ioctl failed (%s)"
42 #define LIBKRRP_EMSG_SVCACTIVE "Service is already enabled"
43 #define LIBKRRP_EMSG_SVCNOTACTIVE "Service is not enabled"
44 #define LIBKRRP_EMSG_NOTSUP "Operation is not supported"
45 #define LIBKRRP_EMSG_IOCTLDATAFAIL "Failed to unpack ioctl data"
46 #define LIBKRRP_EMSG_EVBINDFAIL "Failed to bind to KRRP event channel"
47 #define LIBKRRP_EMSG_EVSUBSCRIBEFAIL "Failed to subscribe to KRRP event channel"
48 #define LIBKRRP_EMSG_EVREADFAIL "Failed to read event data"
49 #define LIBKRRP_EMSG_BUSY "KRRP service is busy"
50 #define LIBKRRP_EMSG_SESSID_NOENT "Session ID not specified"
51 #define LIBKRRP_EMSG_SESSID_INVAL "Invalid session id"
52 #define LIBKRRP_EMSG_SESSERR_INVAL "Invalid session error"
53 #define LIBKRRP_EMSG_KSTATID_NOENT "kstat ID not specified"
54 #define LIBKRRP_EMSG_KSTATID_INVAL "kstat ID must be %d characters in length"
55 #define LIBKRRP_EMSG_SESS_ALREADY "Session already exists"
56 #define LIBKRRP_EMSG_SESS_NOENT "Session does not exist"
57 #define LIBKRRP_EMSG_SESS_NODATA1 "Session private data not specified"
58 #define LIBKRRP_EMSG_SESS_NODATA2 "Session private data does not exist"
59 #define LIBKRRP_EMSG_HOST_NOENT "Remote host is not specified"
60 #define LIBKRRP_EMSG_SESS_BUSY "Session is busy"
61 #define LIBKRRP_EMSG_HOST_INVAL "Invalid remote host"
62 #define LIBKRRP_EMSG_ADDR_INVAL "Invalid listening address"
63 #define LIBKRRP_EMSG_PORT_NOENT "Remote port not specified"
64 #define LIBKRRP_EMSG_PORT_INVAL "Remote port must be in range (%d .. %d)"
65 #define LIBKRRP_EMSG_SESS_CONN_ALREADY "Session connection already exists"
66 #define LIBKRRP_EMSG_CREATEFAIL "Failed to create socket (%s)"
67 #define LIBKRRP_EMSG_SETSOCKOPTFAIL "Failed to set socket options (%s)"
68 #define LIBKRRP_EMSG_CONNFAIL "Failed to connect socket (%s)"
69 #define LIBKRRP_EMSG_SENDFAIL "Failed to send data (%s)"
70 #define LIBKRRP_EMSG_RECVFAIL "Failed to receive data (%s)"
71 #define LIBKRRP_EMSG_UNEXPCLOSE "Connection unexpectedly closed"
72 #define LIBKRRP_EMSG_UNEXPEND "Connection unexpectedly ended"
73 #define LIBKRRP_EMSG_AUTH_NOENT "Authentication data not specified"
74 #define LIBKRRP_EMSG_BADRESP "Unexpected response has been received"
75 #define LIBKRRP_EMSG_NOMEM "Not enough space"
76 #define LIBKRRP_EMSG_BIGPAYLOAD "Payload is too big"
77 #define LIBKRRP_EMSG_SESS_PDUENGINE_ALREADY "PDU engine already exists"
78 #define LIBKRRP_EMSG_DBLKSZ_NOENT "dblk size not specified"
79 #define LIBKRRP_EMSG_DBLKSZ_INVAL "dblk size must be in range (%d .. %d)"
80 #define LIBKRRP_EMSG_MAXMEMSZ_NOENT "Maximum memory size not specified"
81 #define LIBKRRP_EMSG_MAXMEMSZ_INVAL "Maximum memory size cannot be less than %d"
82 #define LIBKRRP_EMSG_SESS_PDUENGINE_NOMEM "Failed to preallocate PDUs"
83 #define LIBKRRP_EMSG_FAKEDSZ_NOENT "Fake stream size not specified"
84 #define LIBKRRP_EMSG_FAKEDSZ_INVAL "Fake stream size cannot be 0"
85 #define LIBKRRP_EMSG_ZFSGCTXFAIL "Failed to initialize global ZFS context"
86 #define LIBKRRP_EMSG_SRCDS_NOENT "Source dataset not specified"
87 #define LIBKRRP_EMSG_SRCDS_INVAL "Invalid source dataset"
88 #define LIBKRRP_EMSG_SRCSNAP_INVAL "Invalid source snapshot"
89 #define LIBKRRP_EMSG_CMNSNAP_INVAL "Invalid common snapshot"
90 #define LIBKRRP_EMSG_SESS_STREAM_ALREADY "Session stream already exists"
91 #define LIBKRRP_EMSG_DSTDS_NOENT "Destination dataset not specified"
92 #define LIBKRRP_EMSG_DSTDS_INVAL "Invalid destination dataset"
93 #define LIBKRRP_EMSG_SESS_STARTED "Session already started"
94 #define LIBKRRP_EMSG_SESS_CONN_NOENT "Session connection does not exist"
95 #define LIBKRRP_EMSG_SESS_PDUENGINE_NOENT "Session PDU engine does not exist"
96 #define LIBKRRP_EMSG_STREAM_NOENT "Stream does not exist"
97 #define LIBKRRP_EMSG_STREAM_EOPNOTSUPP "The source dataset for continuous " \
98 "replication must not have WBC enabled parents"
99 #define LIBKRRP_EMSG_SNAP_NAMES_EQUAL \
100 "Source and common snapshots have the same name"
101 #define LIBKRRP_EMSG_SESS_RUN_ONCE_INCOMPAT \
102 "Cannot run non-continuous stream once"
103 #define LIBKRRP_EMSG_SRCDS_NOTEXIST "Source dataset does not exist"
104 #define LIBKRRP_EMSG_DSTDS_NOTEXIST "Destination dataset does not exist"
105 #define LIBKRRP_EMSG_SRCSNAP_NOTEXIST "Source snapshot does not exist"
106 #define LIBKRRP_EMSG_CMNSNAP_NOTEXIST "Common snapshot does not exist"
107 #define LIBKRRP_EMSG_SESS_THROTTLE_RECV \
108 "Throttle limit can be set only for sender session"
109 #define LIBKRRP_EMSG_SESS_SEND_STOP_ALREADY "Session is already stopping"
110 #define LIBKRRP_EMSG_SESS_SEND_STOP_RECV "Cannot stop session " \
111 "at the receiver side"
112 #define LIBKRRP_EMSG_SESS_NOTACTIVE "Session is not running"
113 #define LIBKRRP_EMSG_CFGTYPE_NOENT "Configuration type not specified"
114 #define LIBKRRP_EMSG_CFGTYPE_INVAL "Invalid configuration type"
115 #define LIBKRRP_EMSG_BINDFAIL "Failed to bind socket (%s)"
116 #define LIBKRRP_EMSG_LISTENFAIL "Failed to listen socket (%s)"
117 #define LIBKRRP_EMSG_LSTPORT_NOENT "Listening port is not defined"
118 #define LIBKRRP_EMSG_LSTPORT_INVAL "Listenng port must be in range (%d .. %d)"
119 #define LIBKRRP_EMSG_SRVRECONF "Server is in re-configuring state"
120 #define LIBKRRP_EMSG_SRVNOTRUN "Server is not running"
121 #define LIBKRRP_EMSG_SESSPINGTIMEOUT "Session ping timeout"
122 #define LIBKRRP_EMSG_OK "No error"
123 #define LIBKRRP_EMSG_UNKNOWN "Unknown error"
124 #define LIBKRRP_EMSG_NOORIGIN "Destination does not have origin snapshot"
125 #define LIBKRRP_EMSG_WRITEFAIL "Session write stream error (%s)"
126 #define LIBKRRP_EMSG_SNAPMISMATCH "Most recent snapshot does not match " \
127 "incremental source"
128 #define LIBKRRP_EMSG_DESTMODIFIED "Destination has been modified since most " \
129 "recent snapshot"
130 #define LIBKRRP_EMSG_DESTEXISTS "Destination already exists"
131 #define LIBKRRP_EMSG_WRITEINVAL "Invalid stream"
132 #define LIBKRRP_EMSG_CHKSUMMISMATCH "Invalid stream (checksum mismatch)"
133 #define LIBKRRP_EMSG_OLDPOOL "Pool must be upgraded to receive this stream"
134 #define LIBKRRP_EMSG_DESTQUOTA "Destination space quota exceeded"
135 #define LIBKRRP_EMSG_DESTNOSPACE "Destination is out of space"
136 #define LIBKRRP_EMSG_READFAIL "Session read stream error (%s)"
137 #define LIBKRRP_EMSG_NOTEARLIERSNAP \
138 "Not an earlier snapshot from the same fs"
139 #define LIBKRRP_EMSG_SENDMBLKFAIL "ksocket_sendmblk error (%s)"
140 #define LIBKRRP_EMSG_SNAPFAIL "Failed to create snapshot (%s)"
141 #define LIBKRRP_EMSG_CONNTIMEOUT_INVAL \
142 "Connection timeout must be in range (%d .. %d)"
143 #define LIBKRRP_EMSG_REMOTE_NODE_ERROR "remote node error"
144 #define LIBKRRP_EMSG_THROTTLE_NOENT "Throttle limit not specified"
145 #define LIBKRRP_EMSG_THROTTLE_INVAL \
146 "Throttle limit must be 0 or greater than or equal to %d"
147 #define LIBKRRP_EMSG_AUTOSNAP_INVAL \
148 "Impossible to activate ZFS Autosnap for given dataset"
149 #define LIBKRRP_EMSG_SESS_CREATE_WRITE_STREAM_FAIL \
150 "Cannot create write stream for sender session"
151 #define LIBKRRP_EMSG_SESS_CREATE_READ_STREAM_FAIL \
152 "Cannot create read stream for receiver or fake compound session"
153 #define LIBKRRP_EMSG_SESS_CREATE_INVAL "Cannot create compound session with " \
154 "the sender flag or the authentication digest"
155 #define LIBKRRP_EMSG_SESS_CREATE_CONN_INVAL \
156 "Cannot create connection for compound session"
157
158 #define LIBKRRP_EMSG_RESUMETOKEN_INVAL \
159 "Resume token is corrupt (invalid format)"
160 #define LIBKRRP_EMSG_RESUMETOKEN_ENOTSUP \
161 "Resume token is corrupt (invalid version)"
162 #define LIBKRRP_EMSG_RESUMETOKEN_EBADMSG \
163 "Resume token is corrupt (payload is not hex-encoded)"
164 #define LIBKRRP_EMSG_RESUMETOKEN_ECKSUM \
165 "Resume token is corrupt (incorrect checksum failed)"
166 #define LIBKRRP_EMSG_RESUMETOKEN_ENOSR \
167 "Resume token is corrupt (decompression failed)"
168 #define LIBKRRP_EMSG_RESUMETOKEN_ENODATA \
169 "Resume token is corrupt (nvlist_unpack failed)"
170
171 #define LIBKRRP_EMSG_SKIP_SNAPS_MASK_EINVAL \
172 "Skip snapshots mask is invalid"
173 #define LIBKRRP_EMSG_SKIP_SNAPS_MASK_EMSGSIZE \
174 "Skip snapshots mask is too long"
175 #define LIBKRRP_EMSG_SKIP_SNAPS_MASK_ENAMETOOLONG \
176 "Skip snapshots mask (property name) is too long"
177 #define LIBKRRP_EMSG_SKIP_SNAPS_MASK_E2BIG \
178 "Skip snapshots mask (property value) is too long"
179
180 #define LIBKRRP_EMSG_RUN_ONCE_RECV "Impossible to use the option 'run-once' " \
181 "at the receiver side"
182 #define LIBKRRP_EMSG_STREAM_POOL_FAULT "Failed to read configuration of " \
183 "target ZFS pool"
184 #define LIBKRRP_EMSG_SESS_CREATE_AUTH_INVAL "Authentication digest " \
185 "must not be greater than %d characters in length"
186 #define LIBKRRP_EMSG_DSNAMETOOLONG "Failed to create autosnapshot: " \
187 "dataset name too long"
188 #define LIBKRRP_EMSG_CANNOT_STOP_SESS "Cannot stop non-continuous session"
189 #define LIBKRRP_EMSG_SESS_CREATE_CONN_AUTH_INVAL "Invalid authentication digest"
190 #define LIBKRRP_EMSG_KEEPSNAPS_INVAL \
191 "The number of keep snapshots must be in range (%d .. %d)"
192 #define LIBKRRP_EMSG_SESS_ENOTSUP \
193 "Operation is not supported for this type of session"
194 #define LIBKRRP_EMSG_PROPS_INVAL "Failed to validate ZFS properties"
195 #define LIBKRRP_EMSG_PROPS_ENOMEM "Failed to initialize ZFS library"
196
197 #define libkrrp_error_init(error) (void) memset(error, 0, \
198 sizeof (libkrrp_error_t));
199
200 #define LIBKRRP_ERRDESCR_MAP(X) \
201 X(SVCNOTACTIVE, 0, LIBKRRP_EMSG_SVCNOTACTIVE) \
202 X(SVCACTIVE, 0, LIBKRRP_EMSG_SVCACTIVE) \
203 X(IOCTLFAIL, 0, LIBKRRP_EMSG_IOCTLFAIL, \
204 krrp_unix_errno_to_str(unix_errno)) \
205 X(NOTSUP, 0, LIBKRRP_EMSG_NOTSUP) \
206 X(IOCTLDATAFAIL, 0, LIBKRRP_EMSG_IOCTLDATAFAIL) \
207 X(KSTATID, EINVAL, LIBKRRP_EMSG_KSTATID_INVAL, \
208 KRRP_KSTAT_ID_STRING_LENGTH - 1) \
209 X(NOMEM, 0, LIBKRRP_EMSG_NOMEM) \
210 X(SESSID, EINVAL, LIBKRRP_EMSG_SESSID_INVAL) \
211 X(SESSID, ENOENT, LIBKRRP_EMSG_SESSID_NOENT) \
212 X(SESSERR, EINVAL, LIBKRRP_EMSG_SESSERR_INVAL) \
213 X(OK, 0, LIBKRRP_EMSG_OK) \
214 X(EVBINDFAIL, 0, LIBKRRP_EMSG_EVBINDFAIL) \
215 X(EVSUBSRIBEFAIL, 0, LIBKRRP_EMSG_EVSUBSCRIBEFAIL) \
216 X(EVREADFAIL, 0, LIBKRRP_EMSG_EVREADFAIL) \
217 X(PROPS, EINVAL, LIBKRRP_EMSG_PROPS_INVAL) \
218 X(PROPS, ENOMEM, LIBKRRP_EMSG_PROPS_ENOMEM) \
219
220 #define UNIX_ERRNO_MAP(X) \
221 X(EPERM) /* Not super-user */ \
222 X(ENOENT) /* No such file or directory */ \
223 X(ESRCH) /* No such process */ \
224 X(EINTR) /* interrupted system call */ \
225 X(EIO) /* I/O error */ \
226 X(ENXIO) /* No such device or address */ \
227 X(E2BIG) /* Arg list too long */ \
228 X(ENOEXEC) /* Exec format error */ \
229 X(EBADF) /* Bad file number */ \
230 X(ECHILD) /* No children */ \
231 X(EAGAIN) /* Resource temporarily unavailable */ \
232 X(ENOMEM) /* Not enough core */ \
233 X(EACCES) /* Permission denied */ \
234 X(EFAULT) /* Bad address */ \
235 X(ENOTBLK) /* Block device required */ \
236 X(EBUSY) /* Mount device busy */ \
237 X(EEXIST) /* File exists */ \
238 X(EXDEV) /* Cross-device link */ \
239 X(ENODEV) /* No such device */ \
240 X(ENOTDIR) /* Not a directory */ \
241 X(EISDIR) /* Is a directory */ \
242 X(EINVAL) /* Invalid argument */ \
243 X(ENFILE) /* File table overflow */ \
244 X(EMFILE) /* Too many open files */ \
245 X(ENOTTY) /* Inappropriate ioctl for device */ \
246 X(ETXTBSY) /* Text file busy */ \
247 X(EFBIG) /* File too large */ \
248 X(ENOSPC) /* No space left on device */ \
249 X(ESPIPE) /* Illegal seek */ \
250 X(EROFS) /* Read only file system */ \
251 X(EMLINK) /* Too many links */ \
252 X(EPIPE) /* Broken pipe */ \
253 X(EDOM) /* Math arg out of domain of func */ \
254 X(ERANGE) /* Math result not representable */ \
255 X(ENOMSG) /* No message of desired type */ \
256 X(EIDRM) /* Identifier removed */ \
257 X(ECHRNG) /* Channel number out of range */ \
258 X(EL2NSYNC) /* Level 2 not synchronized */ \
259 X(EL3HLT) /* Level 3 halted */ \
260 X(EL3RST) /* Level 3 reset */ \
261 X(ELNRNG) /* Link number out of range */ \
262 X(EUNATCH) /* Protocol driver not attached */ \
263 X(ENOCSI) /* No CSI structure available */ \
264 X(EL2HLT) /* Level 2 halted */ \
265 X(EDEADLK) /* Deadlock condition. */ \
266 X(ENOLCK) /* No record locks available. */ \
267 X(ECANCELED) /* Operation canceled */ \
268 X(ENOTSUP) /* Operation not supported */ \
269 \
270 /* Filesystem Quotas */ \
271 X(EDQUOT) /* Disc quota exceeded */ \
272 \
273 /* Convergent Error Returns */ \
274 X(EBADE) /* invalid exchange */ \
275 X(EBADR) /* invalid request descriptor */ \
276 X(EXFULL) /* exchange full */ \
277 X(ENOANO) /* no anode */ \
278 X(EBADRQC) /* invalid request code */ \
279 X(EBADSLT) /* invalid slot */ \
280 X(EDEADLOCK) /* file locking deadlock error */ \
281 \
282 X(EBFONT) /* bad font file fmt */ \
283 \
284 /* Interprocess Robust Locks */ \
285 X(EOWNERDEAD) /* process died with the lock */ \
286 X(ENOTRECOVERABLE) /* lock is not recoverable */ \
287 \
288 /* stream problems */ \
289 X(ENOSTR) /* Device not a stream */ \
290 X(ENODATA) /* no data (for no delay io) */ \
291 X(ETIME) /* timer expired */ \
292 X(ENOSR) /* out of streams resources */ \
293 \
294 X(ENONET) /* Machine is not on the network */ \
295 X(ENOPKG) /* Package not installed */ \
296 X(EREMOTE) /* The object is remote */ \
297 X(ENOLINK) /* the link has been severed */ \
298 X(EADV) /* advertise error */ \
299 X(ESRMNT) /* srmount error */ \
300 \
301 X(ECOMM) /* Communication error on send */ \
302 X(EPROTO) /* Protocol error */ \
303 \
304 /* Interprocess Robust Locks */ \
305 X(ELOCKUNMAPPED) /* locked lock was unmapped */ \
306 \
307 X(ENOTACTIVE) /* Facility is not active */ \
308 X(EMULTIHOP) /* multihop attempted */ \
309 X(EBADMSG) /* trying to read unreadable message */ \
310 X(ENAMETOOLONG) /* path name is too long */ \
311 X(EOVERFLOW) /* value too large to be stored in data type */ \
312 X(ENOTUNIQ) /* given log. name not unique */ \
313 X(EBADFD) /* f.d. invalid for this operation */ \
314 X(EREMCHG) /* Remote address changed */ \
315 \
316 /* shared library problems */ \
317 X(ELIBACC) /* Can't access a needed shared lib. */ \
318 X(ELIBBAD) /* Accessing a corrupted shared lib. */ \
319 X(ELIBSCN) /* .lib section in a.out corrupted. */ \
320 X(ELIBMAX) /* Attempting to link in too many libs. */ \
321 X(ELIBEXEC) /* Attempting to exec a shared library. */ \
322 X(EILSEQ) /* Illegal byte sequence. */ \
323 X(ENOSYS) /* Unsupported file system operation */ \
324 X(ELOOP) /* Symbolic link loop */ \
325 X(ERESTART) /* Restartable system call */ \
326 X(ESTRPIPE) /* if pipe/FIFO, don't sleep in stream head */ \
327 X(ENOTEMPTY) /* directory not empty */ \
328 X(EUSERS) /* Too many users (for UFS) */ \
329 \
330 /* BSD Networking Software argument errors */ \
331 X(ENOTSOCK) /* Socket operation on non-socket */ \
332 X(EDESTADDRREQ) /* Destination address required */ \
333 X(EMSGSIZE) /* Message too long */ \
334 X(EPROTOTYPE) /* Protocol wrong type for socket */ \
335 X(ENOPROTOOPT) /* Protocol not available */ \
336 X(EPROTONOSUPPORT) /* Protocol not supported */ \
337 X(ESOCKTNOSUPPORT) /* Socket type not supported */ \
338 X(EOPNOTSUPP) /* Operation not supported on socket */ \
339 X(EPFNOSUPPORT) /* Protocol family not supported */ \
340 X(EAFNOSUPPORT) /* Address family not supported by protocol family */ \
341 X(EADDRINUSE) /* Address already in use */ \
342 X(EADDRNOTAVAIL) /* Can't assign requested address */ \
343 \
344 /* operational errors */ \
345 X(ENETDOWN) /* Network is down */ \
346 X(ENETUNREACH) /* Network is unreachable */ \
347 X(ENETRESET) /* Network dropped connection because of reset */ \
348 X(ECONNABORTED) /* Software caused connection abort */ \
349 X(ECONNRESET) /* Connection reset by peer */ \
350 X(ENOBUFS) /* No buffer space available */ \
351 X(EISCONN) /* Socket is already connected */ \
352 X(ENOTCONN) /* Socket is not connected */ \
353 /* XENIX has 135 - 142 */ \
354 X(ESHUTDOWN) /* Can't send after socket shutdown */ \
355 X(ETOOMANYREFS) /* Too many references: can't splice */ \
356 X(ETIMEDOUT) /* Connection timed out */ \
357 X(ECONNREFUSED) /* Connection refused */ \
358 X(EHOSTDOWN) /* Host is down */ \
359 X(EHOSTUNREACH) /* No route to host */ \
360 X(EALREADY) /* operation already in progress */ \
361 X(EINPROGRESS) /* operation now in progress */ \
362 \
363 /* SUN Network File System */ \
364 X(ESTALE) /* Stale NFS file handle */ \
365
366 int libkrrp_error_from_nvl(nvlist_t *, libkrrp_error_t *);
367 void libkrrp_error_set(libkrrp_error_t *, libkrrp_errno_t, int, uint32_t);
368 boolean_t libkrrp_error_cmp(libkrrp_errno_t, libkrrp_errno_t, int, int, int,
369 char *, char *, ...);
370 const char *krrp_unix_errno_to_str(int);
371 void libkrrp_common_error_description(libkrrp_error_type_t,
372 libkrrp_error_t *, libkrrp_error_descr_t);
373 void libkrrp_set_error_description(libkrrp_handle_t *hdl, const char *descr);
374 #ifdef __cplusplus
375 }
376 #endif
377
378 #endif /* _LIBKRRP_ERROR_H */