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
;
68 if (sysinfo(SI_ARCHITECTURE_64
, isa
, sizeof (isa
)) < 0)
74 for (p
= engine_path
; p
!= NULL
; p
= q
) {
75 if ((q
= strchr(p
, ':')) != NULL
) {
76 ptrdiff_t len
= q
- p
;
77 (void) strncpy(engine_dir
, p
, len
);
78 engine_dir
[len
] = '\0';
86 (void) strcpy(engine_dir
, p
);
88 if (engine_dir
[0] != '/')
93 (void) snprintf(engine_lib
, MAXPATHLEN
, "%s/%s/%s%s",
94 engine_dir
, isa
, name
, LIBSCSI_ENGINE_EXT
);
96 dl_hdl
= dlopen(engine_lib
,
97 RTLD_LOCAL
| RTLD_LAZY
| RTLD_PARENT
);
100 (void) libscsi_error(hp
, ESCSI_NOENGINE
,
101 "unable to dlopen %s: %s", engine_lib
,
106 (void) snprintf(init_name
, MAXPATHLEN
, "libscsi_%s_init", name
);
107 init
= (libscsi_engine_init_f
)dlsym(dl_hdl
, init_name
);
110 (void) libscsi_error(hp
, ESCSI_NOENGINE
,
111 "failed to find %s in %s: %s", init_name
,
112 engine_lib
, dlerror());
113 (void) dlclose(dl_hdl
);
116 if ((ep
= init(hp
)) == NULL
) {
117 (void) dlclose(dl_hdl
);
119 * libscsi errno set by init.
123 if (ep
->lse_libversion
!= hp
->lsh_version
) {
124 (void) dlclose(dl_hdl
);
125 (void) libscsi_error(hp
, ESCSI_ENGINE_VER
, "engine "
126 "%s version %u does not match library version %u",
127 engine_lib
, ep
->lse_libversion
, hp
->lsh_version
);
131 eip
= libscsi_zalloc(hp
, sizeof (libscsi_engine_impl_t
));
133 (void) dlclose(dl_hdl
);
136 eip
->lsei_engine
= ep
;
137 eip
->lsei_dl_hdl
= dl_hdl
;
138 eip
->lsei_next
= hp
->lsh_engines
;
139 hp
->lsh_engines
= eip
;
145 (void) libscsi_error(hp
, ESCSI_ENGINE_BADPATH
, "no valid "
146 "directories found in engine path %s", engine_path
);
152 scsi_parse_mtbf(const char *envvar
, uint_t
*intp
)
157 if ((strval
= getenv(envvar
)) != NULL
&&
158 (intval
= atoi(strval
)) > 0) {
159 srand48(gethrtime());
165 libscsi_open(libscsi_hdl_t
*hp
, const char *engine
, const void *target
)
167 const libscsi_engine_t
*ep
;
168 libscsi_target_t
*tp
;
171 if (engine
== NULL
) {
172 if ((engine
= getenv("LIBSCSI_DEFAULT_ENGINE")) == NULL
)
173 engine
= LIBSCSI_DEFAULT_ENGINE
;
176 if ((ep
= get_engine(hp
, engine
)) == NULL
)
179 if ((tp
= libscsi_zalloc(hp
, sizeof (libscsi_target_t
))) == NULL
)
182 if ((private = ep
->lse_ops
->lseo_open(hp
, target
)) == NULL
) {
183 libscsi_free(hp
, tp
);
187 scsi_parse_mtbf("LIBSCSI_MTBF_CDB", &tp
->lst_mtbf_cdb
);
188 scsi_parse_mtbf("LIBSCSI_MTBF_READ", &tp
->lst_mtbf_read
);
189 scsi_parse_mtbf("LIBSCSI_MTBF_WRITE", &tp
->lst_mtbf_write
);
193 tp
->lst_priv
= private;
197 if (libscsi_get_inquiry(hp
, tp
) != 0) {
198 libscsi_close(hp
, tp
);
206 libscsi_get_handle(libscsi_target_t
*tp
)
208 return (tp
->lst_hdl
);
212 libscsi_close(libscsi_hdl_t
*hp
, libscsi_target_t
*tp
)
214 tp
->lst_engine
->lse_ops
->lseo_close(hp
, tp
->lst_priv
);
215 libscsi_free(hp
, tp
->lst_vendor
);
216 libscsi_free(hp
, tp
->lst_product
);
217 libscsi_free(hp
, tp
->lst_revision
);
218 libscsi_free(hp
, tp
);
223 libscsi_action_get_status(const libscsi_action_t
*ap
)
225 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
227 return (aip
->lsai_status
);
231 * Set the timeout in seconds for this action. If no timeout is specified
232 * or if the timeout is set to 0, an implementation-specific timeout will be
233 * used (which may vary based on the target, command or other variables).
234 * Not all engines support all timeout values. Setting the timeout to a value
235 * not supported by the engine will cause engine-defined behavior when the
236 * action is executed.
239 libscsi_action_set_timeout(libscsi_action_t
*ap
, uint32_t timeout
)
241 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
243 aip
->lsai_timeout
= timeout
;
247 * Obtain the timeout setting for this action.
250 libscsi_action_get_timeout(const libscsi_action_t
*ap
)
252 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
254 return (aip
->lsai_timeout
);
258 * Returns the flags associated with this action. Never fails.
261 libscsi_action_get_flags(const libscsi_action_t
*ap
)
263 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
265 return (aip
->lsai_flags
);
269 * Return the length of the CDB buffer associated with this action. Never
273 libscsi_action_get_cdblen(const libscsi_action_t
*ap
)
275 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
277 return (aip
->lsai_cdb_len
);
281 * Returns the address of the action's CDB. The CDB buffer is guaranteed to
282 * be large enough to hold the complete CDB for the command specified when the
283 * action was allocated. Therefore, changing the command/opcode portion of
284 * the CDB has undefined effects. The remainder of the CDB may be modified.
287 libscsi_action_get_cdb(const libscsi_action_t
*ap
)
289 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
291 return (aip
->lsai_cdb
);
295 * Places the address of the action buffer in the location pointed to by bp,
296 * if bp is not NULL. If ap is not NULL, it will contain the allocated size
297 * of the buffer itself. If vp is not NULL, it will contain the number of
298 * bytes of valid data currently stored in the buffer.
300 * If the action has LIBSCSI_AF_WRITE set and it has not yet been executed
301 * successfully, the entire buffer is assumed to contain valid data.
303 * If the action has LIBSCSI_AF_READ set and it has not yet been executed
304 * successfully, the amount of valid data is 0.
306 * If both LIBSCSI_AF_READ and LIBSCSI_AF_WRITE are clear, this function
307 * fails with ESCSI_BADFLAGS to indicate that the action flags are
308 * incompatible with the action data buffer.
311 libscsi_action_get_buffer(const libscsi_action_t
*ap
, uint8_t **bp
,
312 size_t *sp
, size_t *vp
)
314 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
316 if ((aip
->lsai_flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
)) == 0)
317 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
318 "data buffer not supported for actions with both "
319 "LIBSCSI_AF_READ and LIBSCSI_AF_WRITE clear"));
321 if ((aip
->lsai_flags
& LIBSCSI_AF_WRITE
) &&
322 aip
->lsai_status
== LIBSCSI_STATUS_INVALID
) {
324 *bp
= aip
->lsai_data
;
326 *sp
= aip
->lsai_data_alloc
;
328 *vp
= aip
->lsai_data_alloc
;
333 if ((aip
->lsai_flags
& LIBSCSI_AF_READ
) &&
334 aip
->lsai_status
!= LIBSCSI_STATUS_INVALID
) {
336 *bp
= aip
->lsai_data
;
338 *sp
= aip
->lsai_data_alloc
;
340 *vp
= aip
->lsai_data_len
;
345 if (aip
->lsai_flags
& LIBSCSI_AF_WRITE
) {
354 *bp
= aip
->lsai_data
;
356 *sp
= aip
->lsai_data_alloc
;
365 * Obtain a pointer to the sense buffer for this action, if any, along with
366 * the size of the sense buffer and the amount of valid data it contains.
369 libscsi_action_get_sense(const libscsi_action_t
*ap
, uint8_t **bp
,
370 size_t *sp
, size_t *vp
)
372 const libscsi_action_impl_t
*aip
= (const libscsi_action_impl_t
*)ap
;
374 if (!(aip
->lsai_flags
& LIBSCSI_AF_RQSENSE
))
375 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
376 "sense data unavailable: LIBSCSI_AF_RQSENSE is clear"));
379 if (aip
->lsai_status
== LIBSCSI_STATUS_INVALID
)
382 *vp
= aip
->lsai_sense_len
;
386 ASSERT(aip
->lsai_sense_data
!= NULL
);
387 *bp
= aip
->lsai_sense_data
;
397 * Set the SCSI status of the action.
402 libscsi_action_set_status(libscsi_action_t
*ap
, sam4_status_t status
)
404 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
406 ASSERT(aip
->lsai_status
== LIBSCSI_STATUS_INVALID
);
408 aip
->lsai_status
= status
;
412 * Set the length of valid data returned by a READ action. If the action is
413 * not a READ action, or the length exceeds the size of the buffer, an error
419 libscsi_action_set_datalen(libscsi_action_t
*ap
, size_t len
)
421 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
423 if ((aip
->lsai_flags
& LIBSCSI_AF_READ
) == 0)
424 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
425 "data cannot be returned for actions with LIBSCSI_AF_READ "
427 if (len
> aip
->lsai_data_alloc
)
428 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADLENGTH
,
429 "data length %lu exceeds allocated buffer capacity %lu",
430 (ulong_t
)len
, (ulong_t
)aip
->lsai_data_alloc
));
432 ASSERT(aip
->lsai_data_len
== 0);
433 aip
->lsai_data_len
= len
;
439 * Set the length of the valid sense data returned following the command, if
440 * LIBSCSI_AF_RQSENSE is set for this action. Otherwise, fail.
445 libscsi_action_set_senselen(libscsi_action_t
*ap
, size_t len
)
447 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
449 if (!(aip
->lsai_flags
& LIBSCSI_AF_RQSENSE
))
450 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADFLAGS
,
451 "sense data not supported: LIBSCSI_AF_RQSENSE is clear"));
454 return (libscsi_error(aip
->lsai_hdl
, ESCSI_BADLENGTH
,
455 "sense length %lu exceeds allocated buffer capacity %lu",
456 (ulong_t
)len
, (ulong_t
)UINT8_MAX
));
458 ASSERT(aip
->lsai_sense_len
== 0);
459 aip
->lsai_sense_len
= len
;
465 * Allocate an action object. The object will contain a CDB area sufficiently
466 * large to hold a CDB for the given command, and the CDB's opcode will be
467 * filled in. A pointer to this CDB, the contents of which may be modified by
468 * the caller, may be obtained by a subsequent call to libscsi_action_cdb().
470 * If flags includes LIBSCSI_AF_READ or LIBSCSI_AF_WRITE, buflen must be
471 * greater than zero. Otherwise, buflen must be 0 and buf must be NULL.
472 * If buflen is nonzero but buf is NULL, a suitably-sized buffer will be
473 * allocated; otherwise, the specified buffer will be used. In either case,
474 * a pointer to the buffer may be obtained via a subsequent call to
475 * libscsi_action_buffer().
477 * If flags includes LIBSCSI_AF_RQSENSE, a REQUEST SENSE command will be
478 * issued immediately following the termination of the specified command.
479 * A buffer will be allocated to receive this sense data. Following successful
480 * execution of the action, a pointer to this buffer and the length of
481 * valid sense data may be obtained by a call to libscsi_action_sense().
482 * If cmd is SPC3_CMD_REQUEST_SENSE, this flag must be clear.
485 libscsi_action_alloc_vendor(libscsi_hdl_t
*hp
, spc3_cmd_t cmd
, size_t cdbsz
,
486 uint_t flags
, void *buf
, size_t buflen
)
488 libscsi_action_impl_t
*aip
;
493 * If there's no buffer, it makes no sense to try to read or write
494 * data. Likewise, if we're neither reading nor writing data, we
495 * should not have a buffer. Both of these are programmer error.
497 if (buflen
== 0 && (flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
))) {
498 (void) libscsi_error(hp
, ESCSI_NEEDBUF
, "a buffer is "
499 "required when reading or writing");
502 if (buflen
> 0 && !(flags
& (LIBSCSI_AF_READ
| LIBSCSI_AF_WRITE
))) {
503 (void) libscsi_error(hp
, ESCSI_BADFLAGS
, "one of "
504 "LIBSCSI_AF_READ and LIBSCSI_AF_WRITE must be specified "
505 "in order to use a buffer");
510 (void) libscsi_error(hp
, ESCSI_BADLENGTH
, "the supplied CDB "
511 "buffer size has an invalid length, it must be non-zero.");
518 * If the caller has asked for a buffer but has not provided one, we
519 * will allocate it in our internal buffer along with the CDB and
520 * request sense space (if requested).
525 if (flags
& LIBSCSI_AF_RQSENSE
)
528 sz
+= offsetof(libscsi_action_impl_t
, lsai_buf
[0]);
530 if ((aip
= libscsi_zalloc(hp
, sz
)) == NULL
)
534 aip
->lsai_flags
= flags
;
538 aip
->lsai_cdb
= aip
->lsai_buf
+ off
;
539 aip
->lsai_cdb_len
= cdbsz
;
541 aip
->lsai_cdb
[0] = (uint8_t)cmd
;
545 aip
->lsai_data
= buf
;
547 aip
->lsai_data
= aip
->lsai_buf
+ off
;
550 aip
->lsai_data_alloc
= buflen
;
551 if (flags
& LIBSCSI_AF_WRITE
)
552 aip
->lsai_data_len
= buflen
;
555 if (flags
& LIBSCSI_AF_RQSENSE
) {
556 aip
->lsai_sense_data
= aip
->lsai_buf
+ off
;
560 aip
->lsai_status
= LIBSCSI_STATUS_INVALID
;
562 return ((libscsi_action_t
*)aip
);
566 libscsi_action_alloc(libscsi_hdl_t
*hp
, spc3_cmd_t cmd
, uint_t flags
,
567 void *buf
, size_t buflen
)
571 if (cmd
== SPC3_CMD_REQUEST_SENSE
&& (flags
& LIBSCSI_AF_RQSENSE
)) {
572 (void) libscsi_error(hp
, ESCSI_BADFLAGS
, "request sense "
573 "flag not allowed for request sense command");
577 if ((cdbsz
= libscsi_cmd_cdblen(hp
, cmd
)) == 0)
580 return (libscsi_action_alloc_vendor(hp
, cmd
, cdbsz
, flags
, buf
,
585 libscsi_action_free(libscsi_action_t
*ap
)
587 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
589 libscsi_free(aip
->lsai_hdl
, aip
);
593 * For testing purposes, we allow data to be corrupted via an environment
594 * variable setting. This helps ensure that higher level software can cope with
595 * arbitrarily broken targets. The mtbf value represents the number of bytes we
596 * will see, on average, in between each failure. Therefore, for each N bytes,
597 * we would expect to see (N / mtbf) bytes of corruption.
600 scsi_inject_errors(void *data
, size_t len
, uint_t mtbf
)
609 prob
= (double)len
/ mtbf
;
612 index
= lrand48() % len
;
613 buf
[index
] = (lrand48() % 256);
617 if (drand48() <= prob
) {
618 index
= lrand48() % len
;
619 buf
[index
] = (lrand48() % 256);
624 libscsi_exec(libscsi_action_t
*ap
, libscsi_target_t
*tp
)
626 libscsi_action_impl_t
*aip
= (libscsi_action_impl_t
*)ap
;
627 libscsi_hdl_t
*hp
= aip
->lsai_hdl
;
630 if (tp
->lst_mtbf_write
!= 0 &&
631 (aip
->lsai_flags
& LIBSCSI_AF_WRITE
)) {
632 scsi_inject_errors(aip
->lsai_data
, aip
->lsai_data_len
,
636 if (tp
->lst_mtbf_cdb
!= 0) {
637 scsi_inject_errors(aip
->lsai_cdb
, aip
->lsai_cdb_len
,
641 ret
= tp
->lst_engine
->lse_ops
->lseo_exec(hp
, tp
->lst_priv
, ap
);
643 if (ret
== 0 && tp
->lst_mtbf_read
!= 0 &&
644 (aip
->lsai_flags
& LIBSCSI_AF_READ
)) {
645 scsi_inject_errors(aip
->lsai_data
, aip
->lsai_data_len
,