30 #include <sys/scsi/scsi.h>
31 #include <sys/scsi/impl/scsi_reset_notify.h>
32 #include <sys/disp.h>
33 #include <sys/byteorder.h>
34 #include <sys/atomic.h>
35
36 #include <sys/stmf.h>
37 #include <sys/lpif.h>
38 #include <sys/portif.h>
39 #include <sys/stmf_ioctl.h>
40
41 #include "stmf_impl.h"
42 #include "lun_map.h"
43 #include "stmf_state.h"
44
45 void stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
46 stmf_lu_t *lu, int action);
47 void stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
48 stmf_i_scsi_session_t *iss, stmf_lun_map_t *vemap);
49 stmf_id_data_t *stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size);
50 stmf_status_t stmf_add_ent_to_map(stmf_lun_map_t *sm, void *ent, uint8_t *lun);
51 stmf_status_t stmf_remove_ent_from_map(stmf_lun_map_t *sm, uint8_t *lun);
52 uint16_t stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun);
53 stmf_status_t stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
54 int allow_special, uint32_t *err_detail);
55 stmf_status_t stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
56 int allow_special, uint32_t *err_detail);
57 stmf_i_local_port_t *stmf_targetident_to_ilport(uint8_t *target_ident,
58 uint16_t ident_size);
59 stmf_i_scsi_session_t *stmf_lookup_session_for_hostident(
60 stmf_i_local_port_t *ilport, uint8_t *host_ident,
61 uint16_t ident_size);
62 stmf_i_lu_t *stmf_luident_to_ilu(uint8_t *lu_ident);
63 stmf_lun_map_t *stmf_get_ve_map_per_ids(stmf_id_data_t *tgid,
64 stmf_id_data_t *hgid);
65 stmf_lun_map_t *stmf_duplicate_ve_map(stmf_lun_map_t *src);
66 int stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
67 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf);
68 void stmf_destroy_ve_map(stmf_lun_map_t *dst);
69 void stmf_free_id(stmf_id_data_t *id);
70
71
162 idmemb_next = idmemb->id_next;
163 stmf_free_id(idmemb);
164 }
165 }
166 idgrp_next = idgrp->id_next;
167 stmf_free_id(idgrp);
168 }
169 stmf_state.stmf_tg_list.id_count = 0;
170 stmf_state.stmf_tg_list.idl_head =
171 stmf_state.stmf_tg_list.idl_tail = NULL;
172 }
173
174 for (ilport = stmf_state.stmf_ilportlist; ilport;
175 ilport = ilport->ilport_next) {
176 ilport->ilport_tg = NULL;
177 }
178 }
179
180 /*
181 * Create luns map for session based on the view
182 */
183 stmf_status_t
184 stmf_session_create_lun_map(stmf_i_local_port_t *ilport,
185 stmf_i_scsi_session_t *iss)
186 {
187 stmf_id_data_t *tg;
188 stmf_id_data_t *hg;
189 stmf_ver_tg_t *vertg;
190 char *phg_data, *ptg_data;
191 stmf_ver_hg_t *verhg;
192 stmf_lun_map_t *ve_map;
193
194 ASSERT(mutex_owned(&stmf_state.stmf_lock));
195
196 tg = ilport->ilport_tg;
197 hg = stmf_lookup_group_for_host(iss->iss_ss->ss_rport_id->ident,
198 iss->iss_ss->ss_rport_id->ident_length);
199 iss->iss_hg = hg;
200
201 /*
219 (verhg->verh_hg_ref != hg)))) {
220 continue;
221 }
222 (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
223 &ve_map, 0);
224 }
225 }
226
227
228 if (ve_map->lm_nluns) {
229 stmf_add_lus_to_session_per_vemap(ilport, iss, ve_map);
230 }
231 /* not configured, cannot access any luns for now */
232
233 stmf_destroy_ve_map(ve_map);
234
235 return (STMF_SUCCESS);
236 }
237
238 /*
239 * destroy lun map for session
240 */
241 /* ARGSUSED */
242 stmf_status_t
243 stmf_session_destroy_lun_map(stmf_i_local_port_t *ilport,
244 stmf_i_scsi_session_t *iss)
245 {
246 stmf_lun_map_t *sm;
247 stmf_i_lu_t *ilu;
248 uint16_t n;
249 stmf_lun_map_ent_t *ent;
250
251 ASSERT(mutex_owned(&stmf_state.stmf_lock));
252 /*
253 * to avoid conflict with updating session's map,
254 * which only grab stmf_lock
255 */
256 sm = iss->iss_sm;
257 iss->iss_sm = NULL;
258 iss->iss_hg = NULL;
259 if (sm->lm_nentries) {
260 for (n = 0; n < sm->lm_nentries; n++) {
261 if ((ent = (stmf_lun_map_ent_t *)sm->lm_plus[n])
262 != NULL) {
263 if (ent->ent_itl_datap) {
264 stmf_do_itl_dereg(ent->ent_lu,
265 ent->ent_itl_datap,
266 STMF_ITL_REASON_IT_NEXUS_LOSS);
267 }
268 ilu = (stmf_i_lu_t *)
269 ent->ent_lu->lu_stmf_private;
270 atomic_dec_32(&ilu->ilu_ref_cnt);
271 kmem_free(sm->lm_plus[n],
272 sizeof (stmf_lun_map_ent_t));
273 }
274 }
275 kmem_free(sm->lm_plus,
276 sizeof (stmf_lun_map_ent_t *) * sm->lm_nentries);
277 }
278
279 kmem_free(sm, sizeof (*sm));
280 return (STMF_SUCCESS);
281 }
282
283 /*
284 * Expects the session lock to be held.
285 */
286 stmf_xfer_data_t *
287 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
288 {
289 stmf_xfer_data_t *xd;
290 uint16_t nluns, ent;
291 uint32_t alloc_size, data_size;
292 int i;
293
294 nluns = sm->lm_nluns;
295
296 data_size = 8 + (((uint32_t)nluns) << 3);
297 if (nluns == 0) {
298 data_size += 8;
299 }
300 alloc_size = data_size + sizeof (stmf_xfer_data_t) - 4;
301
302 xd = (stmf_xfer_data_t *)kmem_zalloc(alloc_size, KM_NOSLEEP);
303
304 if (xd == NULL)
373 return;
374
375 luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
376 if (!luid) {
377 /*
378 * we did not configure view for this lun, this should be
379 * an error
380 */
381 return;
382 }
383
384 for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
385 ve; ve = ve->ve_next) {
386 stmf_update_sessions_per_ve(ve, lu, 0);
387 if (ilu->ilu_ref_cnt == 0)
388 break;
389 }
390 }
391 /*
392 * add lu to a session, stmf_lock is already held
393 */
394 stmf_status_t
395 stmf_add_lu_to_session(stmf_i_local_port_t *ilport,
396 stmf_i_scsi_session_t *iss,
397 stmf_lu_t *lu,
398 uint8_t *lu_nbr)
399 {
400 stmf_lun_map_t *sm = iss->iss_sm;
401 stmf_status_t ret;
402 stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
403 stmf_lun_map_ent_t *lun_map_ent;
404 uint32_t new_flags = 0;
405 uint16_t luNbr =
406 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
407
408 ASSERT(mutex_owned(&stmf_state.stmf_lock));
409 ASSERT(!stmf_get_ent_from_map(sm, luNbr));
410
411 if ((sm->lm_nluns == 0) &&
412 ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
413 new_flags = ISS_GOT_INITIAL_LUNS;
414 atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
417
418 lun_map_ent = (stmf_lun_map_ent_t *)
419 kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
420 lun_map_ent->ent_lu = lu;
421 ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
422 ASSERT(ret == STMF_SUCCESS);
423 atomic_inc_32(&ilu->ilu_ref_cnt);
424 /*
425 * do not set lun inventory flag for standby port
426 * as this would be handled from peer
427 */
428 if (ilport->ilport_standby == 0) {
429 new_flags |= ISS_LUN_INVENTORY_CHANGED;
430 }
431 atomic_or_32(&iss->iss_flags, new_flags);
432 return (STMF_SUCCESS);
433 }
434
435 /*
436 * remvoe lu from a session, stmf_lock is already held
437 */
438 /* ARGSUSED */
439 stmf_status_t
440 stmf_remove_lu_from_session(stmf_i_local_port_t *ilport,
441 stmf_i_scsi_session_t *iss,
442 stmf_lu_t *lu,
443 uint8_t *lu_nbr)
444 {
445 stmf_status_t ret;
446 stmf_i_lu_t *ilu;
447 stmf_lun_map_t *sm = iss->iss_sm;
448 stmf_lun_map_ent_t *lun_map_ent;
449 uint16_t luNbr =
450 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
451
452 ASSERT(mutex_owned(&stmf_state.stmf_lock));
453 lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
454 ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
455
456 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
457
458 ret = stmf_remove_ent_from_map(sm, lu_nbr);
459 ASSERT(ret == STMF_SUCCESS);
460 atomic_dec_32(&ilu->ilu_ref_cnt);
461 iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
462 if (lun_map_ent->ent_itl_datap) {
463 stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
464 STMF_ITL_REASON_USER_REQUEST);
465 }
466 kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
467 return (STMF_SUCCESS);
468 }
469
470 /*
471 * add or remove lu from all related sessions based on view entry,
472 * action is 0 for delete, 1 for add
473 */
474 void
475 stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
476 stmf_lu_t *lu, int action)
477 {
478 stmf_i_lu_t *ilu_tmp;
479 stmf_lu_t *lu_to_add;
480 stmf_i_local_port_t *ilport;
481 stmf_i_scsi_session_t *iss;
482 stmf_id_list_t *hostlist;
483 stmf_id_list_t *targetlist;
484 int all_hg = 0, all_tg = 0;
485
486 ASSERT(mutex_owned(&stmf_state.stmf_lock));
487
502 hostlist = (stmf_id_list_t *)ve->ve_hg->id_impl_specific;
503 targetlist = (stmf_id_list_t *)ve->ve_tg->id_impl_specific;
504
505 if ((!all_hg && !hostlist->idl_head) ||
506 (!all_tg && !targetlist->idl_head))
507 /* No sessions to be updated */
508 return;
509
510 for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
511 ilport = ilport->ilport_next) {
512 if (!all_tg && ilport->ilport_tg != ve->ve_tg)
513 continue;
514 /* This ilport belongs to the target group */
515 rw_enter(&ilport->ilport_lock, RW_WRITER);
516 for (iss = ilport->ilport_ss_list; iss != NULL;
517 iss = iss->iss_next) {
518 if (!all_hg && iss->iss_hg != ve->ve_hg)
519 continue;
520 /* This host belongs to the host group */
521 if (action == 0) { /* to remove */
522 (void) stmf_remove_lu_from_session(ilport, iss,
523 lu_to_add, ve->ve_lun);
524 if (ilu_tmp->ilu_ref_cnt == 0) {
525 rw_exit(&ilport->ilport_lock);
526 return;
527 }
528 } else {
529 (void) stmf_add_lu_to_session(ilport, iss,
530 lu_to_add, ve->ve_lun);
531 }
532 }
533 rw_exit(&ilport->ilport_lock);
534 }
535 }
536
537 /*
538 * add luns in view entry map to a session,
539 * and stmf_lock is already held
540 */
541 void
542 stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
543 stmf_i_scsi_session_t *iss,
544 stmf_lun_map_t *vemap)
545 {
546 stmf_lu_t *lu;
547 stmf_i_lu_t *ilu;
548 stmf_view_entry_t *ve;
549 uint32_t i;
550
551 ASSERT(mutex_owned(&stmf_state.stmf_lock));
552
553 for (i = 0; i < vemap->lm_nentries; i++) {
554 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
555 if (!ve)
556 continue;
557 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
558 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
559 lu = ilu->ilu_lu;
560 (void) stmf_add_lu_to_session(ilport, iss, lu,
561 ve->ve_lun);
562 }
563 }
564 }
565 /* remove luns in view entry map from a session */
566 void
567 stmf_remove_lus_from_session_per_vemap(stmf_i_local_port_t *ilport,
568 stmf_i_scsi_session_t *iss,
569 stmf_lun_map_t *vemap)
570 {
571 stmf_lu_t *lu;
572 stmf_i_lu_t *ilu;
573 stmf_view_entry_t *ve;
574 uint32_t i;
575
576 ASSERT(mutex_owned(&stmf_state.stmf_lock));
577
578 for (i = 0; i < vemap->lm_nentries; i++) {
579 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
580 if (!ve)
581 continue;
582 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
583 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
584 lu = ilu->ilu_lu;
585 (void) stmf_remove_lu_from_session(ilport, iss, lu,
586 ve->ve_lun);
587 }
588 }
589 }
590
591 stmf_id_data_t *
592 stmf_alloc_id(uint16_t id_size, uint16_t type, uint8_t *id_data,
593 uint32_t additional_size)
594 {
595 stmf_id_data_t *id;
596 int struct_size, total_size, real_id_size;
597
598 real_id_size = ((uint32_t)id_size + 7) & (~7);
599 struct_size = (sizeof (*id) + 7) & (~7);
600 total_size = ((additional_size + 7) & (~7)) + struct_size +
601 real_id_size;
602 id = (stmf_id_data_t *)kmem_zalloc(total_size, KM_SLEEP);
603 id->id_type = type;
604 id->id_data_size = id_size;
605 id->id_data = ((uint8_t *)id) + struct_size;
606 id->id_total_alloc_size = total_size;
693 if (id->id_next) {
694 id->id_next->id_prev = id->id_prev;
695 } else {
696 idlist->idl_tail = id->id_prev;
697 }
698
699 if (id->id_prev) {
700 id->id_prev->id_next = id->id_next;
701 } else {
702 idlist->idl_head = id->id_next;
703 }
704 atomic_dec_32(&idlist->id_count);
705 }
706
707
708 /*
709 * The refcnts of objects in a view entry are updated when then entry
710 * is successfully added. ve_map is just another representation of the
711 * view enrtries in a LU. Duplicating or merging a ve map does not
712 * affect any refcnts.
713 */
714 stmf_lun_map_t *
715 stmf_duplicate_ve_map(stmf_lun_map_t *src)
716 {
717 stmf_lun_map_t *dst;
718 int i;
719
720 dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
721
722 if (src == NULL)
723 return (dst);
724
725 if (src->lm_nentries) {
726 dst->lm_plus = kmem_zalloc(dst->lm_nentries *
727 sizeof (void *), KM_SLEEP);
728 for (i = 0; i < dst->lm_nentries; i++) {
729 dst->lm_plus[i] = src->lm_plus[i];
730 }
731 }
732
733 return (dst);
734 }
735
736 void
737 stmf_destroy_ve_map(stmf_lun_map_t *dst)
738 {
739 if (dst->lm_nentries) {
740 kmem_free(dst->lm_plus, dst->lm_nentries * sizeof (void *));
741 }
742 kmem_free(dst, sizeof (*dst));
743 }
744
745 int
746 stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
747 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf)
748 {
749 int i;
750 int nentries;
751 int to_create_space = 0;
752
753 if (dst == NULL) {
754 *pp_ret_map = stmf_duplicate_ve_map(src);
755 return (1);
756 }
757
758 if (src == NULL || src->lm_nluns == 0) {
759 if (mf & MERGE_FLAG_RETURN_NEW_MAP)
760 *pp_ret_map = stmf_duplicate_ve_map(dst);
761 else
762 *pp_ret_map = dst;
763 return (1);
764 }
1049 }
1050 ret = stmf_add_ent_to_map(&verhg_ex->verh_ve_map, ve, ve->ve_lun);
1051 ASSERT(ret == STMF_SUCCESS);
1052
1053 /* we need to update the affected session */
1054 if (stmf_state.stmf_service_running) {
1055 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE)
1056 stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 1);
1057 }
1058
1059 return (STMF_SUCCESS);
1060 add_ve_err_ret:
1061 if (luid_new) {
1062 if (ilu)
1063 ilu->ilu_luid = NULL;
1064 stmf_free_id(luid);
1065 }
1066 return (ret);
1067 }
1068
1069 stmf_status_t
1070 stmf_add_ent_to_map(stmf_lun_map_t *lm, void *ent, uint8_t *lun)
1071 {
1072 uint16_t n;
1073 if (((lun[0] & 0xc0) >> 6) != 0)
1074 return (STMF_FAILURE);
1075
1076 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1077 try_again_to_add:
1078 if (lm->lm_nentries && (n < lm->lm_nentries)) {
1079 if (lm->lm_plus[n] == NULL) {
1080 lm->lm_plus[n] = ent;
1081 lm->lm_nluns++;
1082 return (STMF_SUCCESS);
1083 } else {
1084 return (STMF_LUN_TAKEN);
1085 }
1086 } else {
1087 void **pplu;
1088 uint16_t m = n + 1;
1089 m = ((m + 7) & ~7) & 0x7FFF;
1090 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
1091 bcopy(lm->lm_plus, pplu,
1092 lm->lm_nentries * sizeof (void *));
1093 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1094 lm->lm_plus = pplu;
1095 lm->lm_nentries = m;
1096 goto try_again_to_add;
1097 }
1098 }
1099
1100
1101 stmf_status_t
1102 stmf_remove_ent_from_map(stmf_lun_map_t *lm, uint8_t *lun)
1103 {
1104 uint16_t n, i;
1105 uint8_t lutype = (lun[0] & 0xc0) >> 6;
1106 if (lutype != 0)
1107 return (STMF_FAILURE);
1108
1109 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1110
1111 if (n >= lm->lm_nentries)
1112 return (STMF_NOT_FOUND);
1113 if (lm->lm_plus[n] == NULL)
1114 return (STMF_NOT_FOUND);
1115
1116 lm->lm_plus[n] = NULL;
1117 lm->lm_nluns--;
1118
1119 for (i = 0; i < lm->lm_nentries; i++) {
1120 if (lm->lm_plus[lm->lm_nentries - 1 - i] != NULL)
1121 break;
1122 }
1123 i &= ~15;
1124 if (i >= 16) {
1125 void **pplu;
1126 uint16_t m;
1127 m = lm->lm_nentries - i;
1128 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
1129 bcopy(lm->lm_plus, pplu, m * sizeof (void *));
1130 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1131 lm->lm_plus = pplu;
1132 lm->lm_nentries = m;
1133 }
1134
1135 return (STMF_SUCCESS);
1136 }
1137
1138 uint16_t
1139 stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun)
1140 {
1141 uint16_t luNbr;
1142
1143
1144 if (sm->lm_nluns < 0x4000) {
1145 for (luNbr = 0; luNbr < sm->lm_nentries; luNbr++) {
1146 if (sm->lm_plus[luNbr] == NULL)
1147 break;
1148 }
1149 } else {
1150 return (0xFFFF);
1151 }
1152 if (lun) {
1153 bzero(lun, 8);
1154 lun[1] = luNbr & 0xff;
1155 lun[0] = (luNbr >> 8) & 0xff;
1156 }
1157
1158 return (luNbr);
1159 }
1160
1161 void *
1162 stmf_get_ent_from_map(stmf_lun_map_t *sm, uint16_t lun_num)
1163 {
1164 if ((lun_num & 0xC000) == 0) {
1165 if (sm->lm_nentries > lun_num)
1166 return (sm->lm_plus[lun_num & 0x3FFF]);
1167 else
1168 return (NULL);
1169 }
1170
1171 return (NULL);
1172 }
1173
1174 int
1175 stmf_add_ve(uint8_t *hgname, uint16_t hgname_size,
1176 uint8_t *tgname, uint16_t tgname_size,
1177 uint8_t *lu_guid, uint32_t *ve_id,
1178 uint8_t *luNbr, uint32_t *err_detail)
1179 {
1180 stmf_id_data_t *hg;
1475 }
1476 /* For host group member, update the session if needed */
1477 if (!stmf_state.stmf_service_running)
1478 return (0);
1479 /* Need to consider all target group + this host group */
1480 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1481 1, &grpname_forall);
1482 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
1483
1484 /* check whether there are sessions may be affected */
1485 for (ilport = stmf_state.stmf_ilportlist; ilport;
1486 ilport = ilport->ilport_next) {
1487 if (ilport->ilport_state != STMF_STATE_ONLINE)
1488 continue;
1489 iss = stmf_lookup_session_for_hostident(ilport,
1490 entry_ident, entry_size);
1491 if (iss) {
1492 stmf_id_data_t *tgid;
1493 iss->iss_hg = (void *)id_grp;
1494 tgid = ilport->ilport_tg;
1495 if (tgid) {
1496 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1497 if (vemap)
1498 stmf_add_lus_to_session_per_vemap(
1499 ilport, iss, vemap);
1500 }
1501 if (vemap_alltgt)
1502 stmf_add_lus_to_session_per_vemap(ilport,
1503 iss, vemap_alltgt);
1504 }
1505 }
1506
1507 return (0);
1508 }
1509
1510 int
1511 stmf_remove_group_member(uint8_t *grpname, uint16_t grpname_size,
1512 uint8_t *entry_ident, uint16_t entry_size,
1513 stmf_id_type_t entry_type, uint32_t *err_detail)
1514 {
1515 stmf_id_data_t *id_grp, *id_alltgt;
1516 stmf_id_data_t *id_member;
1517 stmf_lun_map_t *vemap, *vemap_alltgt;
1518 uint8_t grpname_forall = '*';
1519 stmf_i_local_port_t *ilport;
1520 stmf_i_scsi_session_t *iss;
1521
1522 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1523 ASSERT(grpname[0] != '*');
1560 return (0);
1561 }
1562 /* For host group member, update the session */
1563 if (!stmf_state.stmf_service_running)
1564 return (0);
1565
1566 /* Need to consider all target group + this host group */
1567 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1568 1, &grpname_forall);
1569 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
1570
1571 /* check if there are session related, if so, update it */
1572 for (ilport = stmf_state.stmf_ilportlist; ilport;
1573 ilport = ilport->ilport_next) {
1574 if (ilport->ilport_state != STMF_STATE_ONLINE)
1575 continue;
1576 iss = stmf_lookup_session_for_hostident(ilport,
1577 entry_ident, entry_size);
1578 if (iss) {
1579 stmf_id_data_t *tgid;
1580 iss->iss_hg = NULL;
1581 tgid = ilport->ilport_tg;
1582 if (tgid) {
1583 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1584 if (vemap)
1585 stmf_remove_lus_from_session_per_vemap(
1586 ilport, iss, vemap);
1587 }
1588 if (vemap_alltgt)
1589 stmf_remove_lus_from_session_per_vemap(ilport,
1590 iss, vemap_alltgt);
1591 }
1592 }
1593
1594 return (0);
1595 }
1596
1597 /* Assert stmf_lock is already held */
1598 stmf_i_local_port_t *
1599 stmf_targetident_to_ilport(uint8_t *target_ident, uint16_t ident_size)
1600 {
1601 stmf_i_local_port_t *ilport;
1602 uint8_t *id;
1603
1604 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1605
1606 for (ilport = stmf_state.stmf_ilportlist; ilport;
1607 ilport = ilport->ilport_next) {
1608 id = (uint8_t *)ilport->ilport_lport->lport_id;
1609 if ((id[3] == ident_size) &&
1610 bcmp(id + 4, target_ident, ident_size) == 0) {
|
30 #include <sys/scsi/scsi.h>
31 #include <sys/scsi/impl/scsi_reset_notify.h>
32 #include <sys/disp.h>
33 #include <sys/byteorder.h>
34 #include <sys/atomic.h>
35
36 #include <sys/stmf.h>
37 #include <sys/lpif.h>
38 #include <sys/portif.h>
39 #include <sys/stmf_ioctl.h>
40
41 #include "stmf_impl.h"
42 #include "lun_map.h"
43 #include "stmf_state.h"
44
45 void stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
46 stmf_lu_t *lu, int action);
47 void stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
48 stmf_i_scsi_session_t *iss, stmf_lun_map_t *vemap);
49 stmf_id_data_t *stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size);
50 static stmf_status_t stmf_add_ent_to_map(stmf_lun_map_t *sm, void *ent,
51 uint8_t *lun);
52 static stmf_status_t stmf_remove_ent_from_map(stmf_lun_map_t *sm, uint8_t *lun);
53 uint16_t stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun);
54 stmf_status_t stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
55 int allow_special, uint32_t *err_detail);
56 stmf_status_t stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
57 int allow_special, uint32_t *err_detail);
58 stmf_i_local_port_t *stmf_targetident_to_ilport(uint8_t *target_ident,
59 uint16_t ident_size);
60 stmf_i_scsi_session_t *stmf_lookup_session_for_hostident(
61 stmf_i_local_port_t *ilport, uint8_t *host_ident,
62 uint16_t ident_size);
63 stmf_i_lu_t *stmf_luident_to_ilu(uint8_t *lu_ident);
64 stmf_lun_map_t *stmf_get_ve_map_per_ids(stmf_id_data_t *tgid,
65 stmf_id_data_t *hgid);
66 stmf_lun_map_t *stmf_duplicate_ve_map(stmf_lun_map_t *src);
67 int stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
68 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf);
69 void stmf_destroy_ve_map(stmf_lun_map_t *dst);
70 void stmf_free_id(stmf_id_data_t *id);
71
72
163 idmemb_next = idmemb->id_next;
164 stmf_free_id(idmemb);
165 }
166 }
167 idgrp_next = idgrp->id_next;
168 stmf_free_id(idgrp);
169 }
170 stmf_state.stmf_tg_list.id_count = 0;
171 stmf_state.stmf_tg_list.idl_head =
172 stmf_state.stmf_tg_list.idl_tail = NULL;
173 }
174
175 for (ilport = stmf_state.stmf_ilportlist; ilport;
176 ilport = ilport->ilport_next) {
177 ilport->ilport_tg = NULL;
178 }
179 }
180
181 /*
182 * Create luns map for session based on the view
183 * iss_lockp is held
184 */
185 stmf_status_t
186 stmf_session_create_lun_map(stmf_i_local_port_t *ilport,
187 stmf_i_scsi_session_t *iss)
188 {
189 stmf_id_data_t *tg;
190 stmf_id_data_t *hg;
191 stmf_ver_tg_t *vertg;
192 char *phg_data, *ptg_data;
193 stmf_ver_hg_t *verhg;
194 stmf_lun_map_t *ve_map;
195
196 ASSERT(mutex_owned(&stmf_state.stmf_lock));
197
198 tg = ilport->ilport_tg;
199 hg = stmf_lookup_group_for_host(iss->iss_ss->ss_rport_id->ident,
200 iss->iss_ss->ss_rport_id->ident_length);
201 iss->iss_hg = hg;
202
203 /*
221 (verhg->verh_hg_ref != hg)))) {
222 continue;
223 }
224 (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
225 &ve_map, 0);
226 }
227 }
228
229
230 if (ve_map->lm_nluns) {
231 stmf_add_lus_to_session_per_vemap(ilport, iss, ve_map);
232 }
233 /* not configured, cannot access any luns for now */
234
235 stmf_destroy_ve_map(ve_map);
236
237 return (STMF_SUCCESS);
238 }
239
240 /*
241 * Expects the session lock to be held.
242 * iss_lockp is held
243 */
244 stmf_xfer_data_t *
245 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
246 {
247 stmf_xfer_data_t *xd;
248 uint16_t nluns, ent;
249 uint32_t alloc_size, data_size;
250 int i;
251
252 nluns = sm->lm_nluns;
253
254 data_size = 8 + (((uint32_t)nluns) << 3);
255 if (nluns == 0) {
256 data_size += 8;
257 }
258 alloc_size = data_size + sizeof (stmf_xfer_data_t) - 4;
259
260 xd = (stmf_xfer_data_t *)kmem_zalloc(alloc_size, KM_NOSLEEP);
261
262 if (xd == NULL)
331 return;
332
333 luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
334 if (!luid) {
335 /*
336 * we did not configure view for this lun, this should be
337 * an error
338 */
339 return;
340 }
341
342 for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
343 ve; ve = ve->ve_next) {
344 stmf_update_sessions_per_ve(ve, lu, 0);
345 if (ilu->ilu_ref_cnt == 0)
346 break;
347 }
348 }
349 /*
350 * add lu to a session, stmf_lock is already held
351 * iss_lockp/ilport_lock already held
352 */
353 static stmf_status_t
354 stmf_add_lu_to_session(stmf_i_local_port_t *ilport,
355 stmf_i_scsi_session_t *iss,
356 stmf_lu_t *lu,
357 uint8_t *lu_nbr)
358 {
359 stmf_lun_map_t *sm = iss->iss_sm;
360 stmf_status_t ret;
361 stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
362 stmf_lun_map_ent_t *lun_map_ent;
363 uint32_t new_flags = 0;
364 uint16_t luNbr =
365 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
366
367 ASSERT(mutex_owned(&stmf_state.stmf_lock));
368 ASSERT(!stmf_get_ent_from_map(sm, luNbr));
369
370 if ((sm->lm_nluns == 0) &&
371 ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
372 new_flags = ISS_GOT_INITIAL_LUNS;
373 atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
376
377 lun_map_ent = (stmf_lun_map_ent_t *)
378 kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
379 lun_map_ent->ent_lu = lu;
380 ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
381 ASSERT(ret == STMF_SUCCESS);
382 atomic_inc_32(&ilu->ilu_ref_cnt);
383 /*
384 * do not set lun inventory flag for standby port
385 * as this would be handled from peer
386 */
387 if (ilport->ilport_standby == 0) {
388 new_flags |= ISS_LUN_INVENTORY_CHANGED;
389 }
390 atomic_or_32(&iss->iss_flags, new_flags);
391 return (STMF_SUCCESS);
392 }
393
394 /*
395 * remvoe lu from a session, stmf_lock is already held
396 * iss_lockp held
397 */
398 static void
399 stmf_remove_lu_from_session(stmf_i_scsi_session_t *iss,
400 stmf_lu_t *lu, uint8_t *lu_nbr)
401 {
402 stmf_status_t ret;
403 stmf_i_lu_t *ilu;
404 stmf_lun_map_t *sm = iss->iss_sm;
405 stmf_lun_map_ent_t *lun_map_ent;
406 uint16_t luNbr =
407 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
408
409 ASSERT(mutex_owned(&stmf_state.stmf_lock));
410 lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
411 ASSERT(lun_map_ent->ent_lu == lu);
412 if (lun_map_ent == NULL) {
413 return;
414 }
415
416 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
417
418 ret = stmf_remove_ent_from_map(sm, lu_nbr);
419 ASSERT(ret == STMF_SUCCESS);
420 atomic_dec_32(&ilu->ilu_ref_cnt);
421 iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
422 if (lun_map_ent->ent_itl_datap) {
423 stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
424 STMF_ITL_REASON_USER_REQUEST);
425 }
426 kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
427 }
428
429 /*
430 * add or remove lu from all related sessions based on view entry,
431 * action is 0 for delete, 1 for add
432 */
433 void
434 stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
435 stmf_lu_t *lu, int action)
436 {
437 stmf_i_lu_t *ilu_tmp;
438 stmf_lu_t *lu_to_add;
439 stmf_i_local_port_t *ilport;
440 stmf_i_scsi_session_t *iss;
441 stmf_id_list_t *hostlist;
442 stmf_id_list_t *targetlist;
443 int all_hg = 0, all_tg = 0;
444
445 ASSERT(mutex_owned(&stmf_state.stmf_lock));
446
461 hostlist = (stmf_id_list_t *)ve->ve_hg->id_impl_specific;
462 targetlist = (stmf_id_list_t *)ve->ve_tg->id_impl_specific;
463
464 if ((!all_hg && !hostlist->idl_head) ||
465 (!all_tg && !targetlist->idl_head))
466 /* No sessions to be updated */
467 return;
468
469 for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
470 ilport = ilport->ilport_next) {
471 if (!all_tg && ilport->ilport_tg != ve->ve_tg)
472 continue;
473 /* This ilport belongs to the target group */
474 rw_enter(&ilport->ilport_lock, RW_WRITER);
475 for (iss = ilport->ilport_ss_list; iss != NULL;
476 iss = iss->iss_next) {
477 if (!all_hg && iss->iss_hg != ve->ve_hg)
478 continue;
479 /* This host belongs to the host group */
480 if (action == 0) { /* to remove */
481 stmf_remove_lu_from_session(iss, lu_to_add,
482 ve->ve_lun);
483 if (ilu_tmp->ilu_ref_cnt == 0) {
484 rw_exit(&ilport->ilport_lock);
485 return;
486 }
487 } else {
488 (void) stmf_add_lu_to_session(ilport, iss,
489 lu_to_add, ve->ve_lun);
490 }
491 }
492 rw_exit(&ilport->ilport_lock);
493 }
494 }
495
496 /*
497 * add luns in view entry map to a session,
498 * and stmf_lock is already held
499 */
500 void
501 stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
502 stmf_i_scsi_session_t *iss,
503 stmf_lun_map_t *vemap)
504 {
505 stmf_lu_t *lu;
506 stmf_i_lu_t *ilu;
507 stmf_view_entry_t *ve;
508 uint32_t i;
509
510 ASSERT(mutex_owned(&stmf_state.stmf_lock));
511 for (i = 0; i < vemap->lm_nentries; i++) {
512 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
513 if (!ve)
514 continue;
515 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
516 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
517 lu = ilu->ilu_lu;
518 (void) stmf_add_lu_to_session(ilport, iss, lu,
519 ve->ve_lun);
520 }
521 }
522 }
523 /*
524 * remove luns in view entry map from a session
525 * iss_lockp held
526 */
527 void
528 stmf_remove_lus_from_session_per_vemap(stmf_i_scsi_session_t *iss,
529 stmf_lun_map_t *vemap)
530 {
531 stmf_lu_t *lu;
532 stmf_i_lu_t *ilu;
533 stmf_view_entry_t *ve;
534 uint32_t i;
535
536 ASSERT(mutex_owned(&stmf_state.stmf_lock));
537
538 for (i = 0; i < vemap->lm_nentries; i++) {
539 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
540 if (!ve)
541 continue;
542 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
543 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
544 lu = ilu->ilu_lu;
545 stmf_remove_lu_from_session(iss, lu, ve->ve_lun);
546 }
547 }
548 }
549
550 stmf_id_data_t *
551 stmf_alloc_id(uint16_t id_size, uint16_t type, uint8_t *id_data,
552 uint32_t additional_size)
553 {
554 stmf_id_data_t *id;
555 int struct_size, total_size, real_id_size;
556
557 real_id_size = ((uint32_t)id_size + 7) & (~7);
558 struct_size = (sizeof (*id) + 7) & (~7);
559 total_size = ((additional_size + 7) & (~7)) + struct_size +
560 real_id_size;
561 id = (stmf_id_data_t *)kmem_zalloc(total_size, KM_SLEEP);
562 id->id_type = type;
563 id->id_data_size = id_size;
564 id->id_data = ((uint8_t *)id) + struct_size;
565 id->id_total_alloc_size = total_size;
652 if (id->id_next) {
653 id->id_next->id_prev = id->id_prev;
654 } else {
655 idlist->idl_tail = id->id_prev;
656 }
657
658 if (id->id_prev) {
659 id->id_prev->id_next = id->id_next;
660 } else {
661 idlist->idl_head = id->id_next;
662 }
663 atomic_dec_32(&idlist->id_count);
664 }
665
666
667 /*
668 * The refcnts of objects in a view entry are updated when then entry
669 * is successfully added. ve_map is just another representation of the
670 * view enrtries in a LU. Duplicating or merging a ve map does not
671 * affect any refcnts.
672 * stmf_state.stmf_lock held
673 */
674 stmf_lun_map_t *
675 stmf_duplicate_ve_map(stmf_lun_map_t *src)
676 {
677 stmf_lun_map_t *dst;
678 int i;
679
680 dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
681
682 if (src == NULL)
683 return (dst);
684
685 if (src->lm_nentries) {
686 dst->lm_plus = kmem_zalloc(dst->lm_nentries *
687 sizeof (void *), KM_SLEEP);
688 for (i = 0; i < dst->lm_nentries; i++) {
689 dst->lm_plus[i] = src->lm_plus[i];
690 }
691 }
692
693 return (dst);
694 }
695
696 void
697 stmf_destroy_ve_map(stmf_lun_map_t *dst)
698 {
699 if (dst->lm_nentries) {
700 kmem_free(dst->lm_plus, dst->lm_nentries * sizeof (void *));
701 }
702 kmem_free(dst, sizeof (*dst));
703 }
704
705 /*
706 * stmf_state.stmf_lock held. Operations are stmf global in nature and
707 * not session level.
708 */
709 int
710 stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
711 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf)
712 {
713 int i;
714 int nentries;
715 int to_create_space = 0;
716
717 if (dst == NULL) {
718 *pp_ret_map = stmf_duplicate_ve_map(src);
719 return (1);
720 }
721
722 if (src == NULL || src->lm_nluns == 0) {
723 if (mf & MERGE_FLAG_RETURN_NEW_MAP)
724 *pp_ret_map = stmf_duplicate_ve_map(dst);
725 else
726 *pp_ret_map = dst;
727 return (1);
728 }
1013 }
1014 ret = stmf_add_ent_to_map(&verhg_ex->verh_ve_map, ve, ve->ve_lun);
1015 ASSERT(ret == STMF_SUCCESS);
1016
1017 /* we need to update the affected session */
1018 if (stmf_state.stmf_service_running) {
1019 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE)
1020 stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 1);
1021 }
1022
1023 return (STMF_SUCCESS);
1024 add_ve_err_ret:
1025 if (luid_new) {
1026 if (ilu)
1027 ilu->ilu_luid = NULL;
1028 stmf_free_id(luid);
1029 }
1030 return (ret);
1031 }
1032
1033 /*
1034 * protected by stmf_state.stmf_lock when working on global lun map.
1035 * iss_lockp when working at the session level.
1036 */
1037 static stmf_status_t
1038 stmf_add_ent_to_map(stmf_lun_map_t *lm, void *ent, uint8_t *lun)
1039 {
1040 uint16_t n;
1041 if (((lun[0] & 0xc0) >> 6) != 0)
1042 return (STMF_FAILURE);
1043
1044 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1045 try_again_to_add:
1046 if (lm->lm_nentries && (n < lm->lm_nentries)) {
1047 if (lm->lm_plus[n] == NULL) {
1048 lm->lm_plus[n] = ent;
1049 lm->lm_nluns++;
1050 return (STMF_SUCCESS);
1051 } else {
1052 return (STMF_LUN_TAKEN);
1053 }
1054 } else {
1055 void **pplu;
1056 uint16_t m = n + 1;
1057 m = ((m + 7) & ~7) & 0x7FFF;
1058 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
1059 bcopy(lm->lm_plus, pplu,
1060 lm->lm_nentries * sizeof (void *));
1061 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1062 lm->lm_plus = pplu;
1063 lm->lm_nentries = m;
1064 goto try_again_to_add;
1065 }
1066 }
1067
1068
1069 /*
1070 * iss_lockp held when working on a session.
1071 * stmf_state.stmf_lock is held when working on the global views.
1072 */
1073 static stmf_status_t
1074 stmf_remove_ent_from_map(stmf_lun_map_t *lm, uint8_t *lun)
1075 {
1076 uint16_t n, i;
1077 uint8_t lutype = (lun[0] & 0xc0) >> 6;
1078 if (lutype != 0)
1079 return (STMF_FAILURE);
1080
1081 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1082
1083 if (n >= lm->lm_nentries)
1084 return (STMF_NOT_FOUND);
1085 if (lm->lm_plus[n] == NULL)
1086 return (STMF_NOT_FOUND);
1087
1088 lm->lm_plus[n] = NULL;
1089 lm->lm_nluns--;
1090
1091 for (i = 0; i < lm->lm_nentries; i++) {
1092 if (lm->lm_plus[lm->lm_nentries - 1 - i] != NULL)
1093 break;
1094 }
1095 i &= ~15;
1096 if (i >= 16) {
1097 void **pplu;
1098 uint16_t m;
1099 m = lm->lm_nentries - i;
1100 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
1101 bcopy(lm->lm_plus, pplu, m * sizeof (void *));
1102 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1103 lm->lm_plus = pplu;
1104 lm->lm_nentries = m;
1105 }
1106
1107 return (STMF_SUCCESS);
1108 }
1109
1110 /*
1111 * stmf_state.stmf_lock held
1112 */
1113 uint16_t
1114 stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun)
1115 {
1116 uint16_t luNbr;
1117
1118
1119 if (sm->lm_nluns < 0x4000) {
1120 for (luNbr = 0; luNbr < sm->lm_nentries; luNbr++) {
1121 if (sm->lm_plus[luNbr] == NULL)
1122 break;
1123 }
1124 } else {
1125 return (0xFFFF);
1126 }
1127 if (lun) {
1128 bzero(lun, 8);
1129 lun[1] = luNbr & 0xff;
1130 lun[0] = (luNbr >> 8) & 0xff;
1131 }
1132
1133 return (luNbr);
1134 }
1135
1136 /*
1137 * stmf_state.stmf_lock is held when working on global view map
1138 * iss_lockp (RW_WRITER) is held when working on session map.
1139 */
1140 void *
1141 stmf_get_ent_from_map(stmf_lun_map_t *sm, uint16_t lun_num)
1142 {
1143 if ((lun_num & 0xC000) == 0) {
1144 if (sm->lm_nentries > lun_num)
1145 return (sm->lm_plus[lun_num & 0x3FFF]);
1146 else
1147 return (NULL);
1148 }
1149
1150 return (NULL);
1151 }
1152
1153 int
1154 stmf_add_ve(uint8_t *hgname, uint16_t hgname_size,
1155 uint8_t *tgname, uint16_t tgname_size,
1156 uint8_t *lu_guid, uint32_t *ve_id,
1157 uint8_t *luNbr, uint32_t *err_detail)
1158 {
1159 stmf_id_data_t *hg;
1454 }
1455 /* For host group member, update the session if needed */
1456 if (!stmf_state.stmf_service_running)
1457 return (0);
1458 /* Need to consider all target group + this host group */
1459 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1460 1, &grpname_forall);
1461 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
1462
1463 /* check whether there are sessions may be affected */
1464 for (ilport = stmf_state.stmf_ilportlist; ilport;
1465 ilport = ilport->ilport_next) {
1466 if (ilport->ilport_state != STMF_STATE_ONLINE)
1467 continue;
1468 iss = stmf_lookup_session_for_hostident(ilport,
1469 entry_ident, entry_size);
1470 if (iss) {
1471 stmf_id_data_t *tgid;
1472 iss->iss_hg = (void *)id_grp;
1473 tgid = ilport->ilport_tg;
1474 rw_enter(iss->iss_lockp, RW_WRITER);
1475 if (tgid) {
1476 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1477 if (vemap)
1478 stmf_add_lus_to_session_per_vemap(
1479 ilport, iss, vemap);
1480 }
1481 if (vemap_alltgt)
1482 stmf_add_lus_to_session_per_vemap(ilport,
1483 iss, vemap_alltgt);
1484 rw_exit(iss->iss_lockp);
1485 }
1486 }
1487
1488 return (0);
1489 }
1490
1491 int
1492 stmf_remove_group_member(uint8_t *grpname, uint16_t grpname_size,
1493 uint8_t *entry_ident, uint16_t entry_size,
1494 stmf_id_type_t entry_type, uint32_t *err_detail)
1495 {
1496 stmf_id_data_t *id_grp, *id_alltgt;
1497 stmf_id_data_t *id_member;
1498 stmf_lun_map_t *vemap, *vemap_alltgt;
1499 uint8_t grpname_forall = '*';
1500 stmf_i_local_port_t *ilport;
1501 stmf_i_scsi_session_t *iss;
1502
1503 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1504 ASSERT(grpname[0] != '*');
1541 return (0);
1542 }
1543 /* For host group member, update the session */
1544 if (!stmf_state.stmf_service_running)
1545 return (0);
1546
1547 /* Need to consider all target group + this host group */
1548 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1549 1, &grpname_forall);
1550 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
1551
1552 /* check if there are session related, if so, update it */
1553 for (ilport = stmf_state.stmf_ilportlist; ilport;
1554 ilport = ilport->ilport_next) {
1555 if (ilport->ilport_state != STMF_STATE_ONLINE)
1556 continue;
1557 iss = stmf_lookup_session_for_hostident(ilport,
1558 entry_ident, entry_size);
1559 if (iss) {
1560 stmf_id_data_t *tgid;
1561 rw_enter(iss->iss_lockp, RW_WRITER);
1562 iss->iss_hg = NULL;
1563 tgid = ilport->ilport_tg;
1564 if (tgid) {
1565 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1566 if (vemap)
1567 stmf_remove_lus_from_session_per_vemap(
1568 iss, vemap);
1569 }
1570 if (vemap_alltgt)
1571 stmf_remove_lus_from_session_per_vemap(iss,
1572 vemap_alltgt);
1573 rw_exit(iss->iss_lockp);
1574 }
1575 }
1576
1577 return (0);
1578 }
1579
1580 /* Assert stmf_lock is already held */
1581 stmf_i_local_port_t *
1582 stmf_targetident_to_ilport(uint8_t *target_ident, uint16_t ident_size)
1583 {
1584 stmf_i_local_port_t *ilport;
1585 uint8_t *id;
1586
1587 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1588
1589 for (ilport = stmf_state.stmf_ilportlist; ilport;
1590 ilport = ilport->ilport_next) {
1591 id = (uint8_t *)ilport->ilport_lport->lport_id;
1592 if ((id[3] == ident_size) &&
1593 bcmp(id + 4, target_ident, ident_size) == 0) {
|