Print this page
Running stmfadm remove-hg-member caused a NULL pointer dereference panic in stmf_remove_lu_from_session
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Running stmfadm remove-hg-member caused a NULL pointer dereference panic in stmf_remove_lu_from_session
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
SUP-770 deadlock between thread acquiring iss->iss_lockp in stmf_task_free() and thread holding sl->sl_pgr->pgr_lock from sbd_pgr_remove_it_handle()
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/io/comstar/stmf/lun_map.c
+++ new/usr/src/uts/common/io/comstar/stmf/lun_map.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #include <sys/conf.h>
26 26 #include <sys/file.h>
27 27 #include <sys/ddi.h>
28 28 #include <sys/sunddi.h>
29 29 #include <sys/modctl.h>
30 30 #include <sys/scsi/scsi.h>
31 31 #include <sys/scsi/impl/scsi_reset_notify.h>
32 32 #include <sys/disp.h>
33 33 #include <sys/byteorder.h>
34 34 #include <sys/atomic.h>
35 35
36 36 #include <sys/stmf.h>
37 37 #include <sys/lpif.h>
38 38 #include <sys/portif.h>
39 39 #include <sys/stmf_ioctl.h>
|
↓ open down ↓ |
39 lines elided |
↑ open up ↑ |
40 40
41 41 #include "stmf_impl.h"
42 42 #include "lun_map.h"
43 43 #include "stmf_state.h"
44 44
45 45 void stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
46 46 stmf_lu_t *lu, int action);
47 47 void stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
48 48 stmf_i_scsi_session_t *iss, stmf_lun_map_t *vemap);
49 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);
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);
52 53 uint16_t stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun);
53 54 stmf_status_t stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
54 55 int allow_special, uint32_t *err_detail);
55 56 stmf_status_t stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
56 57 int allow_special, uint32_t *err_detail);
57 58 stmf_i_local_port_t *stmf_targetident_to_ilport(uint8_t *target_ident,
58 59 uint16_t ident_size);
59 60 stmf_i_scsi_session_t *stmf_lookup_session_for_hostident(
60 61 stmf_i_local_port_t *ilport, uint8_t *host_ident,
61 62 uint16_t ident_size);
62 63 stmf_i_lu_t *stmf_luident_to_ilu(uint8_t *lu_ident);
63 64 stmf_lun_map_t *stmf_get_ve_map_per_ids(stmf_id_data_t *tgid,
64 65 stmf_id_data_t *hgid);
65 66 stmf_lun_map_t *stmf_duplicate_ve_map(stmf_lun_map_t *src);
66 67 int stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
67 68 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf);
68 69 void stmf_destroy_ve_map(stmf_lun_map_t *dst);
69 70 void stmf_free_id(stmf_id_data_t *id);
70 71
71 72
72 73 /*
73 74 * Init the view
74 75 */
75 76 void
76 77 stmf_view_init()
77 78 {
78 79 uint8_t grpname_forall = '*';
79 80 (void) stmf_add_hg(&grpname_forall, 1, 1, NULL);
80 81 (void) stmf_add_tg(&grpname_forall, 1, 1, NULL);
81 82 }
82 83
83 84 /*
84 85 * Clear config database here
85 86 */
86 87 void
87 88 stmf_view_clear_config()
88 89 {
89 90 stmf_id_data_t *idgrp, *idgrp_next, *idmemb, *idmemb_next;
90 91 stmf_ver_tg_t *vtg, *vtg_next;
91 92 stmf_ver_hg_t *vhg, *vhg_next;
92 93 stmf_view_entry_t *ve, *ve_next;
93 94 stmf_i_lu_t *ilu;
94 95 stmf_id_list_t *idlist;
95 96 stmf_i_local_port_t *ilport;
96 97
97 98 for (vtg = stmf_state.stmf_ver_tg_head; vtg; vtg = vtg_next) {
98 99 for (vhg = vtg->vert_verh_list; vhg; vhg = vhg_next) {
99 100 if (vhg->verh_ve_map.lm_nentries) {
100 101 kmem_free(vhg->verh_ve_map.lm_plus,
101 102 vhg->verh_ve_map.lm_nentries *
102 103 sizeof (void *));
103 104 }
104 105 vhg_next = vhg->verh_next;
105 106 kmem_free(vhg, sizeof (stmf_ver_hg_t));
106 107 }
107 108 vtg_next = vtg->vert_next;
108 109 kmem_free(vtg, sizeof (stmf_ver_tg_t));
109 110 }
110 111 stmf_state.stmf_ver_tg_head = NULL;
111 112
112 113 if (stmf_state.stmf_luid_list.id_count) {
113 114 /* clear the views for lus */
114 115 for (idmemb = stmf_state.stmf_luid_list.idl_head;
115 116 idmemb; idmemb = idmemb_next) {
116 117 for (ve = (stmf_view_entry_t *)idmemb->id_impl_specific;
117 118 ve; ve = ve_next) {
118 119 ve_next = ve->ve_next;
119 120 ve->ve_hg->id_refcnt--;
120 121 ve->ve_tg->id_refcnt--;
121 122 kmem_free(ve, sizeof (stmf_view_entry_t));
122 123 }
123 124 if (idmemb->id_pt_to_object) {
124 125 ilu = (stmf_i_lu_t *)(idmemb->id_pt_to_object);
125 126 ilu->ilu_luid = NULL;
126 127 }
127 128 idmemb_next = idmemb->id_next;
128 129 stmf_free_id(idmemb);
129 130 }
130 131 stmf_state.stmf_luid_list.id_count = 0;
131 132 stmf_state.stmf_luid_list.idl_head =
132 133 stmf_state.stmf_luid_list.idl_tail = NULL;
133 134 }
134 135
135 136 if (stmf_state.stmf_hg_list.id_count) {
136 137 /* free all the host group */
137 138 for (idgrp = stmf_state.stmf_hg_list.idl_head;
138 139 idgrp; idgrp = idgrp_next) {
139 140 idlist = (stmf_id_list_t *)(idgrp->id_impl_specific);
140 141 if (idlist->id_count) {
141 142 for (idmemb = idlist->idl_head; idmemb;
142 143 idmemb = idmemb_next) {
143 144 idmemb_next = idmemb->id_next;
144 145 stmf_free_id(idmemb);
145 146 }
146 147 }
147 148 idgrp_next = idgrp->id_next;
148 149 stmf_free_id(idgrp);
149 150 }
150 151 stmf_state.stmf_hg_list.id_count = 0;
151 152 stmf_state.stmf_hg_list.idl_head =
152 153 stmf_state.stmf_hg_list.idl_tail = NULL;
153 154 }
154 155 if (stmf_state.stmf_tg_list.id_count) {
155 156 /* free all the target group */
156 157 for (idgrp = stmf_state.stmf_tg_list.idl_head;
157 158 idgrp; idgrp = idgrp_next) {
158 159 idlist = (stmf_id_list_t *)(idgrp->id_impl_specific);
159 160 if (idlist->id_count) {
160 161 for (idmemb = idlist->idl_head; idmemb;
161 162 idmemb = idmemb_next) {
162 163 idmemb_next = idmemb->id_next;
163 164 stmf_free_id(idmemb);
164 165 }
165 166 }
166 167 idgrp_next = idgrp->id_next;
167 168 stmf_free_id(idgrp);
168 169 }
169 170 stmf_state.stmf_tg_list.id_count = 0;
170 171 stmf_state.stmf_tg_list.idl_head =
171 172 stmf_state.stmf_tg_list.idl_tail = NULL;
|
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
172 173 }
173 174
174 175 for (ilport = stmf_state.stmf_ilportlist; ilport;
175 176 ilport = ilport->ilport_next) {
176 177 ilport->ilport_tg = NULL;
177 178 }
178 179 }
179 180
180 181 /*
181 182 * Create luns map for session based on the view
183 + * iss_lockp is held
182 184 */
183 185 stmf_status_t
184 186 stmf_session_create_lun_map(stmf_i_local_port_t *ilport,
185 187 stmf_i_scsi_session_t *iss)
186 188 {
187 189 stmf_id_data_t *tg;
188 190 stmf_id_data_t *hg;
189 191 stmf_ver_tg_t *vertg;
190 192 char *phg_data, *ptg_data;
191 193 stmf_ver_hg_t *verhg;
192 194 stmf_lun_map_t *ve_map;
193 195
194 196 ASSERT(mutex_owned(&stmf_state.stmf_lock));
195 197
196 198 tg = ilport->ilport_tg;
197 199 hg = stmf_lookup_group_for_host(iss->iss_ss->ss_rport_id->ident,
198 200 iss->iss_ss->ss_rport_id->ident_length);
199 201 iss->iss_hg = hg;
200 202
201 203 /*
202 204 * get the view entry map,
203 205 * take all host/target group into consideration
204 206 */
205 207 ve_map = stmf_duplicate_ve_map(0);
206 208 for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
207 209 vertg = vertg->vert_next) {
208 210 ptg_data = (char *)vertg->vert_tg_ref->id_data;
209 211 if ((ptg_data[0] != '*') && (!tg ||
210 212 ((tg->id_data[0] != '*') &&
211 213 (vertg->vert_tg_ref != tg)))) {
212 214 continue;
213 215 }
214 216 for (verhg = vertg->vert_verh_list; verhg != NULL;
215 217 verhg = verhg->verh_next) {
216 218 phg_data = (char *)verhg->verh_hg_ref->id_data;
217 219 if ((phg_data[0] != '*') && (!hg ||
218 220 ((hg->id_data[0] != '*') &&
219 221 (verhg->verh_hg_ref != hg)))) {
220 222 continue;
221 223 }
222 224 (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
223 225 &ve_map, 0);
224 226 }
225 227 }
226 228
227 229
228 230 if (ve_map->lm_nluns) {
|
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
229 231 stmf_add_lus_to_session_per_vemap(ilport, iss, ve_map);
230 232 }
231 233 /* not configured, cannot access any luns for now */
232 234
233 235 stmf_destroy_ve_map(ve_map);
234 236
235 237 return (STMF_SUCCESS);
236 238 }
237 239
238 240 /*
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 241 * Expects the session lock to be held.
242 + * iss_lockp is held
285 243 */
286 244 stmf_xfer_data_t *
287 245 stmf_session_prepare_report_lun_data(stmf_lun_map_t *sm)
288 246 {
289 247 stmf_xfer_data_t *xd;
290 248 uint16_t nluns, ent;
291 249 uint32_t alloc_size, data_size;
292 250 int i;
293 251
294 252 nluns = sm->lm_nluns;
295 253
296 254 data_size = 8 + (((uint32_t)nluns) << 3);
297 255 if (nluns == 0) {
298 256 data_size += 8;
299 257 }
300 258 alloc_size = data_size + sizeof (stmf_xfer_data_t) - 4;
301 259
302 260 xd = (stmf_xfer_data_t *)kmem_zalloc(alloc_size, KM_NOSLEEP);
303 261
304 262 if (xd == NULL)
305 263 return (NULL);
306 264
307 265 xd->alloc_size = alloc_size;
308 266 xd->size_left = data_size;
309 267
310 268 *((uint32_t *)xd->buf) = BE_32(data_size - 8);
311 269 if (nluns == 0) {
312 270 return (xd);
313 271 }
314 272
315 273 ent = 0;
316 274
317 275 for (i = 0; ((i < sm->lm_nentries) && (ent < nluns)); i++) {
318 276 if (sm->lm_plus[i] == NULL)
319 277 continue;
320 278 /* Fill in the entry */
321 279 xd->buf[8 + (ent << 3) + 1] = (uchar_t)i;
322 280 xd->buf[8 + (ent << 3) + 0] = ((uchar_t)(i >> 8));
323 281 ent++;
324 282 }
325 283
326 284 ASSERT(ent == nluns);
327 285
328 286 return (xd);
329 287 }
330 288
331 289 /*
332 290 * Add a lu to active sessions based on LUN inventory.
333 291 * Only invoked when the lu is onlined
334 292 */
335 293 void
336 294 stmf_add_lu_to_active_sessions(stmf_lu_t *lu)
337 295 {
338 296 stmf_id_data_t *luid;
339 297 stmf_view_entry_t *ve;
340 298 stmf_i_lu_t *ilu;
341 299
342 300 ASSERT(mutex_owned(&stmf_state.stmf_lock));
343 301 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
344 302 ASSERT(ilu->ilu_state == STMF_STATE_ONLINE);
345 303
346 304 luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
347 305
348 306 if (!luid) {
349 307 /* we did not configure view for this lun, so just return */
350 308 return;
351 309 }
352 310
353 311 for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
354 312 ve; ve = ve->ve_next) {
355 313 stmf_update_sessions_per_ve(ve, lu, 1);
356 314 }
357 315 }
358 316 /*
359 317 * Unmap a lun from all sessions
360 318 */
361 319 void
362 320 stmf_session_lu_unmapall(stmf_lu_t *lu)
363 321 {
364 322 stmf_i_lu_t *ilu;
365 323 stmf_id_data_t *luid;
366 324 stmf_view_entry_t *ve;
367 325
368 326 ASSERT(mutex_owned(&stmf_state.stmf_lock));
369 327
370 328 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
371 329
372 330 if (ilu->ilu_ref_cnt == 0)
373 331 return;
374 332
375 333 luid = ((stmf_i_lu_t *)lu->lu_stmf_private)->ilu_luid;
376 334 if (!luid) {
377 335 /*
378 336 * we did not configure view for this lun, this should be
379 337 * an error
380 338 */
381 339 return;
382 340 }
|
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
383 341
384 342 for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
385 343 ve; ve = ve->ve_next) {
386 344 stmf_update_sessions_per_ve(ve, lu, 0);
387 345 if (ilu->ilu_ref_cnt == 0)
388 346 break;
389 347 }
390 348 }
391 349 /*
392 350 * add lu to a session, stmf_lock is already held
351 + * iss_lockp/ilport_lock already held
393 352 */
394 -stmf_status_t
353 +static stmf_status_t
395 354 stmf_add_lu_to_session(stmf_i_local_port_t *ilport,
396 355 stmf_i_scsi_session_t *iss,
397 356 stmf_lu_t *lu,
398 357 uint8_t *lu_nbr)
399 358 {
400 359 stmf_lun_map_t *sm = iss->iss_sm;
401 360 stmf_status_t ret;
402 361 stmf_i_lu_t *ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
403 362 stmf_lun_map_ent_t *lun_map_ent;
404 363 uint32_t new_flags = 0;
405 364 uint16_t luNbr =
406 365 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
407 366
408 367 ASSERT(mutex_owned(&stmf_state.stmf_lock));
409 368 ASSERT(!stmf_get_ent_from_map(sm, luNbr));
410 369
411 370 if ((sm->lm_nluns == 0) &&
412 371 ((iss->iss_flags & ISS_BEING_CREATED) == 0)) {
413 372 new_flags = ISS_GOT_INITIAL_LUNS;
414 373 atomic_or_32(&ilport->ilport_flags, ILPORT_SS_GOT_INITIAL_LUNS);
415 374 stmf_state.stmf_process_initial_luns = 1;
416 375 }
417 376
418 377 lun_map_ent = (stmf_lun_map_ent_t *)
419 378 kmem_zalloc(sizeof (stmf_lun_map_ent_t), KM_SLEEP);
420 379 lun_map_ent->ent_lu = lu;
421 380 ret = stmf_add_ent_to_map(sm, (void *)lun_map_ent, lu_nbr);
422 381 ASSERT(ret == STMF_SUCCESS);
423 382 atomic_inc_32(&ilu->ilu_ref_cnt);
424 383 /*
425 384 * do not set lun inventory flag for standby port
426 385 * as this would be handled from peer
|
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
427 386 */
428 387 if (ilport->ilport_standby == 0) {
429 388 new_flags |= ISS_LUN_INVENTORY_CHANGED;
430 389 }
431 390 atomic_or_32(&iss->iss_flags, new_flags);
432 391 return (STMF_SUCCESS);
433 392 }
434 393
435 394 /*
436 395 * remvoe lu from a session, stmf_lock is already held
396 + * iss_lockp held
437 397 */
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)
398 +static void
399 +stmf_remove_lu_from_session(stmf_i_scsi_session_t *iss,
400 + stmf_lu_t *lu, uint8_t *lu_nbr)
444 401 {
445 402 stmf_status_t ret;
446 403 stmf_i_lu_t *ilu;
447 404 stmf_lun_map_t *sm = iss->iss_sm;
448 405 stmf_lun_map_ent_t *lun_map_ent;
449 406 uint16_t luNbr =
450 407 ((uint16_t)lu_nbr[1] | (((uint16_t)(lu_nbr[0] & 0x3F)) << 8));
451 408
452 409 ASSERT(mutex_owned(&stmf_state.stmf_lock));
453 410 lun_map_ent = stmf_get_ent_from_map(sm, luNbr);
454 - ASSERT(lun_map_ent && lun_map_ent->ent_lu == lu);
411 + ASSERT(lun_map_ent->ent_lu == lu);
412 + if (lun_map_ent == NULL) {
413 + return;
414 + }
455 415
456 416 ilu = (stmf_i_lu_t *)lu->lu_stmf_private;
457 417
458 418 ret = stmf_remove_ent_from_map(sm, lu_nbr);
459 419 ASSERT(ret == STMF_SUCCESS);
460 420 atomic_dec_32(&ilu->ilu_ref_cnt);
461 421 iss->iss_flags |= ISS_LUN_INVENTORY_CHANGED;
462 422 if (lun_map_ent->ent_itl_datap) {
463 423 stmf_do_itl_dereg(lu, lun_map_ent->ent_itl_datap,
464 424 STMF_ITL_REASON_USER_REQUEST);
465 425 }
466 426 kmem_free((void *)lun_map_ent, sizeof (stmf_lun_map_ent_t));
467 - return (STMF_SUCCESS);
468 427 }
469 428
470 429 /*
471 430 * add or remove lu from all related sessions based on view entry,
472 431 * action is 0 for delete, 1 for add
473 432 */
474 433 void
475 434 stmf_update_sessions_per_ve(stmf_view_entry_t *ve,
476 435 stmf_lu_t *lu, int action)
477 436 {
478 437 stmf_i_lu_t *ilu_tmp;
479 438 stmf_lu_t *lu_to_add;
480 439 stmf_i_local_port_t *ilport;
481 440 stmf_i_scsi_session_t *iss;
482 441 stmf_id_list_t *hostlist;
483 442 stmf_id_list_t *targetlist;
484 443 int all_hg = 0, all_tg = 0;
485 444
486 445 ASSERT(mutex_owned(&stmf_state.stmf_lock));
487 446
488 447 if (!lu) {
489 448 ilu_tmp = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
490 449 if (!ilu_tmp)
491 450 return;
492 451 lu_to_add = ilu_tmp->ilu_lu;
493 452 } else {
494 453 lu_to_add = lu;
495 454 ilu_tmp = (stmf_i_lu_t *)lu->lu_stmf_private;
496 455 }
497 456
498 457 if (ve->ve_hg->id_data[0] == '*')
499 458 all_hg = 1;
500 459 if (ve->ve_tg->id_data[0] == '*')
501 460 all_tg = 1;
502 461 hostlist = (stmf_id_list_t *)ve->ve_hg->id_impl_specific;
503 462 targetlist = (stmf_id_list_t *)ve->ve_tg->id_impl_specific;
504 463
505 464 if ((!all_hg && !hostlist->idl_head) ||
506 465 (!all_tg && !targetlist->idl_head))
507 466 /* No sessions to be updated */
508 467 return;
509 468
510 469 for (ilport = stmf_state.stmf_ilportlist; ilport != NULL;
511 470 ilport = ilport->ilport_next) {
|
↓ open down ↓ |
34 lines elided |
↑ open up ↑ |
512 471 if (!all_tg && ilport->ilport_tg != ve->ve_tg)
513 472 continue;
514 473 /* This ilport belongs to the target group */
515 474 rw_enter(&ilport->ilport_lock, RW_WRITER);
516 475 for (iss = ilport->ilport_ss_list; iss != NULL;
517 476 iss = iss->iss_next) {
518 477 if (!all_hg && iss->iss_hg != ve->ve_hg)
519 478 continue;
520 479 /* This host belongs to the host group */
521 480 if (action == 0) { /* to remove */
522 - (void) stmf_remove_lu_from_session(ilport, iss,
523 - lu_to_add, ve->ve_lun);
481 + stmf_remove_lu_from_session(iss, lu_to_add,
482 + ve->ve_lun);
524 483 if (ilu_tmp->ilu_ref_cnt == 0) {
525 484 rw_exit(&ilport->ilport_lock);
526 485 return;
527 486 }
528 487 } else {
529 488 (void) stmf_add_lu_to_session(ilport, iss,
530 489 lu_to_add, ve->ve_lun);
531 490 }
532 491 }
533 492 rw_exit(&ilport->ilport_lock);
534 493 }
535 494 }
536 495
537 496 /*
538 497 * add luns in view entry map to a session,
539 498 * and stmf_lock is already held
540 499 */
541 500 void
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
542 501 stmf_add_lus_to_session_per_vemap(stmf_i_local_port_t *ilport,
543 502 stmf_i_scsi_session_t *iss,
544 503 stmf_lun_map_t *vemap)
545 504 {
546 505 stmf_lu_t *lu;
547 506 stmf_i_lu_t *ilu;
548 507 stmf_view_entry_t *ve;
549 508 uint32_t i;
550 509
551 510 ASSERT(mutex_owned(&stmf_state.stmf_lock));
552 -
553 511 for (i = 0; i < vemap->lm_nentries; i++) {
554 512 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
555 513 if (!ve)
556 514 continue;
557 515 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
558 516 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
559 517 lu = ilu->ilu_lu;
560 518 (void) stmf_add_lu_to_session(ilport, iss, lu,
561 519 ve->ve_lun);
562 520 }
563 521 }
564 522 }
565 -/* remove luns in view entry map from a session */
523 +/*
524 + * remove luns in view entry map from a session
525 + * iss_lockp held
526 + */
566 527 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)
528 +stmf_remove_lus_from_session_per_vemap(stmf_i_scsi_session_t *iss,
529 + stmf_lun_map_t *vemap)
570 530 {
571 531 stmf_lu_t *lu;
572 532 stmf_i_lu_t *ilu;
573 533 stmf_view_entry_t *ve;
574 534 uint32_t i;
575 535
576 536 ASSERT(mutex_owned(&stmf_state.stmf_lock));
577 537
578 538 for (i = 0; i < vemap->lm_nentries; i++) {
579 539 ve = (stmf_view_entry_t *)vemap->lm_plus[i];
580 540 if (!ve)
581 541 continue;
582 542 ilu = (stmf_i_lu_t *)ve->ve_luid->id_pt_to_object;
583 543 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE) {
584 544 lu = ilu->ilu_lu;
585 - (void) stmf_remove_lu_from_session(ilport, iss, lu,
586 - ve->ve_lun);
545 + stmf_remove_lu_from_session(iss, lu, ve->ve_lun);
587 546 }
588 547 }
589 548 }
590 549
591 550 stmf_id_data_t *
592 551 stmf_alloc_id(uint16_t id_size, uint16_t type, uint8_t *id_data,
593 552 uint32_t additional_size)
594 553 {
595 554 stmf_id_data_t *id;
596 555 int struct_size, total_size, real_id_size;
597 556
598 557 real_id_size = ((uint32_t)id_size + 7) & (~7);
599 558 struct_size = (sizeof (*id) + 7) & (~7);
600 559 total_size = ((additional_size + 7) & (~7)) + struct_size +
601 560 real_id_size;
602 561 id = (stmf_id_data_t *)kmem_zalloc(total_size, KM_SLEEP);
603 562 id->id_type = type;
604 563 id->id_data_size = id_size;
605 564 id->id_data = ((uint8_t *)id) + struct_size;
606 565 id->id_total_alloc_size = total_size;
607 566 if (additional_size) {
608 567 id->id_impl_specific = ((uint8_t *)id) + struct_size +
609 568 real_id_size;
610 569 }
611 570 bcopy(id_data, id->id_data, id_size);
612 571
613 572 return (id);
614 573 }
615 574
616 575 void
617 576 stmf_free_id(stmf_id_data_t *id)
618 577 {
619 578 kmem_free(id, id->id_total_alloc_size);
620 579 }
621 580
622 581
623 582 stmf_id_data_t *
624 583 stmf_lookup_id(stmf_id_list_t *idlist, uint16_t id_size, uint8_t *data)
625 584 {
626 585 stmf_id_data_t *id;
627 586
628 587 for (id = idlist->idl_head; id != NULL; id = id->id_next) {
629 588 if ((id->id_data_size == id_size) &&
630 589 (bcmp(id->id_data, data, id_size) == 0)) {
631 590 return (id);
632 591 }
633 592 }
634 593
635 594 return (NULL);
636 595 }
637 596 /* Return the target group which a target belong to */
638 597 stmf_id_data_t *
639 598 stmf_lookup_group_for_target(uint8_t *ident, uint16_t ident_size)
640 599 {
641 600 stmf_id_data_t *tgid;
642 601 stmf_id_data_t *target;
643 602
644 603 ASSERT(mutex_owned(&stmf_state.stmf_lock));
645 604
646 605 for (tgid = stmf_state.stmf_tg_list.idl_head; tgid;
647 606 tgid = tgid->id_next) {
648 607 target = stmf_lookup_id(
649 608 (stmf_id_list_t *)tgid->id_impl_specific,
650 609 ident_size, ident);
651 610 if (target)
652 611 return (tgid);
653 612 }
654 613 return (NULL);
655 614 }
656 615 /* Return the host group which a host belong to */
657 616 stmf_id_data_t *
658 617 stmf_lookup_group_for_host(uint8_t *ident, uint16_t ident_size)
659 618 {
660 619 stmf_id_data_t *hgid;
661 620 stmf_id_data_t *host;
662 621
663 622 ASSERT(mutex_owned(&stmf_state.stmf_lock));
664 623
665 624 for (hgid = stmf_state.stmf_hg_list.idl_head; hgid;
666 625 hgid = hgid->id_next) {
667 626 host = stmf_lookup_id(
668 627 (stmf_id_list_t *)hgid->id_impl_specific,
669 628 ident_size, ident);
670 629 if (host)
671 630 return (hgid);
672 631 }
673 632 return (NULL);
674 633 }
675 634
676 635 void
677 636 stmf_append_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
678 637 {
679 638 id->id_next = NULL;
680 639
681 640 if ((id->id_prev = idlist->idl_tail) == NULL) {
682 641 idlist->idl_head = idlist->idl_tail = id;
683 642 } else {
684 643 idlist->idl_tail->id_next = id;
685 644 idlist->idl_tail = id;
686 645 }
687 646 atomic_inc_32(&idlist->id_count);
688 647 }
689 648
690 649 void
691 650 stmf_remove_id(stmf_id_list_t *idlist, stmf_id_data_t *id)
692 651 {
693 652 if (id->id_next) {
694 653 id->id_next->id_prev = id->id_prev;
695 654 } else {
696 655 idlist->idl_tail = id->id_prev;
697 656 }
698 657
699 658 if (id->id_prev) {
700 659 id->id_prev->id_next = id->id_next;
701 660 } else {
702 661 idlist->idl_head = id->id_next;
|
↓ open down ↓ |
106 lines elided |
↑ open up ↑ |
703 662 }
704 663 atomic_dec_32(&idlist->id_count);
705 664 }
706 665
707 666
708 667 /*
709 668 * The refcnts of objects in a view entry are updated when then entry
710 669 * is successfully added. ve_map is just another representation of the
711 670 * view enrtries in a LU. Duplicating or merging a ve map does not
712 671 * affect any refcnts.
672 + * stmf_state.stmf_lock held
713 673 */
714 674 stmf_lun_map_t *
715 675 stmf_duplicate_ve_map(stmf_lun_map_t *src)
716 676 {
717 677 stmf_lun_map_t *dst;
718 678 int i;
719 679
720 680 dst = (stmf_lun_map_t *)kmem_zalloc(sizeof (*dst), KM_SLEEP);
721 681
722 682 if (src == NULL)
723 683 return (dst);
724 684
725 685 if (src->lm_nentries) {
726 686 dst->lm_plus = kmem_zalloc(dst->lm_nentries *
727 687 sizeof (void *), KM_SLEEP);
728 688 for (i = 0; i < dst->lm_nentries; i++) {
729 689 dst->lm_plus[i] = src->lm_plus[i];
730 690 }
731 691 }
732 692
733 693 return (dst);
734 694 }
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
735 695
736 696 void
737 697 stmf_destroy_ve_map(stmf_lun_map_t *dst)
738 698 {
739 699 if (dst->lm_nentries) {
740 700 kmem_free(dst->lm_plus, dst->lm_nentries * sizeof (void *));
741 701 }
742 702 kmem_free(dst, sizeof (*dst));
743 703 }
744 704
705 +/*
706 + * stmf_state.stmf_lock held. Operations are stmf global in nature and
707 + * not session level.
708 + */
745 709 int
746 710 stmf_merge_ve_map(stmf_lun_map_t *src, stmf_lun_map_t *dst,
747 711 stmf_lun_map_t **pp_ret_map, stmf_merge_flags_t mf)
748 712 {
749 713 int i;
750 714 int nentries;
751 715 int to_create_space = 0;
752 716
753 717 if (dst == NULL) {
754 718 *pp_ret_map = stmf_duplicate_ve_map(src);
755 719 return (1);
756 720 }
757 721
758 722 if (src == NULL || src->lm_nluns == 0) {
759 723 if (mf & MERGE_FLAG_RETURN_NEW_MAP)
760 724 *pp_ret_map = stmf_duplicate_ve_map(dst);
761 725 else
762 726 *pp_ret_map = dst;
763 727 return (1);
764 728 }
765 729
766 730 if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
767 731 *pp_ret_map = stmf_duplicate_ve_map(NULL);
768 732 nentries = max(dst->lm_nentries, src->lm_nentries);
769 733 to_create_space = 1;
770 734 } else {
771 735 *pp_ret_map = dst;
772 736 /* If there is not enough space in dst map */
773 737 if (dst->lm_nentries < src->lm_nentries) {
774 738 nentries = src->lm_nentries;
775 739 to_create_space = 1;
776 740 }
777 741 }
778 742 if (to_create_space) {
779 743 void **p;
780 744 p = (void **)kmem_zalloc(nentries * sizeof (void *), KM_SLEEP);
781 745 if (dst->lm_nentries) {
782 746 bcopy(dst->lm_plus, p,
783 747 dst->lm_nentries * sizeof (void *));
784 748 }
785 749 if (mf & (MERGE_FLAG_RETURN_NEW_MAP == 0))
786 750 kmem_free(dst->lm_plus,
787 751 dst->lm_nentries * sizeof (void *));
788 752 (*pp_ret_map)->lm_plus = p;
789 753 (*pp_ret_map)->lm_nentries = nentries;
790 754 }
791 755
792 756 for (i = 0; i < src->lm_nentries; i++) {
793 757 if (src->lm_plus[i] == NULL)
794 758 continue;
795 759 if (dst->lm_plus[i] != NULL) {
796 760 if (mf & MERGE_FLAG_NO_DUPLICATE) {
797 761 if (mf & MERGE_FLAG_RETURN_NEW_MAP) {
798 762 stmf_destroy_ve_map(*pp_ret_map);
799 763 *pp_ret_map = NULL;
800 764 }
801 765 return (0);
802 766 }
803 767 } else {
804 768 dst->lm_plus[i] = src->lm_plus[i];
805 769 dst->lm_nluns++;
806 770 }
807 771 }
808 772
809 773 return (1);
810 774 }
811 775
812 776 /*
813 777 * add host group, id_impl_specific point to a list of hosts,
814 778 * on return, if error happened, err_detail may be assigned if
815 779 * the pointer is not NULL
816 780 */
817 781 stmf_status_t
818 782 stmf_add_hg(uint8_t *hg_name, uint16_t hg_name_size,
819 783 int allow_special, uint32_t *err_detail)
820 784 {
821 785 stmf_id_data_t *id;
822 786
823 787 if (!allow_special) {
824 788 if (hg_name[0] == '*')
825 789 return (STMF_INVALID_ARG);
826 790 }
827 791
828 792 if (stmf_lookup_id(&stmf_state.stmf_hg_list,
829 793 hg_name_size, (uint8_t *)hg_name)) {
830 794 if (err_detail)
831 795 *err_detail = STMF_IOCERR_HG_EXISTS;
832 796 return (STMF_ALREADY);
833 797 }
834 798 id = stmf_alloc_id(hg_name_size, STMF_ID_TYPE_HOST_GROUP,
835 799 (uint8_t *)hg_name, sizeof (stmf_id_list_t));
836 800 stmf_append_id(&stmf_state.stmf_hg_list, id);
837 801
838 802 return (STMF_SUCCESS);
839 803 }
840 804
841 805 /* add target group */
842 806 stmf_status_t
843 807 stmf_add_tg(uint8_t *tg_name, uint16_t tg_name_size,
844 808 int allow_special, uint32_t *err_detail)
845 809 {
846 810 stmf_id_data_t *id;
847 811
848 812 if (!allow_special) {
849 813 if (tg_name[0] == '*')
850 814 return (STMF_INVALID_ARG);
851 815 }
852 816
853 817
854 818 if (stmf_lookup_id(&stmf_state.stmf_tg_list, tg_name_size,
855 819 (uint8_t *)tg_name)) {
856 820 if (err_detail)
857 821 *err_detail = STMF_IOCERR_TG_EXISTS;
858 822 return (STMF_ALREADY);
859 823 }
860 824 id = stmf_alloc_id(tg_name_size, STMF_ID_TYPE_TARGET_GROUP,
861 825 (uint8_t *)tg_name, sizeof (stmf_id_list_t));
862 826 stmf_append_id(&stmf_state.stmf_tg_list, id);
863 827
864 828 return (STMF_SUCCESS);
865 829 }
866 830
867 831 /*
868 832 * insert view entry into list for a luid, if ve->ve_id is 0xffffffff,
869 833 * pick up a smallest available veid for it, and return the veid in ve->ve_id.
870 834 * The view entries list is sorted based on veid.
871 835 */
872 836 stmf_status_t
873 837 stmf_add_ve_to_luid(stmf_id_data_t *luid, stmf_view_entry_t *ve)
874 838 {
875 839 stmf_view_entry_t *ve_tmp = NULL;
876 840 stmf_view_entry_t *ve_prev = NULL;
877 841
878 842 ASSERT(mutex_owned(&stmf_state.stmf_lock));
879 843
880 844 ve_tmp = (stmf_view_entry_t *)luid->id_impl_specific;
881 845
882 846 if (ve->ve_id != 0xffffffff) {
883 847 for (; ve_tmp; ve_tmp = ve_tmp->ve_next) {
884 848 if (ve_tmp->ve_id > ve->ve_id) {
885 849 break;
886 850 } else if (ve_tmp->ve_id == ve->ve_id) {
887 851 return (STMF_ALREADY);
888 852 }
889 853 ve_prev = ve_tmp;
890 854 }
891 855 } else {
892 856 uint32_t veid = 0;
893 857 /* search the smallest available veid */
894 858 for (; ve_tmp; ve_tmp = ve_tmp->ve_next) {
895 859 ASSERT(ve_tmp->ve_id >= veid);
896 860 if (ve_tmp->ve_id != veid)
897 861 break;
898 862 veid++;
899 863 if (veid == 0xffffffff)
900 864 return (STMF_NOT_SUPPORTED);
901 865 ve_prev = ve_tmp;
902 866 }
903 867 ve->ve_id = veid;
904 868 }
905 869
906 870 /* insert before ve_tmp if it exist */
907 871 ve->ve_next = ve_tmp;
908 872 ve->ve_prev = ve_prev;
909 873 if (ve_tmp) {
910 874 ve_tmp->ve_prev = ve;
911 875 }
912 876 if (ve_prev) {
913 877 ve_prev->ve_next = ve;
914 878 } else {
915 879 luid->id_impl_specific = (void *)ve;
916 880 }
917 881 return (STMF_SUCCESS);
918 882 }
919 883
920 884 /* stmf_lock is already held, err_detail may be assigned if error happens */
921 885 stmf_status_t
922 886 stmf_add_view_entry(stmf_id_data_t *hg, stmf_id_data_t *tg,
923 887 uint8_t *lu_guid, uint32_t *ve_id, uint8_t *lun,
924 888 stmf_view_entry_t **conflicting, uint32_t *err_detail)
925 889 {
926 890 stmf_id_data_t *luid;
927 891 stmf_view_entry_t *ve;
928 892 char *phg, *ptg;
929 893 stmf_lun_map_t *ve_map = NULL;
930 894 stmf_ver_hg_t *verhg = NULL, *verhg_ex = NULL;
931 895 stmf_ver_tg_t *vertg = NULL, *vertg_ex = NULL;
932 896 char luid_new;
933 897 uint16_t lun_num;
934 898 stmf_i_lu_t *ilu;
935 899 stmf_status_t ret;
936 900
937 901 ASSERT(mutex_owned(&stmf_state.stmf_lock));
938 902
939 903 lun_num = ((uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8));
940 904
941 905 luid = stmf_lookup_id(&stmf_state.stmf_luid_list, 16, lu_guid);
942 906 if (luid == NULL) {
943 907 luid = stmf_alloc_id(16, STMF_ID_TYPE_LU_GUID, lu_guid, 0);
944 908 ilu = stmf_luident_to_ilu(lu_guid);
945 909 if (ilu) {
946 910 ilu->ilu_luid = luid;
947 911 luid->id_pt_to_object = (void *)ilu;
948 912 }
949 913 luid_new = 1;
950 914 } else {
951 915 luid_new = 0;
952 916 ilu = (stmf_i_lu_t *)luid->id_pt_to_object;
953 917 }
954 918
955 919 /* The view entry won't be added if there is any confilict */
956 920 phg = (char *)hg->id_data; ptg = (char *)tg->id_data;
957 921 for (ve = (stmf_view_entry_t *)luid->id_impl_specific; ve != NULL;
958 922 ve = ve->ve_next) {
959 923 if (((phg[0] == '*') || (ve->ve_hg->id_data[0] == '*') ||
960 924 (hg == ve->ve_hg)) && ((ptg[0] == '*') ||
961 925 (ve->ve_tg->id_data[0] == '*') || (tg == ve->ve_tg))) {
962 926 *conflicting = ve;
963 927 *err_detail = STMF_IOCERR_VIEW_ENTRY_CONFLICT;
964 928 ret = STMF_ALREADY;
965 929 goto add_ve_err_ret;
966 930 }
967 931 }
968 932
969 933 ve_map = stmf_duplicate_ve_map(0);
970 934 for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
971 935 vertg = vertg->vert_next) {
972 936 ptg = (char *)vertg->vert_tg_ref->id_data;
973 937 if ((ptg[0] != '*') && (tg->id_data[0] != '*') &&
974 938 (vertg->vert_tg_ref != tg)) {
975 939 continue;
976 940 }
977 941 if (vertg->vert_tg_ref == tg)
978 942 vertg_ex = vertg;
979 943 for (verhg = vertg->vert_verh_list; verhg != NULL;
980 944 verhg = verhg->verh_next) {
981 945 phg = (char *)verhg->verh_hg_ref->id_data;
982 946 if ((phg[0] != '*') && (hg->id_data[0] != '*') &&
983 947 (verhg->verh_hg_ref != hg)) {
984 948 continue;
985 949 }
986 950 if ((vertg_ex == vertg) && (verhg->verh_hg_ref == hg))
987 951 verhg_ex = verhg;
988 952 (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
989 953 &ve_map, 0);
990 954 }
991 955 }
992 956
993 957 if (lun[2] == 0xFF) {
994 958 /* Pick a LUN number */
995 959 lun_num = stmf_get_next_free_lun(ve_map, lun);
996 960 if (lun_num > 0x3FFF) {
997 961 stmf_destroy_ve_map(ve_map);
998 962 ret = STMF_NOT_SUPPORTED;
999 963 goto add_ve_err_ret;
1000 964 }
1001 965 } else {
1002 966 if ((*conflicting = stmf_get_ent_from_map(ve_map, lun_num))
1003 967 != NULL) {
1004 968 stmf_destroy_ve_map(ve_map);
1005 969 *err_detail = STMF_IOCERR_LU_NUMBER_IN_USE;
1006 970 ret = STMF_LUN_TAKEN;
1007 971 goto add_ve_err_ret;
1008 972 }
1009 973 }
1010 974 stmf_destroy_ve_map(ve_map);
1011 975
1012 976 /* All is well, do the actual addition now */
1013 977 ve = (stmf_view_entry_t *)kmem_zalloc(sizeof (*ve), KM_SLEEP);
1014 978 ve->ve_id = *ve_id;
1015 979 ve->ve_lun[0] = lun[0];
1016 980 ve->ve_lun[1] = lun[1];
1017 981
1018 982 if ((ret = stmf_add_ve_to_luid(luid, ve)) != STMF_SUCCESS) {
1019 983 kmem_free(ve, sizeof (stmf_view_entry_t));
1020 984 goto add_ve_err_ret;
1021 985 }
1022 986 ve->ve_hg = hg; hg->id_refcnt++;
1023 987 ve->ve_tg = tg; tg->id_refcnt++;
1024 988 ve->ve_luid = luid; luid->id_refcnt++;
1025 989
1026 990 *ve_id = ve->ve_id;
1027 991
1028 992 if (luid_new) {
1029 993 stmf_append_id(&stmf_state.stmf_luid_list, luid);
1030 994 }
1031 995
1032 996 if (vertg_ex == NULL) {
1033 997 vertg_ex = (stmf_ver_tg_t *)kmem_zalloc(sizeof (stmf_ver_tg_t),
1034 998 KM_SLEEP);
1035 999 vertg_ex->vert_next = stmf_state.stmf_ver_tg_head;
1036 1000 stmf_state.stmf_ver_tg_head = vertg_ex;
1037 1001 vertg_ex->vert_tg_ref = tg;
1038 1002 verhg_ex = vertg_ex->vert_verh_list =
1039 1003 (stmf_ver_hg_t *)kmem_zalloc(sizeof (stmf_ver_hg_t),
1040 1004 KM_SLEEP);
1041 1005 verhg_ex->verh_hg_ref = hg;
1042 1006 }
1043 1007 if (verhg_ex == NULL) {
1044 1008 verhg_ex = (stmf_ver_hg_t *)kmem_zalloc(sizeof (stmf_ver_hg_t),
1045 1009 KM_SLEEP);
1046 1010 verhg_ex->verh_next = vertg_ex->vert_verh_list;
1047 1011 vertg_ex->vert_verh_list = verhg_ex;
1048 1012 verhg_ex->verh_hg_ref = hg;
1049 1013 }
1050 1014 ret = stmf_add_ent_to_map(&verhg_ex->verh_ve_map, ve, ve->ve_lun);
1051 1015 ASSERT(ret == STMF_SUCCESS);
1052 1016
1053 1017 /* we need to update the affected session */
1054 1018 if (stmf_state.stmf_service_running) {
1055 1019 if (ilu && ilu->ilu_state == STMF_STATE_ONLINE)
1056 1020 stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 1);
1057 1021 }
1058 1022
|
↓ open down ↓ |
304 lines elided |
↑ open up ↑ |
1059 1023 return (STMF_SUCCESS);
1060 1024 add_ve_err_ret:
1061 1025 if (luid_new) {
1062 1026 if (ilu)
1063 1027 ilu->ilu_luid = NULL;
1064 1028 stmf_free_id(luid);
1065 1029 }
1066 1030 return (ret);
1067 1031 }
1068 1032
1069 -stmf_status_t
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
1070 1038 stmf_add_ent_to_map(stmf_lun_map_t *lm, void *ent, uint8_t *lun)
1071 1039 {
1072 1040 uint16_t n;
1073 1041 if (((lun[0] & 0xc0) >> 6) != 0)
1074 1042 return (STMF_FAILURE);
1075 1043
1076 1044 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1077 1045 try_again_to_add:
1078 1046 if (lm->lm_nentries && (n < lm->lm_nentries)) {
1079 1047 if (lm->lm_plus[n] == NULL) {
1080 1048 lm->lm_plus[n] = ent;
1081 1049 lm->lm_nluns++;
1082 1050 return (STMF_SUCCESS);
1083 1051 } else {
1084 1052 return (STMF_LUN_TAKEN);
1085 1053 }
1086 1054 } else {
1087 1055 void **pplu;
1088 1056 uint16_t m = n + 1;
1089 1057 m = ((m + 7) & ~7) & 0x7FFF;
1090 1058 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1091 1059 bcopy(lm->lm_plus, pplu,
1092 1060 lm->lm_nentries * sizeof (void *));
1093 1061 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1094 1062 lm->lm_plus = pplu;
1095 1063 lm->lm_nentries = m;
1096 1064 goto try_again_to_add;
1097 1065 }
1098 1066 }
1099 1067
1100 1068
1101 -stmf_status_t
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
1102 1074 stmf_remove_ent_from_map(stmf_lun_map_t *lm, uint8_t *lun)
1103 1075 {
1104 1076 uint16_t n, i;
1105 1077 uint8_t lutype = (lun[0] & 0xc0) >> 6;
1106 1078 if (lutype != 0)
1107 1079 return (STMF_FAILURE);
1108 1080
1109 1081 n = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1110 1082
1111 1083 if (n >= lm->lm_nentries)
1112 1084 return (STMF_NOT_FOUND);
1113 1085 if (lm->lm_plus[n] == NULL)
1114 1086 return (STMF_NOT_FOUND);
1115 1087
1116 1088 lm->lm_plus[n] = NULL;
1117 1089 lm->lm_nluns--;
1118 1090
1119 1091 for (i = 0; i < lm->lm_nentries; i++) {
1120 1092 if (lm->lm_plus[lm->lm_nentries - 1 - i] != NULL)
1121 1093 break;
1122 1094 }
1123 1095 i &= ~15;
1124 1096 if (i >= 16) {
1125 1097 void **pplu;
1126 1098 uint16_t m;
1127 1099 m = lm->lm_nentries - i;
|
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
1128 1100 pplu = (void **)kmem_zalloc(m * sizeof (void *), KM_SLEEP);
1129 1101 bcopy(lm->lm_plus, pplu, m * sizeof (void *));
1130 1102 kmem_free(lm->lm_plus, lm->lm_nentries * sizeof (void *));
1131 1103 lm->lm_plus = pplu;
1132 1104 lm->lm_nentries = m;
1133 1105 }
1134 1106
1135 1107 return (STMF_SUCCESS);
1136 1108 }
1137 1109
1110 +/*
1111 + * stmf_state.stmf_lock held
1112 + */
1138 1113 uint16_t
1139 1114 stmf_get_next_free_lun(stmf_lun_map_t *sm, uint8_t *lun)
1140 1115 {
1141 1116 uint16_t luNbr;
1142 1117
1143 1118
1144 1119 if (sm->lm_nluns < 0x4000) {
1145 1120 for (luNbr = 0; luNbr < sm->lm_nentries; luNbr++) {
1146 1121 if (sm->lm_plus[luNbr] == NULL)
1147 1122 break;
1148 1123 }
1149 1124 } else {
1150 1125 return (0xFFFF);
|
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
1151 1126 }
1152 1127 if (lun) {
1153 1128 bzero(lun, 8);
1154 1129 lun[1] = luNbr & 0xff;
1155 1130 lun[0] = (luNbr >> 8) & 0xff;
1156 1131 }
1157 1132
1158 1133 return (luNbr);
1159 1134 }
1160 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 + */
1161 1140 void *
1162 1141 stmf_get_ent_from_map(stmf_lun_map_t *sm, uint16_t lun_num)
1163 1142 {
1164 1143 if ((lun_num & 0xC000) == 0) {
1165 1144 if (sm->lm_nentries > lun_num)
1166 1145 return (sm->lm_plus[lun_num & 0x3FFF]);
1167 1146 else
1168 1147 return (NULL);
1169 1148 }
1170 1149
1171 1150 return (NULL);
1172 1151 }
1173 1152
1174 1153 int
1175 1154 stmf_add_ve(uint8_t *hgname, uint16_t hgname_size,
1176 1155 uint8_t *tgname, uint16_t tgname_size,
1177 1156 uint8_t *lu_guid, uint32_t *ve_id,
1178 1157 uint8_t *luNbr, uint32_t *err_detail)
1179 1158 {
1180 1159 stmf_id_data_t *hg;
1181 1160 stmf_id_data_t *tg;
1182 1161 stmf_view_entry_t *conflictve;
1183 1162 stmf_status_t ret;
1184 1163
1185 1164 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1186 1165
1187 1166 hg = stmf_lookup_id(&stmf_state.stmf_hg_list, hgname_size,
1188 1167 (uint8_t *)hgname);
1189 1168 if (!hg) {
1190 1169 *err_detail = STMF_IOCERR_INVALID_HG;
1191 1170 return (ENOENT); /* could not find group */
1192 1171 }
1193 1172 tg = stmf_lookup_id(&stmf_state.stmf_tg_list, tgname_size,
1194 1173 (uint8_t *)tgname);
1195 1174 if (!tg) {
1196 1175 *err_detail = STMF_IOCERR_INVALID_TG;
1197 1176 return (ENOENT); /* could not find group */
1198 1177 }
1199 1178 ret = stmf_add_view_entry(hg, tg, lu_guid, ve_id, luNbr,
1200 1179 &conflictve, err_detail);
1201 1180
1202 1181 if (ret == STMF_ALREADY) {
1203 1182 return (EALREADY);
1204 1183 } else if (ret == STMF_LUN_TAKEN) {
1205 1184 return (EEXIST);
1206 1185 } else if (ret == STMF_NOT_SUPPORTED) {
1207 1186 return (E2BIG);
1208 1187 } else if (ret != STMF_SUCCESS) {
1209 1188 return (EINVAL);
1210 1189 }
1211 1190 return (0);
1212 1191 }
1213 1192
1214 1193 int
1215 1194 stmf_remove_ve_by_id(uint8_t *guid, uint32_t veid, uint32_t *err_detail)
1216 1195 {
1217 1196 stmf_id_data_t *luid;
1218 1197 stmf_view_entry_t *ve;
1219 1198 stmf_ver_tg_t *vtg;
1220 1199 stmf_ver_hg_t *vhg;
1221 1200 stmf_ver_tg_t *prev_vtg = NULL;
1222 1201 stmf_ver_hg_t *prev_vhg = NULL;
1223 1202 int found = 0;
1224 1203 stmf_i_lu_t *ilu;
1225 1204
1226 1205 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1227 1206 luid = stmf_lookup_id(&stmf_state.stmf_luid_list, 16, guid);
1228 1207 if (luid == NULL) {
1229 1208 *err_detail = STMF_IOCERR_INVALID_LU_ID;
1230 1209 return (ENODEV);
1231 1210 }
1232 1211 ilu = (stmf_i_lu_t *)luid->id_pt_to_object;
1233 1212
1234 1213 for (ve = (stmf_view_entry_t *)luid->id_impl_specific;
1235 1214 ve; ve = ve->ve_next) {
1236 1215 if (ve->ve_id == veid) {
1237 1216 break;
1238 1217 }
1239 1218 }
1240 1219 if (!ve) {
1241 1220 *err_detail = STMF_IOCERR_INVALID_VE_ID;
1242 1221 return (ENODEV);
1243 1222 }
1244 1223 /* remove the ve */
1245 1224 if (ve->ve_next)
1246 1225 ve->ve_next->ve_prev = ve->ve_prev;
1247 1226 if (ve->ve_prev)
1248 1227 ve->ve_prev->ve_next = ve->ve_next;
1249 1228 else {
1250 1229 luid->id_impl_specific = (void *)ve->ve_next;
1251 1230 if (!luid->id_impl_specific) {
1252 1231 /* don't have any view entries related to this lu */
1253 1232 stmf_remove_id(&stmf_state.stmf_luid_list, luid);
1254 1233 if (ilu)
1255 1234 ilu->ilu_luid = NULL;
1256 1235 stmf_free_id(luid);
1257 1236 }
1258 1237 }
1259 1238
1260 1239 /* we need to update ver_hg->verh_ve_map */
1261 1240 for (vtg = stmf_state.stmf_ver_tg_head; vtg; vtg = vtg->vert_next) {
1262 1241 if (vtg->vert_tg_ref == ve->ve_tg) {
1263 1242 found = 1;
1264 1243 break;
1265 1244 }
1266 1245 prev_vtg = vtg;
1267 1246 }
1268 1247 ASSERT(found);
1269 1248 found = 0;
1270 1249 for (vhg = vtg->vert_verh_list; vhg; vhg = vhg->verh_next) {
1271 1250 if (vhg->verh_hg_ref == ve->ve_hg) {
1272 1251 found = 1;
1273 1252 break;
1274 1253 }
1275 1254 prev_vhg = vhg;
1276 1255 }
1277 1256 ASSERT(found);
1278 1257
1279 1258 (void) stmf_remove_ent_from_map(&vhg->verh_ve_map, ve->ve_lun);
1280 1259
1281 1260 /* free verhg if it don't have any ve entries related */
1282 1261 if (!vhg->verh_ve_map.lm_nluns) {
1283 1262 /* we don't have any view entry related */
1284 1263 if (prev_vhg)
1285 1264 prev_vhg->verh_next = vhg->verh_next;
1286 1265 else
1287 1266 vtg->vert_verh_list = vhg->verh_next;
1288 1267
1289 1268 /* Free entries in case the map still has memory */
1290 1269 if (vhg->verh_ve_map.lm_nentries) {
1291 1270 kmem_free(vhg->verh_ve_map.lm_plus,
1292 1271 vhg->verh_ve_map.lm_nentries *
1293 1272 sizeof (void *));
1294 1273 }
1295 1274 kmem_free(vhg, sizeof (stmf_ver_hg_t));
1296 1275 if (!vtg->vert_verh_list) {
1297 1276 /* we don't have any ve related */
1298 1277 if (prev_vtg)
1299 1278 prev_vtg->vert_next = vtg->vert_next;
1300 1279 else
1301 1280 stmf_state.stmf_ver_tg_head = vtg->vert_next;
1302 1281 kmem_free(vtg, sizeof (stmf_ver_tg_t));
1303 1282 }
1304 1283 }
1305 1284
1306 1285 if (stmf_state.stmf_service_running && ilu &&
1307 1286 ilu->ilu_state == STMF_STATE_ONLINE) {
1308 1287 stmf_update_sessions_per_ve(ve, ilu->ilu_lu, 0);
1309 1288 }
1310 1289
1311 1290 ve->ve_hg->id_refcnt--;
1312 1291 ve->ve_tg->id_refcnt--;
1313 1292
1314 1293 kmem_free(ve, sizeof (stmf_view_entry_t));
1315 1294 return (0);
1316 1295 }
1317 1296
1318 1297 int
1319 1298 stmf_add_group(uint8_t *grpname, uint16_t grpname_size,
1320 1299 stmf_id_type_t group_type, uint32_t *err_detail)
1321 1300 {
1322 1301 stmf_status_t status;
1323 1302
1324 1303 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1325 1304
1326 1305 if (group_type == STMF_ID_TYPE_HOST_GROUP)
1327 1306 status = stmf_add_hg(grpname, grpname_size, 0, err_detail);
1328 1307 else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
1329 1308 status = stmf_add_tg(grpname, grpname_size, 0, err_detail);
1330 1309 else {
1331 1310 return (EINVAL);
1332 1311 }
1333 1312 switch (status) {
1334 1313 case STMF_SUCCESS:
1335 1314 return (0);
1336 1315 case STMF_INVALID_ARG:
1337 1316 return (EINVAL);
1338 1317 case STMF_ALREADY:
1339 1318 return (EEXIST);
1340 1319 default:
1341 1320 return (EIO);
1342 1321 }
1343 1322 }
1344 1323
1345 1324 /*
1346 1325 * Group can only be removed only when it does not have
1347 1326 * any view entry related
1348 1327 */
1349 1328 int
1350 1329 stmf_remove_group(uint8_t *grpname, uint16_t grpname_size,
1351 1330 stmf_id_type_t group_type, uint32_t *err_detail)
1352 1331 {
1353 1332 stmf_id_data_t *id;
1354 1333 stmf_id_data_t *idmemb;
1355 1334 stmf_id_list_t *grp_memblist;
1356 1335 stmf_i_scsi_session_t *iss;
1357 1336 stmf_i_local_port_t *ilport;
1358 1337
1359 1338 if (grpname[0] == '*')
1360 1339 return (EINVAL);
1361 1340
1362 1341 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1363 1342
1364 1343 if (group_type == STMF_ID_TYPE_HOST_GROUP)
1365 1344 id = stmf_lookup_id(&stmf_state.stmf_hg_list,
1366 1345 grpname_size, grpname);
1367 1346 else if (group_type == STMF_ID_TYPE_TARGET_GROUP)
1368 1347 id = stmf_lookup_id(&stmf_state.stmf_tg_list,
1369 1348 grpname_size, grpname);
1370 1349 if (!id) {
1371 1350 *err_detail = (group_type == STMF_ID_TYPE_HOST_GROUP)?
1372 1351 STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
1373 1352 return (ENODEV); /* no such grp */
1374 1353 }
1375 1354 if (id->id_refcnt) {
1376 1355 /* fail, still have viewentry related to it */
1377 1356 *err_detail = (group_type == STMF_ID_TYPE_HOST_GROUP)?
1378 1357 STMF_IOCERR_HG_IN_USE:STMF_IOCERR_TG_IN_USE;
1379 1358 return (EBUSY);
1380 1359 }
1381 1360 grp_memblist = (stmf_id_list_t *)id->id_impl_specific;
1382 1361 while ((idmemb = grp_memblist->idl_head) != NULL) {
1383 1362 stmf_remove_id(grp_memblist, idmemb);
1384 1363 stmf_free_id(idmemb);
1385 1364 }
1386 1365
1387 1366 ASSERT(!grp_memblist->id_count);
1388 1367 if (id->id_type == STMF_ID_TYPE_TARGET_GROUP) {
1389 1368 for (ilport = stmf_state.stmf_ilportlist; ilport;
1390 1369 ilport = ilport->ilport_next) {
1391 1370 if (ilport->ilport_tg == (void *)id) {
1392 1371 ilport->ilport_tg = NULL;
1393 1372 }
1394 1373 }
1395 1374 stmf_remove_id(&stmf_state.stmf_tg_list, id);
1396 1375 } else {
1397 1376 for (ilport = stmf_state.stmf_ilportlist; ilport;
1398 1377 ilport = ilport->ilport_next) {
1399 1378 for (iss = ilport->ilport_ss_list; iss;
1400 1379 iss = iss->iss_next) {
1401 1380 if (iss->iss_hg == (void *)id)
1402 1381 iss->iss_hg = NULL;
1403 1382 }
1404 1383 }
1405 1384 stmf_remove_id(&stmf_state.stmf_hg_list, id);
1406 1385 }
1407 1386 stmf_free_id(id);
1408 1387 return (0);
1409 1388
1410 1389 }
1411 1390
1412 1391 int
1413 1392 stmf_add_group_member(uint8_t *grpname, uint16_t grpname_size,
1414 1393 uint8_t *entry_ident, uint16_t entry_size,
1415 1394 stmf_id_type_t entry_type, uint32_t *err_detail)
1416 1395 {
1417 1396 stmf_id_data_t *id_grp, *id_alltgt;
1418 1397 stmf_id_data_t *id_member;
1419 1398 stmf_id_data_t *id_grp_tmp;
1420 1399 stmf_i_scsi_session_t *iss;
1421 1400 stmf_i_local_port_t *ilport;
1422 1401 stmf_lun_map_t *vemap, *vemap_alltgt;
1423 1402 uint8_t grpname_forall = '*';
1424 1403
1425 1404 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1426 1405 ASSERT(grpname[0] != '*');
1427 1406
1428 1407 if (entry_type == STMF_ID_TYPE_HOST) {
1429 1408 id_grp = stmf_lookup_id(&stmf_state.stmf_hg_list,
1430 1409 grpname_size, grpname);
1431 1410 id_grp_tmp = stmf_lookup_group_for_host(entry_ident,
1432 1411 entry_size);
1433 1412 } else {
1434 1413 id_grp = stmf_lookup_id(&stmf_state.stmf_tg_list,
1435 1414 grpname_size, grpname);
1436 1415 id_grp_tmp = stmf_lookup_group_for_target(entry_ident,
1437 1416 entry_size);
1438 1417 }
1439 1418 if (id_grp == NULL) {
1440 1419 *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
1441 1420 STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
1442 1421 return (ENODEV); /* not found */
1443 1422 }
1444 1423
1445 1424 /* Check whether this member already bound to a group */
1446 1425 if (id_grp_tmp) {
1447 1426 if (id_grp_tmp != id_grp) {
1448 1427 *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
1449 1428 STMF_IOCERR_HG_ENTRY_EXISTS:
1450 1429 STMF_IOCERR_TG_ENTRY_EXISTS;
1451 1430 return (EEXIST); /* already added into another grp */
1452 1431 }
1453 1432 else
1454 1433 return (0);
1455 1434 }
1456 1435
1457 1436 /* verify target is offline */
1458 1437 if (entry_type == STMF_ID_TYPE_TARGET) {
1459 1438 ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
1460 1439 if (ilport && ilport->ilport_state != STMF_STATE_OFFLINE) {
1461 1440 *err_detail = STMF_IOCERR_TG_NEED_TG_OFFLINE;
1462 1441 return (EBUSY);
1463 1442 }
1464 1443 }
1465 1444
1466 1445 id_member = stmf_alloc_id(entry_size, entry_type,
1467 1446 entry_ident, 0);
1468 1447 stmf_append_id((stmf_id_list_t *)id_grp->id_impl_specific, id_member);
1469 1448
1470 1449 if (entry_type == STMF_ID_TYPE_TARGET) {
1471 1450 ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
1472 1451 if (ilport)
1473 1452 ilport->ilport_tg = (void *)id_grp;
1474 1453 return (0);
1475 1454 }
1476 1455 /* For host group member, update the session if needed */
1477 1456 if (!stmf_state.stmf_service_running)
1478 1457 return (0);
1479 1458 /* Need to consider all target group + this host group */
1480 1459 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1481 1460 1, &grpname_forall);
1482 1461 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
1483 1462
1484 1463 /* check whether there are sessions may be affected */
|
↓ open down ↓ |
314 lines elided |
↑ open up ↑ |
1485 1464 for (ilport = stmf_state.stmf_ilportlist; ilport;
1486 1465 ilport = ilport->ilport_next) {
1487 1466 if (ilport->ilport_state != STMF_STATE_ONLINE)
1488 1467 continue;
1489 1468 iss = stmf_lookup_session_for_hostident(ilport,
1490 1469 entry_ident, entry_size);
1491 1470 if (iss) {
1492 1471 stmf_id_data_t *tgid;
1493 1472 iss->iss_hg = (void *)id_grp;
1494 1473 tgid = ilport->ilport_tg;
1474 + rw_enter(iss->iss_lockp, RW_WRITER);
1495 1475 if (tgid) {
1496 1476 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1497 1477 if (vemap)
1498 1478 stmf_add_lus_to_session_per_vemap(
1499 1479 ilport, iss, vemap);
1500 1480 }
1501 1481 if (vemap_alltgt)
1502 1482 stmf_add_lus_to_session_per_vemap(ilport,
1503 1483 iss, vemap_alltgt);
1484 + rw_exit(iss->iss_lockp);
1504 1485 }
1505 1486 }
1506 1487
1507 1488 return (0);
1508 1489 }
1509 1490
1510 1491 int
1511 1492 stmf_remove_group_member(uint8_t *grpname, uint16_t grpname_size,
1512 1493 uint8_t *entry_ident, uint16_t entry_size,
1513 1494 stmf_id_type_t entry_type, uint32_t *err_detail)
1514 1495 {
1515 1496 stmf_id_data_t *id_grp, *id_alltgt;
1516 1497 stmf_id_data_t *id_member;
1517 1498 stmf_lun_map_t *vemap, *vemap_alltgt;
1518 1499 uint8_t grpname_forall = '*';
1519 1500 stmf_i_local_port_t *ilport;
1520 1501 stmf_i_scsi_session_t *iss;
1521 1502
1522 1503 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1523 1504 ASSERT(grpname[0] != '*');
1524 1505
1525 1506 if (entry_type == STMF_ID_TYPE_HOST) {
1526 1507 id_grp = stmf_lookup_id(&stmf_state.stmf_hg_list,
1527 1508 grpname_size, grpname);
1528 1509 } else {
1529 1510 id_grp = stmf_lookup_id(&stmf_state.stmf_tg_list,
1530 1511 grpname_size, grpname);
1531 1512 }
1532 1513 if (id_grp == NULL) {
1533 1514 *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
1534 1515 STMF_IOCERR_INVALID_HG:STMF_IOCERR_INVALID_TG;
1535 1516 return (ENODEV); /* no such group */
1536 1517 }
1537 1518 id_member = stmf_lookup_id((stmf_id_list_t *)id_grp->id_impl_specific,
1538 1519 entry_size, entry_ident);
1539 1520 if (!id_member) {
1540 1521 *err_detail = (entry_type == STMF_ID_TYPE_HOST)?
1541 1522 STMF_IOCERR_INVALID_HG_ENTRY:STMF_IOCERR_INVALID_TG_ENTRY;
1542 1523 return (ENODEV); /* no such member */
1543 1524 }
1544 1525 /* verify target is offline */
1545 1526 if (entry_type == STMF_ID_TYPE_TARGET) {
1546 1527 ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
1547 1528 if (ilport && ilport->ilport_state != STMF_STATE_OFFLINE) {
1548 1529 *err_detail = STMF_IOCERR_TG_NEED_TG_OFFLINE;
1549 1530 return (EBUSY);
1550 1531 }
1551 1532 }
1552 1533
1553 1534 stmf_remove_id((stmf_id_list_t *)id_grp->id_impl_specific, id_member);
1554 1535 stmf_free_id(id_member);
1555 1536
1556 1537 if (entry_type == STMF_ID_TYPE_TARGET) {
1557 1538 ilport = stmf_targetident_to_ilport(entry_ident, entry_size);
1558 1539 if (ilport)
1559 1540 ilport->ilport_tg = NULL;
1560 1541 return (0);
1561 1542 }
1562 1543 /* For host group member, update the session */
1563 1544 if (!stmf_state.stmf_service_running)
1564 1545 return (0);
1565 1546
1566 1547 /* Need to consider all target group + this host group */
1567 1548 id_alltgt = stmf_lookup_id(&stmf_state.stmf_tg_list,
1568 1549 1, &grpname_forall);
1569 1550 vemap_alltgt = stmf_get_ve_map_per_ids(id_alltgt, id_grp);
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
1570 1551
1571 1552 /* check if there are session related, if so, update it */
1572 1553 for (ilport = stmf_state.stmf_ilportlist; ilport;
1573 1554 ilport = ilport->ilport_next) {
1574 1555 if (ilport->ilport_state != STMF_STATE_ONLINE)
1575 1556 continue;
1576 1557 iss = stmf_lookup_session_for_hostident(ilport,
1577 1558 entry_ident, entry_size);
1578 1559 if (iss) {
1579 1560 stmf_id_data_t *tgid;
1561 + rw_enter(iss->iss_lockp, RW_WRITER);
1580 1562 iss->iss_hg = NULL;
1581 1563 tgid = ilport->ilport_tg;
1582 1564 if (tgid) {
1583 1565 vemap = stmf_get_ve_map_per_ids(tgid, id_grp);
1584 1566 if (vemap)
1585 1567 stmf_remove_lus_from_session_per_vemap(
1586 - ilport, iss, vemap);
1568 + iss, vemap);
1587 1569 }
1588 1570 if (vemap_alltgt)
1589 - stmf_remove_lus_from_session_per_vemap(ilport,
1590 - iss, vemap_alltgt);
1571 + stmf_remove_lus_from_session_per_vemap(iss,
1572 + vemap_alltgt);
1573 + rw_exit(iss->iss_lockp);
1591 1574 }
1592 1575 }
1593 1576
1594 1577 return (0);
1595 1578 }
1596 1579
1597 1580 /* Assert stmf_lock is already held */
1598 1581 stmf_i_local_port_t *
1599 1582 stmf_targetident_to_ilport(uint8_t *target_ident, uint16_t ident_size)
1600 1583 {
1601 1584 stmf_i_local_port_t *ilport;
1602 1585 uint8_t *id;
1603 1586
1604 1587 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1605 1588
1606 1589 for (ilport = stmf_state.stmf_ilportlist; ilport;
1607 1590 ilport = ilport->ilport_next) {
1608 1591 id = (uint8_t *)ilport->ilport_lport->lport_id;
1609 1592 if ((id[3] == ident_size) &&
1610 1593 bcmp(id + 4, target_ident, ident_size) == 0) {
1611 1594 return (ilport);
1612 1595 }
1613 1596 }
1614 1597 return (NULL);
1615 1598 }
1616 1599
1617 1600 stmf_i_scsi_session_t *
1618 1601 stmf_lookup_session_for_hostident(stmf_i_local_port_t *ilport,
1619 1602 uint8_t *host_ident, uint16_t ident_size)
1620 1603 {
1621 1604 stmf_i_scsi_session_t *iss;
1622 1605 uint8_t *id;
1623 1606
1624 1607 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1625 1608
1626 1609 for (iss = ilport->ilport_ss_list; iss; iss = iss->iss_next) {
1627 1610 id = (uint8_t *)iss->iss_ss->ss_rport_id;
1628 1611 if ((id[3] == ident_size) &&
1629 1612 bcmp(id + 4, host_ident, ident_size) == 0) {
1630 1613 return (iss);
1631 1614 }
1632 1615 }
1633 1616 return (NULL);
1634 1617 }
1635 1618
1636 1619 stmf_i_lu_t *
1637 1620 stmf_luident_to_ilu(uint8_t *lu_ident)
1638 1621 {
1639 1622 stmf_i_lu_t *ilu;
1640 1623
1641 1624 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1642 1625
1643 1626 for (ilu = stmf_state.stmf_ilulist; ilu; ilu = ilu->ilu_next) {
1644 1627 if (bcmp(&ilu->ilu_lu->lu_id->ident[0], lu_ident, 16) == 0)
1645 1628 return (ilu);
1646 1629 }
1647 1630
1648 1631 return (NULL);
1649 1632 }
1650 1633
1651 1634 /*
1652 1635 * Assert stmf_lock is already held,
1653 1636 * Just get the view map for the specific target group and host group
1654 1637 * tgid and hgid can not be NULL
1655 1638 */
1656 1639 stmf_lun_map_t *
1657 1640 stmf_get_ve_map_per_ids(stmf_id_data_t *tgid, stmf_id_data_t *hgid)
1658 1641 {
1659 1642 int found = 0;
1660 1643 stmf_ver_tg_t *vertg;
1661 1644 stmf_ver_hg_t *verhg;
1662 1645
1663 1646 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1664 1647
1665 1648 for (vertg = stmf_state.stmf_ver_tg_head;
1666 1649 vertg; vertg = vertg->vert_next) {
1667 1650 if (vertg->vert_tg_ref == tgid) {
1668 1651 found = 1;
1669 1652 break;
1670 1653 }
1671 1654 }
1672 1655 if (!found)
1673 1656 return (NULL);
1674 1657
1675 1658 for (verhg = vertg->vert_verh_list; verhg; verhg = verhg->verh_next) {
1676 1659 if (verhg->verh_hg_ref == hgid) {
1677 1660 return (&verhg->verh_ve_map);
1678 1661 }
1679 1662 }
1680 1663 return (NULL);
1681 1664 }
1682 1665
1683 1666 stmf_status_t
1684 1667 stmf_validate_lun_view_entry(stmf_id_data_t *hg, stmf_id_data_t *tg,
1685 1668 uint8_t *lun, uint32_t *err_detail)
1686 1669 {
1687 1670 char *phg, *ptg;
1688 1671 stmf_lun_map_t *ve_map = NULL;
1689 1672 stmf_ver_hg_t *verhg = NULL;
1690 1673 stmf_ver_tg_t *vertg = NULL;
1691 1674 uint16_t lun_num;
1692 1675 stmf_status_t ret = STMF_SUCCESS;
1693 1676
1694 1677 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1695 1678
1696 1679 ve_map = stmf_duplicate_ve_map(0);
1697 1680 for (vertg = stmf_state.stmf_ver_tg_head; vertg != NULL;
1698 1681 vertg = vertg->vert_next) {
1699 1682 ptg = (char *)vertg->vert_tg_ref->id_data;
1700 1683 if ((ptg[0] != '*') && (tg->id_data[0] != '*') &&
1701 1684 (vertg->vert_tg_ref != tg)) {
1702 1685 continue;
1703 1686 }
1704 1687 for (verhg = vertg->vert_verh_list; verhg != NULL;
1705 1688 verhg = verhg->verh_next) {
1706 1689 phg = (char *)verhg->verh_hg_ref->id_data;
1707 1690 if ((phg[0] != '*') && (hg->id_data[0] != '*') &&
1708 1691 (verhg->verh_hg_ref != hg)) {
1709 1692 continue;
1710 1693 }
1711 1694 (void) stmf_merge_ve_map(&verhg->verh_ve_map, ve_map,
1712 1695 &ve_map, 0);
1713 1696 }
1714 1697 }
1715 1698
1716 1699 ret = STMF_SUCCESS;
1717 1700 /* Return an available lun number */
1718 1701 if (lun[2] == 0xFF) {
1719 1702 /* Pick a LUN number */
1720 1703 lun_num = stmf_get_next_free_lun(ve_map, lun);
1721 1704 if (lun_num > 0x3FFF)
1722 1705 ret = STMF_NOT_SUPPORTED;
1723 1706 } else {
1724 1707 lun_num = (uint16_t)lun[1] | (((uint16_t)(lun[0] & 0x3F)) << 8);
1725 1708 if (stmf_get_ent_from_map(ve_map, lun_num) != NULL) {
1726 1709 *err_detail = STMF_IOCERR_LU_NUMBER_IN_USE;
1727 1710 ret = STMF_LUN_TAKEN;
1728 1711 }
1729 1712 }
1730 1713 stmf_destroy_ve_map(ve_map);
1731 1714
1732 1715 return (ret);
1733 1716 }
1734 1717
1735 1718 int
1736 1719 stmf_validate_lun_ve(uint8_t *hgname, uint16_t hgname_size,
1737 1720 uint8_t *tgname, uint16_t tgname_size,
1738 1721 uint8_t *luNbr, uint32_t *err_detail)
1739 1722 {
1740 1723 stmf_id_data_t *hg;
1741 1724 stmf_id_data_t *tg;
1742 1725 stmf_status_t ret;
1743 1726
1744 1727 ASSERT(mutex_owned(&stmf_state.stmf_lock));
1745 1728
1746 1729 hg = stmf_lookup_id(&stmf_state.stmf_hg_list, hgname_size,
1747 1730 (uint8_t *)hgname);
1748 1731 if (!hg) {
1749 1732 *err_detail = STMF_IOCERR_INVALID_HG;
1750 1733 return (ENOENT); /* could not find group */
1751 1734 }
1752 1735 tg = stmf_lookup_id(&stmf_state.stmf_tg_list, tgname_size,
1753 1736 (uint8_t *)tgname);
1754 1737 if (!tg) {
1755 1738 *err_detail = STMF_IOCERR_INVALID_TG;
1756 1739 return (ENOENT); /* could not find group */
1757 1740 }
1758 1741 ret = stmf_validate_lun_view_entry(hg, tg, luNbr, err_detail);
1759 1742
1760 1743 if (ret == STMF_LUN_TAKEN) {
1761 1744 return (EEXIST);
1762 1745 } else if (ret == STMF_NOT_SUPPORTED) {
1763 1746 return (E2BIG);
1764 1747 } else if (ret != STMF_SUCCESS) {
1765 1748 return (EINVAL);
1766 1749 }
1767 1750 return (0);
1768 1751 }
|
↓ open down ↓ |
168 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX