4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2017, Joyent, Inc.
27 #include <sys/types.h>
28 #include <sys/isa_defs.h>
29 #include <sys/systeminfo.h>
30 #include <sys/scsi/generic/commands.h>
31 #include <sys/scsi/impl/commands.h>
32 #include <sys/scsi/impl/uscsi.h>
41 #include <scsi/libscsi.h>
42 #include "libscsi_impl.h"
44 static const libscsi_engine_t
*
45 get_engine(libscsi_hdl_t
*hp
, const char *name
)
47 libscsi_engine_impl_t
*eip
;
48 const libscsi_engine_t
*ep
;
49 const char *engine_path
, *p
, *q
;
50 char engine_dir
[MAXPATHLEN
];
51 char engine_lib
[MAXPATHLEN
];
52 char init_name
[MAXPATHLEN
];
54 libscsi_engine_init_f init
;
55 boolean_t found_lib
= B_FALSE
, found_init
= B_FALSE
;
59 for (eip
= hp
->lsh_engines
; eip
!= NULL
; eip
= eip
->lsei_next
) {
60 if (strcmp(eip
->lsei_engine
->lse_name
, name
) == 0)
61 return (eip
->lsei_engine
);
64 if ((engine_path
= getenv("LIBSCSI_ENGINE_PATH")) == NULL
)
65 engine_path
= LIBSCSI_DEFAULT_ENGINE_PATH
;
73 for (p
= engine_path
; p
!= NULL
; p
= q
) {
74 if ((q
= strchr(p
, ':')) != NULL
) {
75 ptrdiff_t len
= q
- p
;
76 (void) strncpy(engine_dir
, p
, len
);
77 engine_dir
[len
] = '\0';
85 (void) strcpy(engine_dir
, p
);
87 if (engine_dir
[0] != '/')
92 (void) snprintf(engine_lib
, MAXPATHLEN
, "%s/%s/%s%s",
93 engine_dir
, isa
, name
, LIBSCSI_ENGINE_EXT
);
95 dl_hdl
= dlopen(engine_lib
,
96 RTLD_LOCAL
| RTLD_LAZY
| RTLD_PARENT
);
99 (void) libscsi_error(hp
, ESCSI_NOENGINE
,
100 "unable to dlopen %s: %s", engine_lib
,
105 (void) snprintf(init_name
, MAXPATHLEN
, "libscsi_%s_init", name
);
106 init
= (libscsi_engine_init_f
)dlsym(dl_hdl
, init_name
);
109 (void) libscsi_error(hp
, ESCSI_NOENGINE
,
110 "failed to find %s in %s: %s", init_name
,
111 engine_lib
, dlerror());
112 (void) dlclose(dl_hdl
);
115 if ((ep
= init(hp
)) == NULL
) {
116 (void) dlclose(dl_hdl
);
118 * libscsi errno set by init.
122 if (ep
->lse_libversion
!= hp
->lsh_version
) {
123 (void) dlclose(dl_hdl
);
124 (void) libscsi_error(hp
, ESCSI_ENGINE_VER
, "engine "
125 "%s version %u does not match library version %u",
126 engine_lib
, ep
->lse_libversion
, hp
->lsh_version
);
130 eip
= libscsi_zalloc(hp
, sizeof (libscsi_engine_impl_t
));
132 (void) dlclose(dl_hdl
);
135 eip
->lsei_engine
= ep
;
136 eip
->lsei_dl_hdl
= dl_hdl
;
137 eip
->lsei_next
= hp
->lsh_engines
;
138 hp
->lsh_engines
= eip
;
144 (void) libscsi_error(hp
, ESCSI_ENGINE_BADPATH
, "no valid "
145 "directories found in engine path %s", engine_path
);
151 scsi_parse_mtbf(const char *envvar
, uint_t
*intp
)
156 if ((strval
= getenv(envvar
)) != NULL
&&
157 (intval
= atoi(strval
)) > 0) {
158 srand48(gethrtime());
164 libscsi_open(libscsi_hdl_t
*hp
, const char *engine
, const void *target
)
166 const libscsi_engine_t
*ep
;
167 libscsi_target_t
*tp
;
170 if (engine
== NULL
) {
171 if ((engine
= getenv("LIBSCSI_DEFAULT_ENGINE")) == NULL
)
172 engine
= LIBSCSI_DEFAULT_ENGINE
;
175 if ((ep
= get_engine(hp
, engine
)) == NULL
)
178 if ((tp
= libscsi_zalloc(hp
, sizeof (libscsi_target_t
))) == NULL
)
181 if ((private = ep
->lse_ops
->lseo_open(hp
, target
)) == NULL
) {
182 libscsi_free(hp
, tp
);
186 scsi_parse_mtbf("LIBSCSI_MTBF_CDB", &tp
->lst_mtbf_cdb
);
187 scsi_parse_mtbf("LIBSCSI_MTBF_READ", &tp
->lst_mtbf_read
);
188 scsi_parse_mtbf("LIBSCSI_MTBF_WRITE", &tp
->lst_mtbf_write
);
192 tp
->lst_priv
= private;
196 if (libscsi_get_inquiry(hp
, tp
) != 0) {
197 libscsi_close(hp
, tp
);
205 libscsi_get_handle(libscsi_target_t
*tp
)
207 return (tp
->lst_hdl
);
211 libscsi_close(libscsi_hdl_t
*hp
, libscsi_target_t
*tp
)
213 tp
->lst_engine
->lse_ops
->lseo_close(hp
, tp
->lst_priv
);
214 libscsi_free(hp
, tp
->lst_vendor
);
215 libscsi_free(hp
, tp
->lst_product
);
216 libscsi_free(hp
, tp
->lst_revision
);
217 libscsi_free(hp
, tp
);
222 libscsi_action_get_status(const libscsi_action_t
*ap
)
224 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
226 return (aip
->lsai_status
);
230 * Set the timeout in seconds for this action. If no timeout is specified
231 * or if the timeout is set to 0, an implementation-specific timeout will be
232 * used (which may vary based on the target, command or other variables).
233 * Not all engines support all timeout values. Setting the timeout to a value
234 * not supported by the engine will cause engine-defined behavior when the
235 * action is executed.
238 libscsi_action_set_timeout(libscsi_action_t
*ap
, uint32_t timeout
)
240 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
242 aip
->lsai_timeout
= timeout
;
246 * Obtain the timeout setting for this action.
249 libscsi_action_get_timeout(const libscsi_action_t
*ap
)
251 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
253 return (aip
->lsai_timeout
);
257 * Returns the flags associated with this action. Never fails.
260 libscsi_action_get_flags(const libscsi_action_t
*ap
)
262 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
264 return (aip
->lsai_flags
);
268 * Return the length of the CDB buffer associated with this action. Never
272 libscsi_action_get_cdblen(const libscsi_action_t
*ap
)
274 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
276 return (aip
->lsai_cdb_len
);
280 * Returns the address of the action's CDB. The CDB buffer is guaranteed to
281 * be large enough to hold the complete CDB for the command specified when the
282 * action was allocated. Therefore, changing the command/opcode portion of
283 * the CDB has undefined effects. The remainder of the CDB may be modified.
286 libscsi_action_get_cdb(const libscsi_action_t
*ap
)
288 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
290 return (aip
->lsai_cdb
);
294 * Places the address of the action buffer in the location pointed to by bp,
295 * if bp is not NULL. If ap is not NULL, it will contain the allocated size
296 * of the buffer itself. If vp is not NULL, it will contain the number of
297 * bytes of valid data currently stored in the buffer.
299 * If the action has LIBSCSI_AF_WRITE set and it has not yet been executed
300 * successfully, the entire buffer is assumed to contain valid data.
302 * If the action has LIBSCSI_AF_READ set and it has not yet been executed
303 * successfully, the amount of valid data is 0.
305 * If both LIBSCSI_AF_READ and LIBSCSI_AF_WRITE are clear, this function
306 * fails with ESCSI_BADFLAGS to indicate that the action flags are
307 * incompatible with the action data buffer.
310 libscsi_action_get_buffer(const libscsi_action_t
*ap
, uint8_t **bp
,
311 size_t *sp
, size_t *vp
)
313 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
315 if ((aip
->lsai_flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
)) == 0)
316 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
317 "data buffer not supported for actions with both "
318 "LIBSCSI_AF_READ and LIBSCSI_AF_WRITE clear"));
320 if ((aip
->lsai_flags
& LIBSCSI_AF_WRITE
) &&
321 aip
->lsai_status
== LIBSCSI_STATUS_INVALID
) {
323 *bp
= aip
->lsai_data
;
325 *sp
= aip
->lsai_data_alloc
;
327 *vp
= aip
->lsai_data_alloc
;
332 if ((aip
->lsai_flags
& LIBSCSI_AF_READ
) &&
333 aip
->lsai_status
!= LIBSCSI_STATUS_INVALID
) {
335 *bp
= aip
->lsai_data
;
337 *sp
= aip
->lsai_data_alloc
;
339 *vp
= aip
->lsai_data_len
;
344 if (aip
->lsai_flags
& LIBSCSI_AF_WRITE
) {
353 *bp
= aip
->lsai_data
;
355 *sp
= aip
->lsai_data_alloc
;
364 * Obtain a pointer to the sense buffer for this action, if any, along with
365 * the size of the sense buffer and the amount of valid data it contains.
368 libscsi_action_get_sense(const libscsi_action_t
*ap
, uint8_t **bp
,
369 size_t *sp
, size_t *vp
)
371 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
373 if (!(aip
->lsai_flags
& LIBSCSI_AF_RQSENSE
))
374 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
375 "sense data unavailable: LIBSCSI_AF_RQSENSE is clear"));
378 if (aip
->lsai_status
== LIBSCSI_STATUS_INVALID
)
381 *vp
= aip
->lsai_sense_len
;
385 ASSERT(aip
->lsai_sense_data
!= NULL
);
386 *bp
= aip
->lsai_sense_data
;
396 * Set the SCSI status of the action.
401 libscsi_action_set_status(libscsi_action_t
*ap
, sam4_status_t status
)
403 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
405 ASSERT(aip
->lsai_status
== LIBSCSI_STATUS_INVALID
);
407 aip
->lsai_status
= status
;
411 * Set the length of valid data returned by a READ action. If the action is
412 * not a READ action, or the length exceeds the size of the buffer, an error
418 libscsi_action_set_datalen(libscsi_action_t
*ap
, size_t len
)
420 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
422 if ((aip
->lsai_flags
& LIBSCSI_AF_READ
) == 0)
423 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
424 "data cannot be returned for actions with LIBSCSI_AF_READ "
426 if (len
> aip
->lsai_data_alloc
)
427 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADLENGTH
,
428 "data length %lu exceeds allocated buffer capacity %lu",
429 (ulong_t
)len
, (ulong_t
)aip
->lsai_data_alloc
));
431 ASSERT(aip
->lsai_data_len
== 0);
432 aip
->lsai_data_len
= len
;
438 * Set the length of the valid sense data returned following the command, if
439 * LIBSCSI_AF_RQSENSE is set for this action. Otherwise, fail.
444 libscsi_action_set_senselen(libscsi_action_t
*ap
, size_t len
)
446 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
448 if (!(aip
->lsai_flags
& LIBSCSI_AF_RQSENSE
))
449 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
450 "sense data not supported: LIBSCSI_AF_RQSENSE is clear"));
453 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADLENGTH
,
454 "sense length %lu exceeds allocated buffer capacity %lu",
455 (ulong_t
)len
, (ulong_t
)UINT8_MAX
));
457 ASSERT(aip
->lsai_sense_len
== 0);
458 aip
->lsai_sense_len
= len
;
464 * Allocate an action object. The object will contain a CDB area sufficiently
465 * large to hold a CDB for the given command, and the CDB's opcode will be
466 * filled in. A pointer to this CDB, the contents of which may be modified by
467 * the caller, may be obtained by a subsequent call to libscsi_action_cdb().
469 * If flags includes LIBSCSI_AF_READ or LIBSCSI_AF_WRITE, buflen must be
470 * greater than zero. Otherwise, buflen must be 0 and buf must be NULL.
471 * If buflen is nonzero but buf is NULL, a suitably-sized buffer will be
472 * allocated; otherwise, the specified buffer will be used. In either case,
473 * a pointer to the buffer may be obtained via a subsequent call to
474 * libscsi_action_buffer().
476 * If flags includes LIBSCSI_AF_RQSENSE, a REQUEST SENSE command will be
477 * issued immediately following the termination of the specified command.
478 * A buffer will be allocated to receive this sense data. Following successful
479 * execution of the action, a pointer to this buffer and the length of
480 * valid sense data may be obtained by a call to libscsi_action_sense().
481 * If cmd is SPC3_CMD_REQUEST_SENSE, this flag must be clear.
484 libscsi_action_alloc_vendor(libscsi_hdl_t
*hp
, spc3_cmd_t cmd
, size_t cdbsz
,
485 uint_t flags
, void *buf
, size_t buflen
)
487 libscsi_action_impl_t
*aip
;
492 * If there's no buffer, it makes no sense to try to read or write
493 * data. Likewise, if we're neither reading nor writing data, we
494 * should not have a buffer. Both of these are programmer error.
496 if (buflen
== 0 && (flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
))) {
497 (void) libscsi_error(hp
, ESCSI_NEEDBUF
, "a buffer is "
498 "required when reading or writing");
501 if (buflen
> 0 && !(flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
))) {
502 (void) libscsi_error(hp
, ESCSI_BADFLAGS
, "one of "
503 "LIBSCSI_AF_READ and LIBSCSI_AF_WRITE must be specified "
504 "in order to use a buffer");
509 (void) libscsi_error(hp
, ESCSI_BADLENGTH
, "the supplied CDB "
510 "buffer size has an invalid length, it must be non-zero.");
517 * If the caller has asked for a buffer but has not provided one, we
518 * will allocate it in our internal buffer along with the CDB and
519 * request sense space (if requested).
524 if (flags
& LIBSCSI_AF_RQSENSE
)
527 sz
+= offsetof(libscsi_action_impl_t
, lsai_buf
[0]);
529 if ((aip
= libscsi_zalloc(hp
, sz
)) == NULL
)
533 aip
->lsai_flags
= flags
;
537 aip
->lsai_cdb
= aip
->lsai_buf
+ off
;
538 aip
->lsai_cdb_len
= cdbsz
;
540 aip
->lsai_cdb
[0] = (uint8_t)cmd
;
544 aip
->lsai_data
= buf
;
546 aip
->lsai_data
= aip
->lsai_buf
+ off
;
549 aip
->lsai_data_alloc
= buflen
;
550 if (flags
& LIBSCSI_AF_WRITE
)
551 aip
->lsai_data_len
= buflen
;
554 if (flags
& LIBSCSI_AF_RQSENSE
) {
555 aip
->lsai_sense_data
= aip
->lsai_buf
+ off
;
559 aip
->lsai_status
= LIBSCSI_STATUS_INVALID
;
561 return ((libscsi_action_t
*)aip
);
565 libscsi_action_alloc(libscsi_hdl_t
*hp
, spc3_cmd_t cmd
, uint_t flags
,
566 void *buf
, size_t buflen
)
570 if (cmd
== SPC3_CMD_REQUEST_SENSE
&& (flags
& LIBSCSI_AF_RQSENSE
)) {
571 (void) libscsi_error(hp
, ESCSI_BADFLAGS
, "request sense "
572 "flag not allowed for request sense command");
576 if ((cdbsz
= libscsi_cmd_cdblen(hp
, cmd
)) == 0)
579 return (libscsi_action_alloc_vendor(hp
, cmd
, cdbsz
, flags
, buf
,
584 libscsi_action_free(libscsi_action_t
*ap
)
586 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
588 libscsi_free(aip
->lsai_hdl
, aip
);
592 * For testing purposes, we allow data to be corrupted via an environment
593 * variable setting. This helps ensure that higher level software can cope with
594 * arbitrarily broken targets. The mtbf value represents the number of bytes we
595 * will see, on average, in between each failure. Therefore, for each N bytes,
596 * we would expect to see (N / mtbf) bytes of corruption.
599 scsi_inject_errors(void *data
, size_t len
, uint_t mtbf
)
608 prob
= (double)len
/ mtbf
;
611 index
= lrand48() % len
;
612 buf
[index
] = (lrand48() % 256);
616 if (drand48() <= prob
) {
617 index
= lrand48() % len
;
618 buf
[index
] = (lrand48() % 256);
623 libscsi_exec(libscsi_action_t
*ap
, libscsi_target_t
*tp
)
625 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
626 libscsi_hdl_t
*hp
= aip
->lsai_hdl
;
629 if (tp
->lst_mtbf_write
!= 0 &&
630 (aip
->lsai_flags
& LIBSCSI_AF_WRITE
)) {
631 scsi_inject_errors(aip
->lsai_data
, aip
->lsai_data_len
,
635 if (tp
->lst_mtbf_cdb
!= 0) {
636 scsi_inject_errors(aip
->lsai_cdb
, aip
->lsai_cdb_len
,
640 ret
= tp
->lst_engine
->lse_ops
->lseo_exec(hp
, tp
->lst_priv
, ap
);
642 if (ret
== 0 && tp
->lst_mtbf_read
!= 0 &&
643 (aip
->lsai_flags
& LIBSCSI_AF_READ
)) {
644 scsi_inject_errors(aip
->lsai_data
, aip
->lsai_data_len
,