21 *
22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 * nor the names of its contributors may be used to endorse or promote
24 * products derived from this software without specific prior written
25 * permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39 /* Copyright (c) 2007, The Storage Networking Industry Association. */
40 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
41
42 #include <sys/types.h>
43 #include <ctype.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <stdlib.h>
47 #include "ndmpd_common.h"
48 #include "ndmpd.h"
49 #include <string.h>
50 #include <sys/scsi/impl/uscsi.h>
51 #include <sys/scsi/scsi.h>
52
53 static void scsi_open_send_reply(ndmp_connection_t *connection, int err);
54 static void common_open(ndmp_connection_t *connection, char *devname);
55 static void common_set_target(ndmp_connection_t *connection, char *device,
56 ushort_t controller, ushort_t sid, ushort_t lun);
57
58
59 /*
60 * ************************************************************************
61 * NDMP V2 HANDLERS
62 * ************************************************************************
86 /*
87 * ndmpd_scsi_close_v2
88 *
89 * This handler closes the currently open SCSI device.
90 *
91 * Parameters:
92 * connection (input) - connection handle.
93 * body (input) - request message body.
94 *
95 * Returns:
96 * void
97 */
98 /*ARGSUSED*/
99 void
100 ndmpd_scsi_close_v2(ndmp_connection_t *connection, void *body)
101 {
102 ndmp_scsi_close_reply reply;
103 ndmpd_session_t *session = ndmp_get_client_data(connection);
104
105 if (session->ns_scsi.sd_is_open == -1) {
106 NDMP_LOG(LOG_ERR, "SCSI device is not open.");
107 reply.error = NDMP_DEV_NOT_OPEN_ERR;
108 ndmp_send_reply(connection, (void *) &reply,
109 "sending scsi_close reply");
110 return;
111 }
112 (void) ndmp_open_list_del(session->ns_scsi.sd_adapter_name,
113 session->ns_scsi.sd_sid,
114 session->ns_scsi.sd_lun);
115 (void) close(session->ns_scsi.sd_devid);
116
117 session->ns_scsi.sd_is_open = -1;
118 session->ns_scsi.sd_devid = -1;
119 session->ns_scsi.sd_sid = 0;
120 session->ns_scsi.sd_lun = 0;
121 session->ns_scsi.sd_valid_target_set = FALSE;
122 (void) memset(session->ns_scsi.sd_adapter_name, 0,
123 sizeof (session->ns_scsi.sd_adapter_name));
124
125 reply.error = NDMP_NO_ERR;
126 ndmp_send_reply(connection, (void *) &reply,
209 * This handler resets the currently targeted SCSI device.
210 *
211 * Parameters:
212 * connection (input) - connection handle.
213 * body (input) - request message body.
214 *
215 * Returns:
216 * void
217 */
218 /*ARGSUSED*/
219 void
220 ndmpd_scsi_reset_device_v2(ndmp_connection_t *connection, void *body)
221 {
222 ndmp_scsi_reset_device_reply reply;
223
224
225 ndmpd_session_t *session = ndmp_get_client_data(connection);
226 struct uscsi_cmd cmd;
227
228 if (session->ns_scsi.sd_devid == -1) {
229 NDMP_LOG(LOG_ERR, "SCSI device is not open.");
230 reply.error = NDMP_DEV_NOT_OPEN_ERR;
231 } else {
232 reply.error = NDMP_NO_ERR;
233 (void) memset((void*)&cmd, 0, sizeof (cmd));
234 cmd.uscsi_flags |= USCSI_RESET;
235 if (ioctl(session->ns_scsi.sd_devid, USCSICMD, &cmd) < 0) {
236 NDMP_LOG(LOG_ERR, "USCSI reset failed: %m.");
237 NDMP_LOG(LOG_DEBUG,
238 "ioctl(USCSICMD) USCSI_RESET failed: %m.");
239 reply.error = NDMP_IO_ERR;
240 }
241 }
242
243 ndmp_send_reply(connection, (void *) &reply,
244 "sending scsi_reset_device reply");
245 }
246
247
248 /*
249 * ndmpd_scsi_reset_bus_v2
250 *
251 * This handler resets the currently targeted SCSI bus.
252 *
253 * Request not yet supported.
254 *
255 * Parameters:
256 * connection (input) - connection handle.
257 * body (input) - request message body.
258 *
259 * Returns:
260 * void
261 */
262 /*ARGSUSED*/
263 void
264 ndmpd_scsi_reset_bus_v2(ndmp_connection_t *connection, void *body)
265 {
266 ndmp_scsi_reset_bus_reply reply;
267
268 NDMP_LOG(LOG_DEBUG, "request not supported");
269 reply.error = NDMP_NOT_SUPPORTED_ERR;
270
271 ndmp_send_reply(connection, (void *) &reply,
272 "sending scsi_reset_bus reply");
273 }
274
275
276 /*
277 * ndmpd_scsi_execute_cdb_v2
278 *
279 * This handler sends the CDB to the currently targeted SCSI device.
280 *
281 * Parameters:
282 * connection (input) - connection handle.
283 * body (input) - request message body.
284 *
285 * Returns:
286 * void
287 */
288 void
289 ndmpd_scsi_execute_cdb_v2(ndmp_connection_t *connection, void *body)
290 {
291 ndmp_execute_cdb_request *request = (ndmp_execute_cdb_request *) body;
292 ndmp_execute_cdb_reply reply;
293 ndmpd_session_t *session = ndmp_get_client_data(connection);
294
295 if (session->ns_scsi.sd_is_open == -1 ||
296 !session->ns_scsi.sd_valid_target_set) {
297 (void) memset((void *) &reply, 0, sizeof (reply));
298
299 NDMP_LOG(LOG_ERR, "SCSI device is not open.");
300 reply.error = NDMP_DEV_NOT_OPEN_ERR;
301 ndmp_send_reply(connection, (void *) &reply,
302 "sending scsi_execute_cdb reply");
303 } else {
304 ndmp_execute_cdb(session, session->ns_scsi.sd_adapter_name,
305 session->ns_scsi.sd_sid, session->ns_scsi.sd_lun, request);
306 }
307 }
308
309
310 /*
311 * ************************************************************************
312 * NDMP V3 HANDLERS
313 * ************************************************************************
314 */
315
316 /*
317 * ndmpd_scsi_open_v3
318 *
319 * This handler opens the specified SCSI device.
399 /*
400 * common_open
401 *
402 * Common SCSI open function for all NDMP versions
403 *
404 * Parameters:
405 * connection (input) - connection handle.
406 * devname (input) - device name to open.
407 *
408 * Returns:
409 * void
410 */
411 static void
412 common_open(ndmp_connection_t *connection, char *devname)
413 {
414 ndmpd_session_t *session = ndmp_get_client_data(connection);
415 char adptnm[SCSI_MAX_NAME];
416 int sid, lun;
417 int err;
418 scsi_adapter_t *sa;
419 int devid;
420
421 err = NDMP_NO_ERR;
422
423 if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
424 NDMP_LOG(LOG_ERR,
425 "Session already has a tape or scsi device open.");
426 err = NDMP_DEVICE_OPENED_ERR;
427 } else if ((sa = scsi_get_adapter(0)) != NULL) {
428 NDMP_LOG(LOG_DEBUG, "Adapter device found: %s", devname);
429 (void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
430 adptnm[SCSI_MAX_NAME-1] = '\0';
431 sid = lun = -1;
432
433 scsi_find_sid_lun(sa, devname, &sid, &lun);
434 if (ndmp_open_list_find(devname, sid, lun) == NULL &&
435 (devid = open(devname, O_RDWR | O_NDELAY)) < 0) {
436 NDMP_LOG(LOG_ERR, "Failed to open device %s: %m.",
437 devname);
438 err = NDMP_NO_DEVICE_ERR;
439 }
440 } else {
441 NDMP_LOG(LOG_ERR, "%s: No such SCSI adapter.", devname);
442 err = NDMP_NO_DEVICE_ERR;
443 }
444
445 if (err != NDMP_NO_ERR) {
446 scsi_open_send_reply(connection, err);
447 return;
448 }
449
450 switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
451 case 0:
452 /* OK */
453 break;
454 case EBUSY:
455 err = NDMP_DEVICE_BUSY_ERR;
456 break;
457 case ENOMEM:
458 err = NDMP_NO_MEM_ERR;
459 break;
460 default:
461 err = NDMP_IO_ERR;
495 *
496 * Returns:
497 * 0: on success
498 * -1: otherwise
499 */
500 /*ARGSUSED*/
501 static void
502 common_set_target(ndmp_connection_t *connection, char *device,
503 ushort_t controller, ushort_t sid, ushort_t lun)
504 {
505 ndmp_scsi_set_target_reply reply;
506 ndmpd_session_t *session = ndmp_get_client_data(connection);
507 int type;
508
509 reply.error = NDMP_NO_ERR;
510
511 if (session->ns_scsi.sd_is_open == -1) {
512 reply.error = NDMP_DEV_NOT_OPEN_ERR;
513 } else if (!scsi_dev_exists(session->ns_scsi.sd_adapter_name, sid,
514 lun)) {
515 NDMP_LOG(LOG_ERR, "No such SCSI device: target %d lun %d.",
516 sid, lun);
517 reply.error = NDMP_NO_DEVICE_ERR;
518 } else {
519 type = scsi_get_devtype(session->ns_scsi.sd_adapter_name, sid,
520 lun);
521 if (type != DTYPE_SEQUENTIAL && type != DTYPE_CHANGER) {
522 NDMP_LOG(LOG_ERR,
523 "Not a tape or robot device: target %d lun %d.",
524 sid, lun);
525 reply.error = NDMP_ILLEGAL_ARGS_ERR;
526 }
527 }
528
529 if (reply.error != NDMP_NO_ERR) {
530 ndmp_send_reply(connection, (void *) &reply,
531 "sending scsi_set_target reply");
532 return;
533 }
534
535 /*
536 * The open_list must be updated if the SID or LUN are going to be
537 * changed. Close uses the same SID & LUN for removing the entry
538 * from the open_list.
539 */
540 if (sid != session->ns_scsi.sd_sid || lun != session->ns_scsi.sd_lun) {
541 switch (ndmp_open_list_add(connection,
542 session->ns_scsi.sd_adapter_name, sid, lun, 0)) {
543 case 0:
544 (void) ndmp_open_list_del(session->
545 ns_scsi.sd_adapter_name, session->ns_scsi.sd_sid,
546 session->ns_scsi.sd_lun);
547 break;
548 case EBUSY:
549 reply.error = NDMP_DEVICE_BUSY_ERR;
550 break;
551 case ENOMEM:
552 reply.error = NDMP_NO_MEM_ERR;
553 break;
554 default:
555 reply.error = NDMP_IO_ERR;
556 }
557 }
558
559 if (reply.error == NDMP_NO_ERR) {
560 NDMP_LOG(LOG_DEBUG, "Updated sid %d lun %d", sid, lun);
561 session->ns_scsi.sd_sid = sid;
562 session->ns_scsi.sd_lun = lun;
563 session->ns_scsi.sd_valid_target_set = TRUE;
564 }
565
566 ndmp_send_reply(connection, (void *) &reply,
567 "sending scsi_set_target reply");
568 }
569
570 /*
571 * scsi_find_sid_lun
572 *
573 * gets the adapter, and returns the sid and lun number
574 */
575 void
576 scsi_find_sid_lun(scsi_adapter_t *sa, char *devname, int *sid, int *lun)
577 {
578 scsi_link_t *sl;
579 char *name;
580
|
21 *
22 * - Neither the name of The Storage Networking Industry Association (SNIA)
23 * nor the names of its contributors may be used to endorse or promote
24 * products derived from this software without specific prior written
25 * permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39 /* Copyright (c) 2007, The Storage Networking Industry Association. */
40 /* Copyright (c) 1996, 1997 PDC, Network Appliance. All Rights Reserved */
41 /* Copyright 2017 Nexenta Systems, Inc. All rights reserved. */
42
43 #include <sys/types.h>
44 #include <syslog.h>
45 #include <ctype.h>
46 #include <errno.h>
47 #include <fcntl.h>
48 #include <stdlib.h>
49 #include "ndmpd_common.h"
50 #include "ndmpd.h"
51 #include <string.h>
52 #include <sys/scsi/impl/uscsi.h>
53 #include <sys/scsi/scsi.h>
54
55 static void scsi_open_send_reply(ndmp_connection_t *connection, int err);
56 static void common_open(ndmp_connection_t *connection, char *devname);
57 static void common_set_target(ndmp_connection_t *connection, char *device,
58 ushort_t controller, ushort_t sid, ushort_t lun);
59
60
61 /*
62 * ************************************************************************
63 * NDMP V2 HANDLERS
64 * ************************************************************************
88 /*
89 * ndmpd_scsi_close_v2
90 *
91 * This handler closes the currently open SCSI device.
92 *
93 * Parameters:
94 * connection (input) - connection handle.
95 * body (input) - request message body.
96 *
97 * Returns:
98 * void
99 */
100 /*ARGSUSED*/
101 void
102 ndmpd_scsi_close_v2(ndmp_connection_t *connection, void *body)
103 {
104 ndmp_scsi_close_reply reply;
105 ndmpd_session_t *session = ndmp_get_client_data(connection);
106
107 if (session->ns_scsi.sd_is_open == -1) {
108 syslog(LOG_ERR, "SCSI device is not open.");
109 reply.error = NDMP_DEV_NOT_OPEN_ERR;
110 ndmp_send_reply(connection, (void *) &reply,
111 "sending scsi_close reply");
112 return;
113 }
114 (void) ndmp_open_list_del(session->ns_scsi.sd_adapter_name,
115 session->ns_scsi.sd_sid,
116 session->ns_scsi.sd_lun);
117 (void) close(session->ns_scsi.sd_devid);
118
119 session->ns_scsi.sd_is_open = -1;
120 session->ns_scsi.sd_devid = -1;
121 session->ns_scsi.sd_sid = 0;
122 session->ns_scsi.sd_lun = 0;
123 session->ns_scsi.sd_valid_target_set = FALSE;
124 (void) memset(session->ns_scsi.sd_adapter_name, 0,
125 sizeof (session->ns_scsi.sd_adapter_name));
126
127 reply.error = NDMP_NO_ERR;
128 ndmp_send_reply(connection, (void *) &reply,
211 * This handler resets the currently targeted SCSI device.
212 *
213 * Parameters:
214 * connection (input) - connection handle.
215 * body (input) - request message body.
216 *
217 * Returns:
218 * void
219 */
220 /*ARGSUSED*/
221 void
222 ndmpd_scsi_reset_device_v2(ndmp_connection_t *connection, void *body)
223 {
224 ndmp_scsi_reset_device_reply reply;
225
226
227 ndmpd_session_t *session = ndmp_get_client_data(connection);
228 struct uscsi_cmd cmd;
229
230 if (session->ns_scsi.sd_devid == -1) {
231 syslog(LOG_ERR, "SCSI device is not open.");
232 reply.error = NDMP_DEV_NOT_OPEN_ERR;
233 } else {
234 reply.error = NDMP_NO_ERR;
235 (void) memset((void*)&cmd, 0, sizeof (cmd));
236 cmd.uscsi_flags |= USCSI_RESET;
237 if (ioctl(session->ns_scsi.sd_devid, USCSICMD, &cmd) < 0) {
238 syslog(LOG_ERR, "USCSI reset failed: %m.");
239 reply.error = NDMP_IO_ERR;
240 }
241 }
242
243 ndmp_send_reply(connection, (void *) &reply,
244 "sending scsi_reset_device reply");
245 }
246
247
248 /*
249 * ndmpd_scsi_reset_bus_v2
250 *
251 * This handler resets the currently targeted SCSI bus.
252 *
253 * Request not yet supported.
254 *
255 * Parameters:
256 * connection (input) - connection handle.
257 * body (input) - request message body.
258 *
259 * Returns:
260 * void
261 */
262 /*ARGSUSED*/
263 void
264 ndmpd_scsi_reset_bus_v2(ndmp_connection_t *connection, void *body)
265 {
266 ndmp_scsi_reset_bus_reply reply;
267
268 reply.error = NDMP_NOT_SUPPORTED_ERR;
269
270 ndmp_send_reply(connection, (void *) &reply,
271 "sending scsi_reset_bus reply");
272 }
273
274
275 /*
276 * ndmpd_scsi_execute_cdb_v2
277 *
278 * This handler sends the CDB to the currently targeted SCSI device.
279 *
280 * Parameters:
281 * connection (input) - connection handle.
282 * body (input) - request message body.
283 *
284 * Returns:
285 * void
286 */
287 void
288 ndmpd_scsi_execute_cdb_v2(ndmp_connection_t *connection, void *body)
289 {
290 ndmp_execute_cdb_request *request = (ndmp_execute_cdb_request *) body;
291 ndmp_execute_cdb_reply reply;
292 ndmpd_session_t *session = ndmp_get_client_data(connection);
293
294 if (session->ns_scsi.sd_is_open == -1 ||
295 !session->ns_scsi.sd_valid_target_set) {
296 (void) memset((void *) &reply, 0, sizeof (reply));
297
298 reply.error = NDMP_DEV_NOT_OPEN_ERR;
299 ndmp_send_reply(connection, (void *) &reply,
300 "sending scsi_execute_cdb reply");
301 } else {
302 ndmp_execute_cdb(session, session->ns_scsi.sd_adapter_name,
303 session->ns_scsi.sd_sid, session->ns_scsi.sd_lun, request);
304 }
305 }
306
307
308 /*
309 * ************************************************************************
310 * NDMP V3 HANDLERS
311 * ************************************************************************
312 */
313
314 /*
315 * ndmpd_scsi_open_v3
316 *
317 * This handler opens the specified SCSI device.
397 /*
398 * common_open
399 *
400 * Common SCSI open function for all NDMP versions
401 *
402 * Parameters:
403 * connection (input) - connection handle.
404 * devname (input) - device name to open.
405 *
406 * Returns:
407 * void
408 */
409 static void
410 common_open(ndmp_connection_t *connection, char *devname)
411 {
412 ndmpd_session_t *session = ndmp_get_client_data(connection);
413 char adptnm[SCSI_MAX_NAME];
414 int sid, lun;
415 int err;
416 scsi_adapter_t *sa;
417 int devid = -1;
418
419 err = NDMP_NO_ERR;
420
421 if (session->ns_tape.td_fd != -1 || session->ns_scsi.sd_is_open != -1) {
422 err = NDMP_DEVICE_OPENED_ERR;
423 } else if ((sa = scsi_get_adapter(0)) != NULL) {
424 (void) strlcpy(adptnm, devname, SCSI_MAX_NAME-2);
425 adptnm[SCSI_MAX_NAME-1] = '\0';
426 sid = lun = -1;
427
428 scsi_find_sid_lun(sa, devname, &sid, &lun);
429 if (ndmp_open_list_find(devname, sid, lun) == NULL &&
430 (devid = open(devname, O_RDWR | O_NDELAY)) < 0) {
431 syslog(LOG_ERR, "Failed to open device %s: %m.",
432 devname);
433 err = NDMP_NO_DEVICE_ERR;
434 }
435 } else {
436 syslog(LOG_ERR, "%s: No such SCSI adapter.", devname);
437 err = NDMP_NO_DEVICE_ERR;
438 }
439
440 if (err != NDMP_NO_ERR) {
441 scsi_open_send_reply(connection, err);
442 return;
443 }
444
445 switch (ndmp_open_list_add(connection, adptnm, sid, lun, devid)) {
446 case 0:
447 /* OK */
448 break;
449 case EBUSY:
450 err = NDMP_DEVICE_BUSY_ERR;
451 break;
452 case ENOMEM:
453 err = NDMP_NO_MEM_ERR;
454 break;
455 default:
456 err = NDMP_IO_ERR;
490 *
491 * Returns:
492 * 0: on success
493 * -1: otherwise
494 */
495 /*ARGSUSED*/
496 static void
497 common_set_target(ndmp_connection_t *connection, char *device,
498 ushort_t controller, ushort_t sid, ushort_t lun)
499 {
500 ndmp_scsi_set_target_reply reply;
501 ndmpd_session_t *session = ndmp_get_client_data(connection);
502 int type;
503
504 reply.error = NDMP_NO_ERR;
505
506 if (session->ns_scsi.sd_is_open == -1) {
507 reply.error = NDMP_DEV_NOT_OPEN_ERR;
508 } else if (!scsi_dev_exists(session->ns_scsi.sd_adapter_name, sid,
509 lun)) {
510 syslog(LOG_ERR, "No such SCSI device: target %d lun %d.",
511 sid, lun);
512 reply.error = NDMP_NO_DEVICE_ERR;
513 } else {
514 type = scsi_get_devtype(session->ns_scsi.sd_adapter_name, sid,
515 lun);
516 if (type != DTYPE_SEQUENTIAL && type != DTYPE_CHANGER) {
517 syslog(LOG_ERR,
518 "Not a tape or robot device: target %d lun %d.",
519 sid, lun);
520 reply.error = NDMP_ILLEGAL_ARGS_ERR;
521 }
522 }
523
524 if (reply.error != NDMP_NO_ERR) {
525 ndmp_send_reply(connection, (void *) &reply,
526 "sending scsi_set_target reply");
527 return;
528 }
529
530 /*
531 * The open_list must be updated if the SID or LUN are going to be
532 * changed. Close uses the same SID & LUN for removing the entry
533 * from the open_list.
534 */
535 if (sid != session->ns_scsi.sd_sid || lun != session->ns_scsi.sd_lun) {
536 switch (ndmp_open_list_add(connection,
537 session->ns_scsi.sd_adapter_name, sid, lun, 0)) {
538 case 0:
539 (void) ndmp_open_list_del(session->
540 ns_scsi.sd_adapter_name, session->ns_scsi.sd_sid,
541 session->ns_scsi.sd_lun);
542 break;
543 case EBUSY:
544 reply.error = NDMP_DEVICE_BUSY_ERR;
545 break;
546 case ENOMEM:
547 reply.error = NDMP_NO_MEM_ERR;
548 break;
549 default:
550 reply.error = NDMP_IO_ERR;
551 }
552 }
553
554 if (reply.error == NDMP_NO_ERR) {
555 session->ns_scsi.sd_sid = sid;
556 session->ns_scsi.sd_lun = lun;
557 session->ns_scsi.sd_valid_target_set = TRUE;
558 }
559
560 ndmp_send_reply(connection, (void *) &reply,
561 "sending scsi_set_target reply");
562 }
563
564 /*
565 * scsi_find_sid_lun
566 *
567 * gets the adapter, and returns the sid and lun number
568 */
569 void
570 scsi_find_sid_lun(scsi_adapter_t *sa, char *devname, int *sid, int *lun)
571 {
572 scsi_link_t *sl;
573 char *name;
574
|