Print this page
1845 allow disable of UNMAP via stmfadm(1M).
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libstmf/common/stmf.c
+++ new/usr/src/lib/libstmf/common/stmf.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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 */
24 24
25 25 #include <stdlib.h>
26 26 #include <stdio.h>
27 27 #include <wchar.h>
28 28 #include <strings.h>
29 29 #include <sys/types.h>
30 30 #include <sys/stat.h>
31 31 #include <fcntl.h>
32 32 #include <unistd.h>
33 33 #include <libintl.h>
34 34 #include <errno.h>
35 35 #include <string.h>
36 36 #include <assert.h>
37 37 #include <libnvpair.h>
38 38 #include <pthread.h>
39 39 #include <syslog.h>
40 40 #include <libstmf.h>
41 41 #include <netinet/in.h>
42 42 #include <inttypes.h>
43 43 #include <store.h>
44 44 #include <locale.h>
45 45 #include <math.h>
46 46 #include <libstmf_impl.h>
47 47 #include <sys/stmf_ioctl.h>
48 48 #include <sys/stmf_sbd_ioctl.h>
49 49 #include <sys/pppt_ioctl.h>
50 50 #include <macros.h>
51 51
52 52 #define STMF_PATH "/devices/pseudo/stmf@0:admin"
53 53 #define SBD_PATH "/devices/pseudo/stmf_sbd@0:admin"
54 54 #define PPPT_PATH "/devices/pseudo/pppt@0:pppt"
55 55
56 56 #define EUI "eui."
57 57 #define WWN "wwn."
58 58 #define IQN "iqn."
59 59 #define LU_ASCII_GUID_SIZE 32
60 60 #define LU_GUID_SIZE 16
61 61 #define OUI_ASCII_SIZE 6
62 62 #define HOST_ID_ASCII_SIZE 8
63 63 #define OUI_SIZE 3
64 64 #define HOST_ID_SIZE 4
65 65 #define IDENT_LENGTH_BYTE 3
66 66
67 67 /* various initial allocation values */
68 68 #define ALLOC_LU 8192
69 69 #define ALLOC_TARGET_PORT 2048
70 70 #define ALLOC_PROVIDER 64
71 71 #define ALLOC_GROUP 2048
72 72 #define ALLOC_SESSION 2048
73 73 #define ALLOC_VE 256
74 74 #define ALLOC_PP_DATA_SIZE 128*1024
75 75 #define ALLOC_GRP_MEMBER 256
76 76
77 77 #define MAX_ISCSI_NAME 223
78 78 #define MAX_SERIAL_SIZE 252 + 1
79 79 #define MAX_LU_ALIAS_SIZE 256
80 80 #define MAX_SBD_PROPS MAXPATHLEN + MAX_SERIAL_SIZE + MAX_LU_ALIAS_SIZE
81 81
82 82 #define OPEN_STMF 0
83 83 #define OPEN_EXCL_STMF O_EXCL
84 84
85 85 #define OPEN_SBD 0
86 86 #define OPEN_EXCL_SBD O_EXCL
87 87
88 88 #define OPEN_PPPT 0
89 89 #define OPEN_EXCL_PPPT O_EXCL
90 90
91 91 #define LOGICAL_UNIT_TYPE 0
92 92 #define TARGET_TYPE 1
93 93 #define STMF_SERVICE_TYPE 2
94 94
95 95 #define HOST_GROUP 1
96 96 #define TARGET_GROUP 2
97 97
98 98 /* set default persistence here */
99 99 #define STMF_DEFAULT_PERSIST STMF_PERSIST_SMF
100 100
101 101 #define MAX_PROVIDER_RETRY 30
102 102
103 103 static int openStmf(int, int *fd);
104 104 static int openSbd(int, int *fd);
105 105 static int openPppt(int, int *fd);
106 106 static int groupIoctl(int fd, int cmd, stmfGroupName *);
107 107 static int loadStore(int fd);
108 108 static int initializeConfig();
109 109 static int groupMemberIoctl(int fd, int cmd, stmfGroupName *, stmfDevid *);
110 110 static int guidCompare(const void *, const void *);
111 111 static int addViewEntryIoctl(int fd, stmfGuid *, stmfViewEntry *);
112 112 static int loadHostGroups(int fd, stmfGroupList *);
113 113 static int loadTargetGroups(int fd, stmfGroupList *);
114 114 static int getStmfState(stmf_state_desc_t *);
115 115 static int setStmfState(int fd, stmf_state_desc_t *, int);
116 116 static int setProviderData(int fd, char *, nvlist_t *, int, uint64_t *);
117 117 static int createDiskResource(luResourceImpl *);
118 118 static int createDiskLu(diskResource *, stmfGuid *);
119 119 static int deleteDiskLu(stmfGuid *luGuid);
120 120 static int getDiskProp(luResourceImpl *, uint32_t, char *, size_t *);
121 121 static int getDiskAllProps(stmfGuid *luGuid, luResource *hdl);
122 122 static int loadDiskPropsFromDriver(luResourceImpl *, sbd_lu_props_t *);
123 123 static int removeGuidFromDiskStore(stmfGuid *);
124 124 static int addGuidToDiskStore(stmfGuid *, char *);
125 125 static int persistDiskGuid(stmfGuid *, char *, boolean_t);
126 126 static int setDiskProp(luResourceImpl *, uint32_t, const char *);
127 127 static int getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen);
128 128 static int checkHexUpper(char *);
129 129 static int strToShift(const char *);
130 130 static int niceStrToNum(const char *, uint64_t *);
131 131 static void diskError(uint32_t, int *);
132 132 static int importDiskLu(char *fname, stmfGuid *);
133 133 static int modifyDiskLu(diskResource *, stmfGuid *, const char *);
134 134 static int modifyDiskLuProp(stmfGuid *, const char *, uint32_t, const char *);
135 135 static int validateModifyDiskProp(uint32_t);
136 136 static uint8_t iGetPersistMethod();
137 137 static int groupListIoctl(stmfGroupList **, int);
138 138 static int iLoadGroupFromPs(stmfGroupList **, int);
139 139 static int groupMemberListIoctl(stmfGroupName *, stmfGroupProperties **, int);
140 140 static int getProviderData(char *, nvlist_t **, int, uint64_t *);
141 141 static int setDiskStandby(stmfGuid *luGuid);
142 142 static int setDiskGlobalProp(uint32_t, const char *);
143 143 static int viewEntryCompare(const void *, const void *);
144 144 static void deleteNonActiveLus();
145 145 static int loadStmfProp(int fd);
146 146
147 147 static pthread_mutex_t persistenceTypeLock = PTHREAD_MUTEX_INITIALIZER;
148 148 static int iPersistType = 0;
149 149 /* when B_TRUE, no need to access SMF anymore. Just use iPersistType */
150 150 static boolean_t iLibSetPersist = B_FALSE;
151 151
152 152 /*
153 153 * Open for stmf module
154 154 *
155 155 * flag - open flag (OPEN_STMF, OPEN_EXCL_STMF)
156 156 * fd - pointer to integer. On success, contains the stmf file descriptor
157 157 */
158 158 static int
159 159 openStmf(int flag, int *fd)
160 160 {
161 161 int ret = STMF_STATUS_ERROR;
162 162
163 163 if ((*fd = open(STMF_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
164 164 ret = STMF_STATUS_SUCCESS;
165 165 } else {
166 166 if (errno == EBUSY) {
167 167 ret = STMF_ERROR_BUSY;
168 168 } else if (errno == EACCES) {
169 169 ret = STMF_ERROR_PERM;
170 170 } else {
171 171 ret = STMF_STATUS_ERROR;
172 172 }
173 173 syslog(LOG_DEBUG, "openStmf:open failure:%s:errno(%d)",
174 174 STMF_PATH, errno);
175 175 }
176 176
177 177 return (ret);
178 178 }
179 179
180 180 /*
181 181 * Open for sbd module
182 182 *
183 183 * flag - open flag (OPEN_SBD, OPEN_EXCL_SBD)
184 184 * fd - pointer to integer. On success, contains the stmf file descriptor
185 185 */
186 186 static int
187 187 openSbd(int flag, int *fd)
188 188 {
189 189 int ret = STMF_STATUS_ERROR;
190 190
191 191 if ((*fd = open(SBD_PATH, O_NDELAY | O_RDONLY | flag)) != -1) {
192 192 ret = STMF_STATUS_SUCCESS;
193 193 } else {
194 194 if (errno == EBUSY) {
195 195 ret = STMF_ERROR_BUSY;
196 196 } else if (errno == EACCES) {
197 197 ret = STMF_ERROR_PERM;
198 198 } else {
199 199 ret = STMF_STATUS_ERROR;
200 200 }
201 201 syslog(LOG_DEBUG, "openSbd:open failure:%s:errno(%d)",
202 202 SBD_PATH, errno);
203 203 }
204 204
205 205 return (ret);
206 206 }
207 207
208 208 /*
209 209 * Open for pppt module
210 210 *
211 211 * flag - open flag (OPEN_PPPT, OPEN_EXCL_PPPT)
212 212 * fd - pointer to integer. On success, contains the stmf file descriptor
213 213 */
214 214 static int
215 215 openPppt(int flag, int *fd)
216 216 {
217 217 int ret = STMF_STATUS_ERROR;
218 218
219 219 if ((*fd = open(PPPT_PATH, O_RDONLY | flag)) != -1) {
220 220 ret = STMF_STATUS_SUCCESS;
221 221 } else {
222 222 if (errno == EBUSY) {
223 223 ret = STMF_ERROR_BUSY;
224 224 } else if (errno == EACCES) {
225 225 ret = STMF_ERROR_PERM;
226 226 } else {
227 227 ret = STMF_STATUS_ERROR;
228 228 }
229 229 syslog(LOG_DEBUG, "openPppt:open failure:%s:errno(%d)",
230 230 PPPT_PATH, errno);
231 231 }
232 232
233 233 return (ret);
234 234 }
235 235
236 236 /*
237 237 * initializeConfig
238 238 *
239 239 * This routine should be called before any ioctl requiring initialization
240 240 * which is basically everything except stmfGetState(), setStmfState() and
241 241 * stmfLoadConfig().
242 242 */
243 243 static int
244 244 initializeConfig()
245 245 {
246 246 int ret;
247 247 stmfState state;
248 248
249 249
250 250 ret = stmfGetState(&state);
251 251 if (ret != STMF_STATUS_SUCCESS) {
252 252 return (ret);
253 253 }
254 254
255 255 /* if we've already initialized or in the process, return success */
256 256 if (state.configState == STMF_CONFIG_STATE_INIT_DONE ||
257 257 state.configState == STMF_CONFIG_STATE_INIT) {
258 258 return (STMF_STATUS_SUCCESS);
259 259 }
260 260
261 261 ret = stmfLoadConfig();
262 262 if (ret != STMF_STATUS_SUCCESS) {
263 263 syslog(LOG_DEBUG,
264 264 "initializeConfig:stmfLoadConfig:error(%d)", ret);
265 265 return (ret);
266 266 }
267 267
268 268 ret = stmfGetState(&state);
269 269 if (ret != STMF_STATUS_SUCCESS) {
270 270 syslog(LOG_DEBUG,
271 271 "initializeConfig:stmfGetState:error(%d)", ret);
272 272 return (ret);
273 273 }
274 274
275 275 if (state.configState != STMF_CONFIG_STATE_INIT_DONE) {
276 276 syslog(LOG_DEBUG, "initializeConfig:state.configState(%d)",
277 277 state.configState);
278 278 ret = STMF_STATUS_ERROR;
279 279 }
280 280
281 281 return (ret);
282 282 }
283 283
284 284
285 285 /*
286 286 * groupIoctl
287 287 *
288 288 * Purpose: issue ioctl for create/delete on group
289 289 *
290 290 * cmd - valid STMF ioctl group cmd
291 291 * groupName - groupName to create or delete
292 292 */
293 293 static int
294 294 groupIoctl(int fd, int cmd, stmfGroupName *groupName)
295 295 {
296 296 int ret = STMF_STATUS_SUCCESS;
297 297 int ioctlRet;
298 298 stmf_iocdata_t stmfIoctl;
299 299 stmf_group_name_t iGroupName;
300 300
301 301 bzero(&iGroupName, sizeof (iGroupName));
302 302
303 303 bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
304 304
305 305 iGroupName.name_size = strlen((char *)groupName);
306 306
307 307 bzero(&stmfIoctl, sizeof (stmfIoctl));
308 308 /*
309 309 * Issue ioctl to create the host group
310 310 */
311 311 stmfIoctl.stmf_version = STMF_VERSION_1;
312 312 stmfIoctl.stmf_ibuf_size = sizeof (iGroupName);
313 313 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
314 314 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
315 315 if (ioctlRet != 0) {
316 316 switch (errno) {
317 317 case EPERM:
318 318 case EACCES:
319 319 ret = STMF_ERROR_PERM;
320 320 break;
321 321 default:
322 322 switch (stmfIoctl.stmf_error) {
323 323 case STMF_IOCERR_TG_EXISTS:
324 324 case STMF_IOCERR_HG_EXISTS:
325 325 ret = STMF_ERROR_EXISTS;
326 326 break;
327 327 case STMF_IOCERR_TG_IN_USE:
328 328 case STMF_IOCERR_HG_IN_USE:
329 329 ret = STMF_ERROR_GROUP_IN_USE;
330 330 break;
331 331 case STMF_IOCERR_INVALID_HG:
332 332 case STMF_IOCERR_INVALID_TG:
333 333 ret = STMF_ERROR_NOT_FOUND;
334 334 break;
335 335 default:
336 336 syslog(LOG_DEBUG,
337 337 "groupIoctl:error(%d)",
338 338 stmfIoctl.stmf_error);
339 339 ret = STMF_STATUS_ERROR;
340 340 break;
341 341 }
342 342 break;
343 343 }
344 344 }
345 345 done:
346 346 return (ret);
347 347 }
348 348
349 349 /*
350 350 * groupMemberIoctl
351 351 *
352 352 * Purpose: issue ioctl for add/remove member on group
353 353 *
354 354 * cmd - valid STMF ioctl group member cmd
355 355 * groupName - groupName to add to or remove from
356 356 * devid - group member to add or remove
357 357 */
358 358 static int
359 359 groupMemberIoctl(int fd, int cmd, stmfGroupName *groupName, stmfDevid *devid)
360 360 {
361 361 int ret = STMF_STATUS_SUCCESS;
362 362 int ioctlRet;
363 363 stmf_iocdata_t stmfIoctl;
364 364 stmf_group_op_data_t stmfGroupData;
365 365
366 366 bzero(&stmfGroupData, sizeof (stmfGroupData));
367 367
368 368 bcopy(groupName, &stmfGroupData.group.name, strlen((char *)groupName));
369 369
370 370 stmfGroupData.group.name_size = strlen((char *)groupName);
371 371 stmfGroupData.ident[IDENT_LENGTH_BYTE] = devid->identLength;
372 372 bcopy(&(devid->ident), &stmfGroupData.ident[IDENT_LENGTH_BYTE + 1],
373 373 devid->identLength);
374 374
375 375 bzero(&stmfIoctl, sizeof (stmfIoctl));
376 376 /*
377 377 * Issue ioctl to add to the host group
378 378 */
379 379 stmfIoctl.stmf_version = STMF_VERSION_1;
380 380 stmfIoctl.stmf_ibuf_size = sizeof (stmfGroupData);
381 381 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&stmfGroupData;
382 382 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
383 383 if (ioctlRet != 0) {
384 384 switch (errno) {
385 385 case EBUSY:
386 386 switch (stmfIoctl.stmf_error) {
387 387 case STMF_IOCERR_TG_NEED_TG_OFFLINE:
388 388 ret = STMF_ERROR_TG_ONLINE;
389 389 break;
390 390 default:
391 391 ret = STMF_ERROR_BUSY;
392 392 break;
393 393 }
394 394 break;
395 395 case EPERM:
396 396 case EACCES:
397 397 ret = STMF_ERROR_PERM;
398 398 break;
399 399 default:
400 400 switch (stmfIoctl.stmf_error) {
401 401 case STMF_IOCERR_TG_ENTRY_EXISTS:
402 402 case STMF_IOCERR_HG_ENTRY_EXISTS:
403 403 ret = STMF_ERROR_EXISTS;
404 404 break;
405 405 case STMF_IOCERR_INVALID_TG_ENTRY:
406 406 case STMF_IOCERR_INVALID_HG_ENTRY:
407 407 ret =
408 408 STMF_ERROR_MEMBER_NOT_FOUND;
409 409 break;
410 410 case STMF_IOCERR_INVALID_TG:
411 411 case STMF_IOCERR_INVALID_HG:
412 412 ret =
413 413 STMF_ERROR_GROUP_NOT_FOUND;
414 414 break;
415 415 default:
416 416 syslog(LOG_DEBUG,
417 417 "groupMemberIoctl:error"
418 418 "(%d)",
419 419 stmfIoctl.stmf_error);
420 420 ret = STMF_STATUS_ERROR;
421 421 break;
422 422 }
423 423 break;
424 424 }
425 425 }
426 426 done:
427 427 return (ret);
428 428 }
429 429
430 430 /*
431 431 * qsort function
432 432 * sort on veIndex
433 433 */
434 434 static int
435 435 viewEntryCompare(const void *p1, const void *p2)
436 436 {
437 437
438 438 stmfViewEntry *v1 = (stmfViewEntry *)p1, *v2 = (stmfViewEntry *)p2;
439 439 if (v1->veIndex > v2->veIndex)
440 440 return (1);
441 441 if (v1->veIndex < v2->veIndex)
442 442 return (-1);
443 443 return (0);
444 444 }
445 445
446 446 /*
447 447 * guidCompare
448 448 *
449 449 * qsort function
450 450 * sort on guid
451 451 */
452 452 static int
453 453 guidCompare(const void *p1, const void *p2)
454 454 {
455 455
456 456 stmfGuid *g1 = (stmfGuid *)p1, *g2 = (stmfGuid *)p2;
457 457 int i;
458 458
459 459 for (i = 0; i < sizeof (stmfGuid); i++) {
460 460 if (g1->guid[i] > g2->guid[i])
461 461 return (1);
462 462 if (g1->guid[i] < g2->guid[i])
463 463 return (-1);
464 464 }
465 465
466 466 return (0);
467 467 }
468 468
469 469 /*
470 470 * stmfAddToHostGroup
471 471 *
472 472 * Purpose: Adds an initiator to an existing host group
473 473 *
474 474 * hostGroupName - name of an existing host group
475 475 * hostName - name of initiator to add
476 476 */
477 477 int
478 478 stmfAddToHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
479 479 {
480 480 int ret;
481 481 int fd;
482 482
483 483 if (hostGroupName == NULL ||
484 484 (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
485 485 == sizeof (stmfGroupName)) || hostName == NULL) {
486 486 return (STMF_ERROR_INVALID_ARG);
487 487 }
488 488
489 489 /* call init */
490 490 ret = initializeConfig();
491 491 if (ret != STMF_STATUS_SUCCESS) {
492 492 return (ret);
493 493 }
494 494
495 495 /*
496 496 * Open control node for stmf
497 497 */
498 498 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
499 499 return (ret);
500 500
501 501 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY, hostGroupName,
502 502 hostName)) != STMF_STATUS_SUCCESS) {
503 503 goto done;
504 504 }
505 505
506 506 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
507 507 goto done;
508 508 }
509 509
510 510 ret = psAddHostGroupMember((char *)hostGroupName,
511 511 (char *)hostName->ident);
512 512 switch (ret) {
513 513 case STMF_PS_SUCCESS:
514 514 ret = STMF_STATUS_SUCCESS;
515 515 break;
516 516 case STMF_PS_ERROR_EXISTS:
517 517 ret = STMF_ERROR_EXISTS;
518 518 break;
519 519 case STMF_PS_ERROR_GROUP_NOT_FOUND:
520 520 ret = STMF_ERROR_GROUP_NOT_FOUND;
521 521 break;
522 522 case STMF_PS_ERROR_BUSY:
523 523 ret = STMF_ERROR_BUSY;
524 524 break;
525 525 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
526 526 ret = STMF_ERROR_SERVICE_NOT_FOUND;
527 527 break;
528 528 case STMF_PS_ERROR_VERSION_MISMATCH:
529 529 ret = STMF_ERROR_SERVICE_DATA_VERSION;
530 530 break;
531 531 default:
532 532 syslog(LOG_DEBUG,
533 533 "stmfAddToHostGroup:psAddHostGroupMember:error(%d)",
534 534 ret);
535 535 ret = STMF_STATUS_ERROR;
536 536 break;
537 537 }
538 538
539 539 done:
540 540 (void) close(fd);
541 541 return (ret);
542 542 }
543 543
544 544 /*
545 545 * stmfAddToTargetGroup
546 546 *
547 547 * Purpose: Adds a local port to an existing target group
548 548 *
549 549 * targetGroupName - name of an existing target group
550 550 * targetName - name of target to add
551 551 */
552 552 int
553 553 stmfAddToTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
554 554 {
555 555 int ret;
556 556 int fd;
557 557
558 558 if (targetGroupName == NULL ||
559 559 (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
560 560 == sizeof (stmfGroupName)) || targetName == NULL) {
561 561 return (STMF_ERROR_INVALID_ARG);
562 562 }
563 563
564 564 /* call init */
565 565 ret = initializeConfig();
566 566 if (ret != STMF_STATUS_SUCCESS) {
567 567 return (ret);
568 568 }
569 569
570 570 /*
571 571 * Open control node for stmf
572 572 */
573 573 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
574 574 return (ret);
575 575
576 576 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
577 577 targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
578 578 goto done;
579 579 }
580 580
581 581 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
582 582 goto done;
583 583 }
584 584
585 585 ret = psAddTargetGroupMember((char *)targetGroupName,
586 586 (char *)targetName->ident);
587 587 switch (ret) {
588 588 case STMF_PS_SUCCESS:
589 589 ret = STMF_STATUS_SUCCESS;
590 590 break;
591 591 case STMF_PS_ERROR_EXISTS:
592 592 ret = STMF_ERROR_EXISTS;
593 593 break;
594 594 case STMF_PS_ERROR_GROUP_NOT_FOUND:
595 595 ret = STMF_ERROR_GROUP_NOT_FOUND;
596 596 break;
597 597 case STMF_PS_ERROR_BUSY:
598 598 ret = STMF_ERROR_BUSY;
599 599 break;
600 600 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
601 601 ret = STMF_ERROR_SERVICE_NOT_FOUND;
602 602 break;
603 603 case STMF_PS_ERROR_VERSION_MISMATCH:
604 604 ret = STMF_ERROR_SERVICE_DATA_VERSION;
605 605 break;
606 606 default:
607 607 syslog(LOG_DEBUG,
608 608 "stmfAddToTargetGroup:psAddTargetGroupMember:"
609 609 "error(%d)", ret);
610 610 ret = STMF_STATUS_ERROR;
611 611 break;
612 612 }
613 613
614 614 done:
615 615 (void) close(fd);
616 616 return (ret);
617 617 }
618 618
619 619 /*
620 620 * addViewEntryIoctl
621 621 *
622 622 * Purpose: Issues ioctl to add a view entry
623 623 *
624 624 * lu - Logical Unit identifier to which the view entry is added
625 625 * viewEntry - view entry to add
626 626 * init - When set to B_TRUE, we are in the init state, i.e. don't call open
627 627 */
628 628 static int
629 629 addViewEntryIoctl(int fd, stmfGuid *lu, stmfViewEntry *viewEntry)
630 630 {
631 631 int ret = STMF_STATUS_SUCCESS;
632 632 int ioctlRet;
633 633 stmf_iocdata_t stmfIoctl;
634 634 stmf_view_op_entry_t ioctlViewEntry;
635 635
636 636 bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
637 637 /*
638 638 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
639 639 * false on input
640 640 */
641 641 ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
642 642 ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
643 643 ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
644 644
645 645 if (viewEntry->allHosts == B_FALSE) {
646 646 bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
647 647 sizeof (stmfGroupName));
648 648 ioctlViewEntry.ve_host_group.name_size =
649 649 strlen((char *)viewEntry->hostGroup);
650 650 }
651 651 if (viewEntry->allTargets == B_FALSE) {
652 652 bcopy(viewEntry->targetGroup,
653 653 &ioctlViewEntry.ve_target_group.name,
654 654 sizeof (stmfGroupName));
655 655 ioctlViewEntry.ve_target_group.name_size =
656 656 strlen((char *)viewEntry->targetGroup);
657 657 }
658 658 if (viewEntry->luNbrValid) {
659 659 bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
660 660 sizeof (ioctlViewEntry.ve_lu_nbr));
661 661 }
662 662 bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
663 663
664 664 bzero(&stmfIoctl, sizeof (stmfIoctl));
665 665 /*
666 666 * Issue ioctl to add to the view entry
667 667 */
668 668 stmfIoctl.stmf_version = STMF_VERSION_1;
669 669 stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
670 670 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
671 671 stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
672 672 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
673 673 ioctlRet = ioctl(fd, STMF_IOCTL_ADD_VIEW_ENTRY, &stmfIoctl);
674 674 if (ioctlRet != 0) {
675 675 switch (errno) {
676 676 case EBUSY:
677 677 ret = STMF_ERROR_BUSY;
678 678 break;
679 679 case EPERM:
680 680 ret = STMF_ERROR_PERM;
681 681 break;
682 682 case EACCES:
683 683 switch (stmfIoctl.stmf_error) {
684 684 case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
685 685 ret = STMF_ERROR_CONFIG_NONE;
686 686 break;
687 687 default:
688 688 ret = STMF_ERROR_PERM;
689 689 break;
690 690 }
691 691 break;
692 692 default:
693 693 switch (stmfIoctl.stmf_error) {
694 694 case STMF_IOCERR_LU_NUMBER_IN_USE:
695 695 ret = STMF_ERROR_LUN_IN_USE;
696 696 break;
697 697 case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
698 698 ret = STMF_ERROR_VE_CONFLICT;
699 699 break;
700 700 case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
701 701 ret = STMF_ERROR_CONFIG_NONE;
702 702 break;
703 703 case STMF_IOCERR_INVALID_HG:
704 704 ret = STMF_ERROR_INVALID_HG;
705 705 break;
706 706 case STMF_IOCERR_INVALID_TG:
707 707 ret = STMF_ERROR_INVALID_TG;
708 708 break;
709 709 default:
710 710 syslog(LOG_DEBUG,
711 711 "addViewEntryIoctl"
712 712 ":error(%d)",
713 713 stmfIoctl.stmf_error);
714 714 ret = STMF_STATUS_ERROR;
715 715 break;
716 716 }
717 717 break;
718 718 }
719 719 goto done;
720 720 }
721 721
722 722 /* copy lu nbr back to caller's view entry on success */
723 723 viewEntry->veIndex = ioctlViewEntry.ve_ndx;
724 724 if (ioctlViewEntry.ve_lu_number_valid) {
725 725 bcopy(&ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
726 726 sizeof (ioctlViewEntry.ve_lu_nbr));
727 727 }
728 728 viewEntry->luNbrValid = B_TRUE;
729 729
730 730 done:
731 731 return (ret);
732 732 }
733 733
734 734 /*
735 735 * stmfAddViewEntry
736 736 *
737 737 * Purpose: Adds a view entry to a logical unit
738 738 *
739 739 * lu - guid of the logical unit to which the view entry is added
740 740 * viewEntry - view entry structure to add
741 741 */
742 742 int
743 743 stmfAddViewEntry(stmfGuid *lu, stmfViewEntry *viewEntry)
744 744 {
745 745 int ret;
746 746 int fd;
747 747 stmfViewEntry iViewEntry;
748 748
749 749 if (lu == NULL || viewEntry == NULL) {
750 750 return (STMF_ERROR_INVALID_ARG);
751 751 }
752 752
753 753 /* initialize and set internal view entry */
754 754 bzero(&iViewEntry, sizeof (iViewEntry));
755 755
756 756 if (!viewEntry->allHosts) {
757 757 bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
758 758 sizeof (iViewEntry.hostGroup));
759 759 } else {
760 760 iViewEntry.allHosts = B_TRUE;
761 761 }
762 762
763 763 if (!viewEntry->allTargets) {
764 764 bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
765 765 sizeof (iViewEntry.targetGroup));
766 766 } else {
767 767 iViewEntry.allTargets = B_TRUE;
768 768 }
769 769
770 770 if (viewEntry->luNbrValid) {
771 771 iViewEntry.luNbrValid = B_TRUE;
772 772 bcopy(viewEntry->luNbr, iViewEntry.luNbr,
773 773 sizeof (iViewEntry.luNbr));
774 774 }
775 775
776 776 /*
777 777 * set users return view entry index valid flag to false
778 778 * in case of failure
779 779 */
780 780 viewEntry->veIndexValid = B_FALSE;
781 781
782 782 /* Check to ensure service exists */
783 783 if (psCheckService() != STMF_STATUS_SUCCESS) {
784 784 return (STMF_ERROR_SERVICE_NOT_FOUND);
785 785 }
786 786
787 787 /* call init */
788 788 ret = initializeConfig();
789 789 if (ret != STMF_STATUS_SUCCESS) {
790 790 return (ret);
791 791 }
792 792
793 793 /*
794 794 * Open control node for stmf
795 795 */
796 796 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
797 797 return (ret);
798 798
799 799 /*
800 800 * First add the view entry to the driver
801 801 */
802 802 ret = addViewEntryIoctl(fd, lu, &iViewEntry);
803 803 if (ret != STMF_STATUS_SUCCESS) {
804 804 goto done;
805 805 }
806 806
807 807 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
808 808 goto done;
809 809 }
810 810
811 811 /*
812 812 * If the add to driver was successful, add it to the persistent
813 813 * store.
814 814 */
815 815 ret = psAddViewEntry(lu, &iViewEntry);
816 816 switch (ret) {
817 817 case STMF_PS_SUCCESS:
818 818 ret = STMF_STATUS_SUCCESS;
819 819 break;
820 820 case STMF_PS_ERROR_NOT_FOUND:
821 821 ret = STMF_ERROR_NOT_FOUND;
822 822 break;
823 823 case STMF_PS_ERROR_BUSY:
824 824 ret = STMF_ERROR_BUSY;
825 825 break;
826 826 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
827 827 ret = STMF_ERROR_SERVICE_NOT_FOUND;
828 828 break;
829 829 case STMF_PS_ERROR_VERSION_MISMATCH:
830 830 ret = STMF_ERROR_SERVICE_DATA_VERSION;
831 831 break;
832 832 default:
833 833 syslog(LOG_DEBUG,
834 834 "stmfAddViewEntry:psAddViewEntry:error(%d)", ret);
835 835 ret = STMF_STATUS_ERROR;
836 836 break;
837 837 }
838 838
839 839 done:
840 840 (void) close(fd);
841 841
842 842 if (ret == STMF_STATUS_SUCCESS) {
843 843 /* set caller's view entry on success */
844 844 viewEntry->veIndexValid = iViewEntry.veIndexValid;
845 845 viewEntry->veIndex = iViewEntry.veIndex;
846 846 viewEntry->luNbrValid = B_TRUE;
847 847 bcopy(iViewEntry.luNbr, viewEntry->luNbr,
848 848 sizeof (iViewEntry.luNbr));
849 849 }
850 850 return (ret);
851 851 }
852 852
853 853 /*
854 854 * stmfClearProviderData
855 855 *
856 856 * Purpose: delete all provider data for specified provider
857 857 *
858 858 * providerName - name of provider for which data should be deleted
859 859 */
860 860 int
861 861 stmfClearProviderData(char *providerName, int providerType)
862 862 {
863 863 int ret;
864 864 int fd;
865 865 int ioctlRet;
866 866 int savedErrno;
867 867 stmf_iocdata_t stmfIoctl;
868 868 stmf_ppioctl_data_t ppi;
869 869
870 870 /* call init */
871 871 ret = initializeConfig();
872 872 if (ret != STMF_STATUS_SUCCESS) {
873 873 return (ret);
874 874 }
875 875
876 876 if (providerName == NULL) {
877 877 return (STMF_ERROR_INVALID_ARG);
878 878 }
879 879
880 880 if (providerType != STMF_LU_PROVIDER_TYPE &&
881 881 providerType != STMF_PORT_PROVIDER_TYPE) {
882 882 return (STMF_ERROR_INVALID_ARG);
883 883 }
884 884
885 885 /*
886 886 * Open control node for stmf
887 887 */
888 888 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
889 889 return (ret);
890 890
891 891 bzero(&ppi, sizeof (ppi));
892 892
893 893 (void) strncpy(ppi.ppi_name, providerName, sizeof (ppi.ppi_name));
894 894
895 895 switch (providerType) {
896 896 case STMF_LU_PROVIDER_TYPE:
897 897 ppi.ppi_lu_provider = 1;
898 898 break;
899 899 case STMF_PORT_PROVIDER_TYPE:
900 900 ppi.ppi_port_provider = 1;
901 901 break;
902 902 default:
903 903 ret = STMF_ERROR_INVALID_ARG;
904 904 goto done;
905 905 }
906 906
907 907 bzero(&stmfIoctl, sizeof (stmfIoctl));
908 908
909 909 stmfIoctl.stmf_version = STMF_VERSION_1;
910 910 stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
911 911 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
912 912
913 913 ioctlRet = ioctl(fd, STMF_IOCTL_CLEAR_PP_DATA, &stmfIoctl);
914 914 if (ioctlRet != 0) {
915 915 savedErrno = errno;
916 916 switch (savedErrno) {
917 917 case EBUSY:
918 918 ret = STMF_ERROR_BUSY;
919 919 break;
920 920 case EPERM:
921 921 case EACCES:
922 922 ret = STMF_ERROR_PERM;
923 923 break;
924 924 default:
925 925 syslog(LOG_DEBUG,
926 926 "stmfClearProviderData:ioctl error(%d)",
927 927 ioctlRet);
928 928 ret = STMF_STATUS_ERROR;
929 929 break;
930 930 }
931 931 if (savedErrno != ENOENT) {
932 932 goto done;
933 933 }
934 934 }
935 935
936 936 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
937 937 goto done;
938 938 }
939 939
940 940 ret = psClearProviderData(providerName, providerType);
941 941 switch (ret) {
942 942 case STMF_PS_SUCCESS:
943 943 ret = STMF_STATUS_SUCCESS;
944 944 break;
945 945 case STMF_PS_ERROR_NOT_FOUND:
946 946 ret = STMF_ERROR_NOT_FOUND;
947 947 break;
948 948 case STMF_PS_ERROR_BUSY:
949 949 ret = STMF_ERROR_BUSY;
950 950 break;
951 951 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
952 952 ret = STMF_ERROR_SERVICE_NOT_FOUND;
953 953 break;
954 954 case STMF_PS_ERROR_VERSION_MISMATCH:
955 955 ret = STMF_ERROR_SERVICE_DATA_VERSION;
956 956 break;
957 957 default:
958 958 syslog(LOG_DEBUG,
959 959 "stmfClearProviderData:psClearProviderData"
960 960 ":error(%d)", ret);
961 961 ret = STMF_STATUS_ERROR;
962 962 break;
963 963 }
964 964
965 965 done:
966 966 (void) close(fd);
967 967 return (ret);
968 968 }
969 969
970 970 /*
971 971 * stmfCreateHostGroup
972 972 *
973 973 * Purpose: Create a new initiator group
974 974 *
975 975 * hostGroupName - name of host group to create
976 976 */
977 977 int
978 978 stmfCreateHostGroup(stmfGroupName *hostGroupName)
979 979 {
980 980 int ret;
981 981 int fd;
982 982
983 983 if (hostGroupName == NULL ||
984 984 (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
985 985 == sizeof (stmfGroupName))) {
986 986 return (STMF_ERROR_INVALID_ARG);
987 987 }
988 988
989 989 /* Check to ensure service exists */
990 990 if (psCheckService() != STMF_STATUS_SUCCESS) {
991 991 return (STMF_ERROR_SERVICE_NOT_FOUND);
992 992 }
993 993
994 994 /* call init */
995 995 ret = initializeConfig();
996 996 if (ret != STMF_STATUS_SUCCESS) {
997 997 return (ret);
998 998 }
999 999
1000 1000 /*
1001 1001 * Open control node for stmf
1002 1002 */
1003 1003 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
1004 1004 return (ret);
1005 1005
1006 1006 if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
1007 1007 hostGroupName)) != STMF_STATUS_SUCCESS) {
1008 1008 goto done;
1009 1009 }
1010 1010
1011 1011 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
1012 1012 goto done;
1013 1013 }
1014 1014
1015 1015 ret = psCreateHostGroup((char *)hostGroupName);
1016 1016 switch (ret) {
1017 1017 case STMF_PS_SUCCESS:
1018 1018 ret = STMF_STATUS_SUCCESS;
1019 1019 break;
1020 1020 case STMF_PS_ERROR_EXISTS:
1021 1021 ret = STMF_ERROR_EXISTS;
1022 1022 break;
1023 1023 case STMF_PS_ERROR_BUSY:
1024 1024 ret = STMF_ERROR_BUSY;
1025 1025 break;
1026 1026 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
1027 1027 ret = STMF_ERROR_SERVICE_NOT_FOUND;
1028 1028 break;
1029 1029 case STMF_PS_ERROR_VERSION_MISMATCH:
1030 1030 ret = STMF_ERROR_SERVICE_DATA_VERSION;
1031 1031 break;
1032 1032 default:
1033 1033 syslog(LOG_DEBUG,
1034 1034 "stmfCreateHostGroup:psCreateHostGroup:error(%d)",
1035 1035 ret);
1036 1036 ret = STMF_STATUS_ERROR;
1037 1037 break;
1038 1038 }
1039 1039
1040 1040 done:
1041 1041 (void) close(fd);
1042 1042 return (ret);
1043 1043 }
1044 1044
1045 1045 /*
1046 1046 * stmfCreateLu
1047 1047 *
1048 1048 * Purpose: Create a logical unit
1049 1049 *
1050 1050 * hdl - handle to logical unit resource created via stmfCreateLuResource
1051 1051 *
1052 1052 * luGuid - If non-NULL, on success, contains the guid of the created logical
1053 1053 * unit
1054 1054 */
1055 1055 int
1056 1056 stmfCreateLu(luResource hdl, stmfGuid *luGuid)
1057 1057 {
1058 1058 int ret = STMF_STATUS_SUCCESS;
1059 1059 luResourceImpl *luPropsHdl = hdl;
1060 1060
1061 1061 if (hdl == NULL) {
1062 1062 return (STMF_ERROR_INVALID_ARG);
1063 1063 }
1064 1064
1065 1065 if (luPropsHdl->type == STMF_DISK) {
1066 1066 ret = createDiskLu((diskResource *)luPropsHdl->resource,
1067 1067 luGuid);
1068 1068 } else {
1069 1069 return (STMF_ERROR_INVALID_ARG);
1070 1070 }
1071 1071
1072 1072 return (ret);
1073 1073 }
1074 1074
1075 1075 /*
1076 1076 * stmfCreateLuResource
1077 1077 *
1078 1078 * Purpose: Create resource handle for a logical unit
1079 1079 *
1080 1080 * dType - Type of logical unit resource to create
1081 1081 * Can be: STMF_DISK
1082 1082 *
1083 1083 * hdl - pointer to luResource
1084 1084 */
1085 1085 int
1086 1086 stmfCreateLuResource(uint16_t dType, luResource *hdl)
1087 1087 {
1088 1088 int ret = STMF_STATUS_SUCCESS;
1089 1089
1090 1090 if (dType != STMF_DISK || hdl == NULL) {
1091 1091 return (STMF_ERROR_INVALID_ARG);
1092 1092 }
1093 1093
1094 1094 *hdl = calloc(1, sizeof (luResourceImpl));
1095 1095 if (*hdl == NULL) {
1096 1096 return (STMF_ERROR_NOMEM);
1097 1097 }
1098 1098
1099 1099 ret = createDiskResource((luResourceImpl *)*hdl);
1100 1100 if (ret != STMF_STATUS_SUCCESS) {
1101 1101 free(*hdl);
1102 1102 return (ret);
1103 1103 }
1104 1104
1105 1105 return (STMF_STATUS_SUCCESS);
1106 1106 }
1107 1107
1108 1108 /*
1109 1109 * Creates a disk logical unit
1110 1110 *
1111 1111 * disk - pointer to diskResource structure that represents the properties
1112 1112 * for the disk logical unit to be created.
1113 1113 */
1114 1114 static int
1115 1115 createDiskLu(diskResource *disk, stmfGuid *createdGuid)
1116 1116 {
1117 1117 int ret = STMF_STATUS_SUCCESS;
1118 1118 int dataFileNameLen = 0;
1119 1119 int metaFileNameLen = 0;
1120 1120 int serialNumLen = 0;
1121 1121 int luAliasLen = 0;
1122 1122 int luMgmtUrlLen = 0;
1123 1123 int sluBufSize = 0;
1124 1124 int bufOffset = 0;
1125 1125 int fd = 0;
1126 1126 int ioctlRet;
1127 1127 int savedErrno;
1128 1128 stmfGuid guid;
1129 1129 stmf_iocdata_t sbdIoctl = {0};
1130 1130
1131 1131 sbd_create_and_reg_lu_t *sbdLu = NULL;
1132 1132
1133 1133 /*
1134 1134 * Open control node for sbd
1135 1135 */
1136 1136 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1137 1137 return (ret);
1138 1138
1139 1139 /* data file name must be specified */
1140 1140 if (disk->luDataFileNameValid) {
1141 1141 dataFileNameLen = strlen(disk->luDataFileName);
1142 1142 } else {
1143 1143 (void) close(fd);
1144 1144 return (STMF_ERROR_MISSING_PROP_VAL);
1145 1145 }
1146 1146
1147 1147 sluBufSize += dataFileNameLen + 1;
1148 1148
1149 1149 if (disk->luMetaFileNameValid) {
1150 1150 metaFileNameLen = strlen(disk->luMetaFileName);
1151 1151 sluBufSize += metaFileNameLen + 1;
1152 1152 }
1153 1153
1154 1154 serialNumLen = strlen(disk->serialNum);
1155 1155 sluBufSize += serialNumLen;
1156 1156
1157 1157 if (disk->luAliasValid) {
1158 1158 luAliasLen = strlen(disk->luAlias);
1159 1159 sluBufSize += luAliasLen + 1;
1160 1160 }
1161 1161
1162 1162 if (disk->luMgmtUrlValid) {
1163 1163 luMgmtUrlLen = strlen(disk->luMgmtUrl);
1164 1164 sluBufSize += luMgmtUrlLen + 1;
1165 1165 }
1166 1166
1167 1167 /*
1168 1168 * 8 is the size of the buffer set aside for
1169 1169 * concatenation of variable length fields
1170 1170 */
1171 1171 sbdLu = (sbd_create_and_reg_lu_t *)calloc(1,
1172 1172 sizeof (sbd_create_and_reg_lu_t) + sluBufSize - 8);
1173 1173 if (sbdLu == NULL) {
1174 1174 return (STMF_ERROR_NOMEM);
1175 1175 }
1176 1176
1177 1177 sbdLu->slu_struct_size = sizeof (sbd_create_and_reg_lu_t) +
1178 1178 sluBufSize - 8;
1179 1179
1180 1180 if (metaFileNameLen) {
1181 1181 sbdLu->slu_meta_fname_valid = 1;
1182 1182 sbdLu->slu_meta_fname_off = bufOffset;
1183 1183 bcopy(disk->luMetaFileName, &(sbdLu->slu_buf[bufOffset]),
1184 1184 metaFileNameLen + 1);
1185 1185 bufOffset += metaFileNameLen + 1;
1186 1186 }
1187 1187
1188 1188 bcopy(disk->luDataFileName, &(sbdLu->slu_buf[bufOffset]),
1189 1189 dataFileNameLen + 1);
1190 1190 sbdLu->slu_data_fname_off = bufOffset;
1191 1191 bufOffset += dataFileNameLen + 1;
1192 1192
1193 1193 /* currently, serial # is not passed null terminated to the driver */
1194 1194 if (disk->serialNumValid) {
1195 1195 sbdLu->slu_serial_valid = 1;
1196 1196 sbdLu->slu_serial_off = bufOffset;
1197 1197 sbdLu->slu_serial_size = serialNumLen;
1198 1198 bcopy(disk->serialNum, &(sbdLu->slu_buf[bufOffset]),
1199 1199 serialNumLen);
1200 1200 bufOffset += serialNumLen;
1201 1201 }
1202 1202
1203 1203 if (disk->luAliasValid) {
1204 1204 sbdLu->slu_alias_valid = 1;
1205 1205 sbdLu->slu_alias_off = bufOffset;
1206 1206 bcopy(disk->luAlias, &(sbdLu->slu_buf[bufOffset]),
1207 1207 luAliasLen + 1);
1208 1208 bufOffset += luAliasLen + 1;
1209 1209 }
1210 1210
1211 1211 if (disk->luMgmtUrlValid) {
1212 1212 sbdLu->slu_mgmt_url_valid = 1;
1213 1213 sbdLu->slu_mgmt_url_off = bufOffset;
1214 1214 bcopy(disk->luMgmtUrl, &(sbdLu->slu_buf[bufOffset]),
1215 1215 luMgmtUrlLen + 1);
1216 1216 bufOffset += luMgmtUrlLen + 1;
1217 1217 }
1218 1218
1219 1219 if (disk->luSizeValid) {
1220 1220 sbdLu->slu_lu_size_valid = 1;
1221 1221 sbdLu->slu_lu_size = disk->luSize;
1222 1222 }
1223 1223
1224 1224 if (disk->luGuidValid) {
1225 1225 sbdLu->slu_guid_valid = 1;
1226 1226 bcopy(disk->luGuid, sbdLu->slu_guid, sizeof (disk->luGuid));
1227 1227 }
1228 1228
1229 1229 if (disk->vidValid) {
1230 1230 sbdLu->slu_vid_valid = 1;
1231 1231 bcopy(disk->vid, sbdLu->slu_vid, sizeof (disk->vid));
1232 1232 }
1233 1233
1234 1234 if (disk->pidValid) {
1235 1235 sbdLu->slu_pid_valid = 1;
1236 1236 bcopy(disk->pid, sbdLu->slu_pid, sizeof (disk->pid));
1237 1237 }
1238 1238
1239 1239 if (disk->revValid) {
1240 1240 sbdLu->slu_rev_valid = 1;
1241 1241 bcopy(disk->rev, sbdLu->slu_rev, sizeof (disk->rev));
1242 1242 }
1243 1243
1244 1244 if (disk->companyIdValid) {
1245 1245 sbdLu->slu_company_id_valid = 1;
1246 1246 sbdLu->slu_company_id = disk->companyId;
1247 1247 }
1248 1248
1249 1249 if (disk->hostIdValid) {
1250 1250 sbdLu->slu_host_id_valid = 1;
1251 1251 sbdLu->slu_host_id = disk->hostId;
1252 1252 }
1253 1253
1254 1254 if (disk->blkSizeValid) {
|
↓ open down ↓ |
1254 lines elided |
↑ open up ↑ |
1255 1255 sbdLu->slu_blksize_valid = 1;
1256 1256 sbdLu->slu_blksize = disk->blkSize;
1257 1257 }
1258 1258
1259 1259 if (disk->writeProtectEnableValid) {
1260 1260 if (disk->writeProtectEnable) {
1261 1261 sbdLu->slu_write_protected = 1;
1262 1262 }
1263 1263 }
1264 1264
1265 + if (disk->unmapValid) {
1266 + sbdLu->slu_unmap_valid = 1;
1267 + if (disk->unmap) {
1268 + sbdLu->slu_unmap = 1;
1269 + }
1270 + }
1271 +
1265 1272 if (disk->writebackCacheDisableValid) {
1266 1273 sbdLu->slu_writeback_cache_disable_valid = 1;
1267 1274 if (disk->writebackCacheDisable) {
1268 1275 sbdLu->slu_writeback_cache_disable = 1;
1269 1276 }
1270 1277 }
1271 1278
1272 1279 sbdIoctl.stmf_version = STMF_VERSION_1;
1273 1280 sbdIoctl.stmf_ibuf_size = sbdLu->slu_struct_size;
1274 1281 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1275 1282 sbdIoctl.stmf_obuf_size = sbdLu->slu_struct_size;
1276 1283 sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1277 1284
1278 1285 ioctlRet = ioctl(fd, SBD_IOCTL_CREATE_AND_REGISTER_LU, &sbdIoctl);
1279 1286 if (ioctlRet != 0) {
1280 1287 savedErrno = errno;
1281 1288 switch (savedErrno) {
1282 1289 case EBUSY:
1283 1290 ret = STMF_ERROR_BUSY;
1284 1291 break;
1285 1292 case EPERM:
1286 1293 case EACCES:
1287 1294 ret = STMF_ERROR_PERM;
1288 1295 break;
1289 1296 default:
1290 1297 diskError(sbdIoctl.stmf_error, &ret);
1291 1298 if (ret == STMF_STATUS_ERROR) {
1292 1299 syslog(LOG_DEBUG,
1293 1300 "createDiskLu:ioctl "
1294 1301 "error(%d) (%d) (%d)", ioctlRet,
1295 1302 sbdIoctl.stmf_error, savedErrno);
1296 1303 }
1297 1304 break;
1298 1305 }
1299 1306 }
1300 1307
1301 1308 if (ret != STMF_STATUS_SUCCESS) {
1302 1309 goto done;
1303 1310 }
1304 1311
1305 1312 /*
1306 1313 * on success, copy the resulting guid into the caller's guid if not
1307 1314 * NULL
1308 1315 */
1309 1316 if (createdGuid) {
1310 1317 bcopy(sbdLu->slu_guid, createdGuid->guid,
1311 1318 sizeof (sbdLu->slu_guid));
1312 1319 }
1313 1320
1314 1321 bcopy(sbdLu->slu_guid, guid.guid, sizeof (sbdLu->slu_guid));
1315 1322 if (disk->luMetaFileNameValid) {
1316 1323 ret = addGuidToDiskStore(&guid, disk->luMetaFileName);
1317 1324 } else {
1318 1325 ret = addGuidToDiskStore(&guid, disk->luDataFileName);
1319 1326 }
1320 1327 done:
1321 1328 free(sbdLu);
1322 1329 (void) close(fd);
1323 1330 return (ret);
1324 1331 }
1325 1332
1326 1333
1327 1334 /*
1328 1335 * stmfImportLu
1329 1336 *
1330 1337 * Purpose: Import a previously created logical unit
1331 1338 *
1332 1339 * dType - Type of logical unit
1333 1340 * Can be: STMF_DISK
1334 1341 *
1335 1342 * luGuid - If non-NULL, on success, contains the guid of the imported logical
1336 1343 * unit
1337 1344 *
1338 1345 * fname - A file name where the metadata resides
1339 1346 *
1340 1347 */
1341 1348 int
1342 1349 stmfImportLu(uint16_t dType, char *fname, stmfGuid *luGuid)
1343 1350 {
1344 1351 int ret = STMF_STATUS_SUCCESS;
1345 1352
1346 1353 if (dType == STMF_DISK) {
1347 1354 ret = importDiskLu(fname, luGuid);
1348 1355 } else {
1349 1356 return (STMF_ERROR_INVALID_ARG);
1350 1357 }
1351 1358
1352 1359 return (ret);
1353 1360 }
1354 1361
1355 1362 /*
1356 1363 * importDiskLu
1357 1364 *
1358 1365 * filename - filename to import
1359 1366 * createdGuid - if not NULL, on success contains the imported guid
1360 1367 *
1361 1368 */
1362 1369 static int
1363 1370 importDiskLu(char *fname, stmfGuid *createdGuid)
1364 1371 {
1365 1372 int ret = STMF_STATUS_SUCCESS;
1366 1373 int fd = 0;
1367 1374 int ioctlRet;
1368 1375 int savedErrno;
1369 1376 int metaFileNameLen;
1370 1377 stmfGuid iGuid;
1371 1378 int iluBufSize = 0;
1372 1379 sbd_import_lu_t *sbdLu = NULL;
1373 1380 stmf_iocdata_t sbdIoctl = {0};
1374 1381
1375 1382 if (fname == NULL) {
1376 1383 return (STMF_ERROR_INVALID_ARG);
1377 1384 }
1378 1385
1379 1386 /*
1380 1387 * Open control node for sbd
1381 1388 */
1382 1389 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1383 1390 return (ret);
1384 1391
1385 1392 metaFileNameLen = strlen(fname);
1386 1393 iluBufSize += metaFileNameLen + 1;
1387 1394
1388 1395 /*
1389 1396 * 8 is the size of the buffer set aside for
1390 1397 * concatenation of variable length fields
1391 1398 */
1392 1399 sbdLu = (sbd_import_lu_t *)calloc(1,
1393 1400 sizeof (sbd_import_lu_t) + iluBufSize - 8);
1394 1401 if (sbdLu == NULL) {
1395 1402 (void) close(fd);
1396 1403 return (STMF_ERROR_NOMEM);
1397 1404 }
1398 1405
1399 1406 /*
1400 1407 * Accept either a data file or meta data file.
1401 1408 * sbd will do the right thing here either way.
1402 1409 * i.e. if it's a data file, it assumes that the
1403 1410 * meta data is shared with the data.
1404 1411 */
1405 1412 (void) strncpy(sbdLu->ilu_meta_fname, fname, metaFileNameLen);
1406 1413
1407 1414 sbdLu->ilu_struct_size = sizeof (sbd_import_lu_t) + iluBufSize - 8;
1408 1415
1409 1416 sbdIoctl.stmf_version = STMF_VERSION_1;
1410 1417 sbdIoctl.stmf_ibuf_size = sbdLu->ilu_struct_size;
1411 1418 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1412 1419 sbdIoctl.stmf_obuf_size = sbdLu->ilu_struct_size;
1413 1420 sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdLu;
1414 1421
1415 1422 ioctlRet = ioctl(fd, SBD_IOCTL_IMPORT_LU, &sbdIoctl);
1416 1423 if (ioctlRet != 0) {
1417 1424
1418 1425 if (createdGuid && sbdIoctl.stmf_error ==
1419 1426 SBD_RET_FILE_ALREADY_REGISTERED) {
1420 1427 bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
1421 1428 sizeof (sbdLu->ilu_ret_guid));
1422 1429 }
1423 1430
1424 1431 savedErrno = errno;
1425 1432 switch (savedErrno) {
1426 1433 case EBUSY:
1427 1434 ret = STMF_ERROR_BUSY;
1428 1435 break;
1429 1436 case EPERM:
1430 1437 case EACCES:
1431 1438 ret = STMF_ERROR_PERM;
1432 1439 break;
1433 1440 default:
1434 1441 diskError(sbdIoctl.stmf_error, &ret);
1435 1442 if (ret == STMF_STATUS_ERROR) {
1436 1443 syslog(LOG_DEBUG,
1437 1444 "importDiskLu:ioctl "
1438 1445 "error(%d) (%d) (%d)", ioctlRet,
1439 1446 sbdIoctl.stmf_error, savedErrno);
1440 1447 }
1441 1448 break;
1442 1449 }
1443 1450 }
1444 1451
1445 1452
1446 1453 if (ret != STMF_STATUS_SUCCESS) {
1447 1454 goto done;
1448 1455 }
1449 1456
1450 1457 /*
1451 1458 * on success, copy the resulting guid into the caller's guid if not
1452 1459 * NULL and add it to the persistent store for sbd
1453 1460 */
1454 1461 if (createdGuid) {
1455 1462 bcopy(sbdLu->ilu_ret_guid, createdGuid->guid,
1456 1463 sizeof (sbdLu->ilu_ret_guid));
1457 1464 ret = addGuidToDiskStore(createdGuid, fname);
1458 1465 } else {
1459 1466 bcopy(sbdLu->ilu_ret_guid, iGuid.guid,
1460 1467 sizeof (sbdLu->ilu_ret_guid));
1461 1468 ret = addGuidToDiskStore(&iGuid, fname);
1462 1469 }
1463 1470 done:
1464 1471 free(sbdLu);
1465 1472 (void) close(fd);
1466 1473 return (ret);
1467 1474 }
1468 1475
1469 1476 /*
1470 1477 * diskError
1471 1478 *
1472 1479 * Purpose: Translate sbd driver error
1473 1480 */
1474 1481 static void
1475 1482 diskError(uint32_t stmfError, int *ret)
1476 1483 {
1477 1484 switch (stmfError) {
1478 1485 case SBD_RET_META_CREATION_FAILED:
1479 1486 case SBD_RET_ZFS_META_CREATE_FAILED:
1480 1487 *ret = STMF_ERROR_META_CREATION;
1481 1488 break;
1482 1489 case SBD_RET_INVALID_BLKSIZE:
1483 1490 *ret = STMF_ERROR_INVALID_BLKSIZE;
1484 1491 break;
1485 1492 case SBD_RET_FILE_ALREADY_REGISTERED:
1486 1493 *ret = STMF_ERROR_FILE_IN_USE;
1487 1494 break;
1488 1495 case SBD_RET_GUID_ALREADY_REGISTERED:
1489 1496 *ret = STMF_ERROR_GUID_IN_USE;
1490 1497 break;
1491 1498 case SBD_RET_META_PATH_NOT_ABSOLUTE:
1492 1499 case SBD_RET_META_FILE_LOOKUP_FAILED:
1493 1500 case SBD_RET_META_FILE_OPEN_FAILED:
1494 1501 case SBD_RET_META_FILE_GETATTR_FAILED:
1495 1502 case SBD_RET_NO_META:
1496 1503 *ret = STMF_ERROR_META_FILE_NAME;
1497 1504 break;
1498 1505 case SBD_RET_DATA_PATH_NOT_ABSOLUTE:
1499 1506 case SBD_RET_DATA_FILE_LOOKUP_FAILED:
1500 1507 case SBD_RET_DATA_FILE_OPEN_FAILED:
1501 1508 case SBD_RET_DATA_FILE_GETATTR_FAILED:
1502 1509 *ret = STMF_ERROR_DATA_FILE_NAME;
1503 1510 break;
1504 1511 case SBD_RET_FILE_SIZE_ERROR:
1505 1512 *ret = STMF_ERROR_FILE_SIZE_INVALID;
|
↓ open down ↓ |
231 lines elided |
↑ open up ↑ |
1506 1513 break;
1507 1514 case SBD_RET_SIZE_OUT_OF_RANGE:
1508 1515 *ret = STMF_ERROR_SIZE_OUT_OF_RANGE;
1509 1516 break;
1510 1517 case SBD_RET_LU_BUSY:
1511 1518 *ret = STMF_ERROR_LU_BUSY;
1512 1519 break;
1513 1520 case SBD_RET_WRITE_CACHE_SET_FAILED:
1514 1521 *ret = STMF_ERROR_WRITE_CACHE_SET;
1515 1522 break;
1523 + case SBD_RET_UNMAP_SET_FAILED:
1524 + *ret = STMF_ERROR_UNMAP_SET;
1525 + break;
1516 1526 case SBD_RET_ACCESS_STATE_FAILED:
1517 1527 *ret = STMF_ERROR_ACCESS_STATE_SET;
1518 1528 break;
1519 1529 default:
1520 1530 *ret = STMF_STATUS_ERROR;
1521 1531 break;
1522 1532 }
1523 1533 }
1524 1534
1525 1535 /*
1526 1536 * Creates a logical unit resource of type STMF_DISK.
1527 1537 *
1528 1538 * No defaults should be set here as all defaults are derived from the
1529 1539 * driver's default settings.
1530 1540 */
1531 1541 static int
1532 1542 createDiskResource(luResourceImpl *hdl)
1533 1543 {
1534 1544 hdl->type = STMF_DISK;
1535 1545
1536 1546 hdl->resource = calloc(1, sizeof (diskResource));
1537 1547 if (hdl->resource == NULL) {
1538 1548 return (STMF_ERROR_NOMEM);
1539 1549 }
1540 1550
1541 1551 return (STMF_STATUS_SUCCESS);
1542 1552 }
1543 1553
1544 1554 /*
1545 1555 * stmfDeleteLu
1546 1556 *
1547 1557 * Purpose: Delete a logical unit
1548 1558 *
1549 1559 * hdl - handle to logical unit resource created via stmfCreateLuResource
1550 1560 *
1551 1561 * luGuid - If non-NULL, on success, contains the guid of the created logical
1552 1562 * unit
1553 1563 */
1554 1564 int
1555 1565 stmfDeleteLu(stmfGuid *luGuid)
1556 1566 {
1557 1567 int ret = STMF_STATUS_SUCCESS;
1558 1568 stmfLogicalUnitProperties luProps;
1559 1569
1560 1570 if (luGuid == NULL) {
1561 1571 return (STMF_ERROR_INVALID_ARG);
1562 1572 }
1563 1573
1564 1574 /* Check logical unit provider name to call correct dtype function */
1565 1575 if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1566 1576 != STMF_STATUS_SUCCESS) {
1567 1577 return (ret);
1568 1578 } else {
1569 1579 if (strcmp(luProps.providerName, "sbd") == 0) {
1570 1580 ret = deleteDiskLu(luGuid);
1571 1581 } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1572 1582 return (STMF_ERROR_NOT_FOUND);
1573 1583 } else {
1574 1584 return (STMF_ERROR_INVALID_ARG);
1575 1585 }
1576 1586 }
1577 1587
1578 1588 return (ret);
1579 1589 }
1580 1590
1581 1591 static int
1582 1592 deleteDiskLu(stmfGuid *luGuid)
1583 1593 {
1584 1594 int ret = STMF_STATUS_SUCCESS;
1585 1595 int fd;
1586 1596 int savedErrno;
1587 1597 int ioctlRet;
1588 1598 sbd_delete_lu_t deleteLu = {0};
1589 1599
1590 1600 stmf_iocdata_t sbdIoctl = {0};
1591 1601
1592 1602 /*
1593 1603 * Open control node for sbd
1594 1604 */
1595 1605 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1596 1606 return (ret);
1597 1607
1598 1608 ret = removeGuidFromDiskStore(luGuid);
1599 1609 if (ret != STMF_STATUS_SUCCESS) {
1600 1610 goto done;
1601 1611 }
1602 1612
1603 1613 bcopy(luGuid, deleteLu.dlu_guid, sizeof (deleteLu.dlu_guid));
1604 1614 deleteLu.dlu_by_guid = 1;
1605 1615
1606 1616 sbdIoctl.stmf_version = STMF_VERSION_1;
1607 1617 sbdIoctl.stmf_ibuf_size = sizeof (deleteLu);
1608 1618 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&deleteLu;
1609 1619 ioctlRet = ioctl(fd, SBD_IOCTL_DELETE_LU, &sbdIoctl);
1610 1620 if (ioctlRet != 0) {
1611 1621 savedErrno = errno;
1612 1622 switch (savedErrno) {
1613 1623 case EBUSY:
1614 1624 ret = STMF_ERROR_BUSY;
1615 1625 break;
1616 1626 case EPERM:
1617 1627 case EACCES:
1618 1628 ret = STMF_ERROR_PERM;
1619 1629 break;
1620 1630 case ENOENT:
1621 1631 ret = STMF_ERROR_NOT_FOUND;
1622 1632 break;
1623 1633 default:
1624 1634 syslog(LOG_DEBUG,
1625 1635 "deleteDiskLu:ioctl error(%d) (%d) (%d)",
1626 1636 ioctlRet, sbdIoctl.stmf_error, savedErrno);
1627 1637 ret = STMF_STATUS_ERROR;
1628 1638 break;
1629 1639 }
1630 1640 }
1631 1641
1632 1642 done:
1633 1643 (void) close(fd);
1634 1644 return (ret);
1635 1645 }
1636 1646
1637 1647 /*
1638 1648 * stmfLuStandby
1639 1649 *
1640 1650 * Purpose: Sets access state to standby
1641 1651 *
1642 1652 * luGuid - guid of registered logical unit
1643 1653 *
1644 1654 */
1645 1655 int
1646 1656 stmfLuStandby(stmfGuid *luGuid)
1647 1657 {
1648 1658 int ret = STMF_STATUS_SUCCESS;
1649 1659 stmfLogicalUnitProperties luProps;
1650 1660
1651 1661 if (luGuid == NULL) {
1652 1662 return (STMF_ERROR_INVALID_ARG);
1653 1663 }
1654 1664
1655 1665 /* Check logical unit provider name to call correct dtype function */
1656 1666 if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1657 1667 != STMF_STATUS_SUCCESS) {
1658 1668 return (ret);
1659 1669 } else {
1660 1670 if (strcmp(luProps.providerName, "sbd") == 0) {
1661 1671 ret = setDiskStandby(luGuid);
1662 1672 } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1663 1673 return (STMF_ERROR_NOT_FOUND);
1664 1674 } else {
1665 1675 return (STMF_ERROR_INVALID_ARG);
1666 1676 }
1667 1677 }
1668 1678
1669 1679 return (ret);
1670 1680 }
1671 1681
1672 1682 static int
1673 1683 setDiskStandby(stmfGuid *luGuid)
1674 1684 {
1675 1685 int ret = STMF_STATUS_SUCCESS;
1676 1686 stmf_iocdata_t sbdIoctl = {0};
1677 1687 sbd_set_lu_standby_t sbdLu = {0};
1678 1688 int ioctlRet;
1679 1689 int savedErrno;
1680 1690 int fd = 0;
1681 1691
1682 1692 /*
1683 1693 * Open control node for sbd
1684 1694 */
1685 1695 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1686 1696 return (ret);
1687 1697
1688 1698 bcopy(luGuid, &sbdLu.stlu_guid, sizeof (stmfGuid));
1689 1699
1690 1700 sbdIoctl.stmf_version = STMF_VERSION_1;
1691 1701 sbdIoctl.stmf_ibuf_size = sizeof (sbd_set_lu_standby_t);
1692 1702 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)&sbdLu;
1693 1703
1694 1704 ioctlRet = ioctl(fd, SBD_IOCTL_SET_LU_STANDBY, &sbdIoctl);
1695 1705 if (ioctlRet != 0) {
1696 1706 savedErrno = errno;
1697 1707 switch (savedErrno) {
1698 1708 case EBUSY:
1699 1709 ret = STMF_ERROR_BUSY;
1700 1710 break;
1701 1711 case EPERM:
1702 1712 case EACCES:
1703 1713 ret = STMF_ERROR_PERM;
1704 1714 break;
1705 1715 default:
1706 1716 diskError(sbdIoctl.stmf_error, &ret);
1707 1717 if (ret == STMF_STATUS_ERROR) {
1708 1718 syslog(LOG_DEBUG,
1709 1719 "setDiskStandby:ioctl "
1710 1720 "error(%d) (%d) (%d)", ioctlRet,
1711 1721 sbdIoctl.stmf_error, savedErrno);
1712 1722 }
1713 1723 break;
1714 1724 }
1715 1725 }
1716 1726 (void) close(fd);
1717 1727 return (ret);
1718 1728 }
1719 1729
1720 1730 /*
1721 1731 * stmfModifyLu
1722 1732 *
1723 1733 * Purpose: Modify properties of a logical unit
1724 1734 *
1725 1735 * luGuid - guid of registered logical unit
1726 1736 * prop - property to modify
1727 1737 * propVal - property value to set
1728 1738 *
1729 1739 */
1730 1740 int
1731 1741 stmfModifyLu(stmfGuid *luGuid, uint32_t prop, const char *propVal)
1732 1742 {
1733 1743 int ret = STMF_STATUS_SUCCESS;
1734 1744 stmfLogicalUnitProperties luProps;
1735 1745
1736 1746 if (luGuid == NULL) {
1737 1747 return (STMF_ERROR_INVALID_ARG);
1738 1748 }
1739 1749
1740 1750 /* Check logical unit provider name to call correct dtype function */
1741 1751 if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
1742 1752 != STMF_STATUS_SUCCESS) {
1743 1753 return (ret);
1744 1754 } else {
1745 1755 if (strcmp(luProps.providerName, "sbd") == 0) {
1746 1756 ret = modifyDiskLuProp(luGuid, NULL, prop, propVal);
1747 1757 } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
1748 1758 return (STMF_ERROR_NOT_FOUND);
1749 1759 } else {
1750 1760 return (STMF_ERROR_INVALID_ARG);
1751 1761 }
1752 1762 }
1753 1763
1754 1764 return (ret);
1755 1765 }
1756 1766
1757 1767 /*
1758 1768 * stmfModifyLuByFname
1759 1769 *
1760 1770 * Purpose: Modify a device by filename. Device does not need to be registered.
1761 1771 *
1762 1772 * dType - type of device to modify
1763 1773 * STMF_DISK
1764 1774 *
1765 1775 * fname - filename or meta filename
1766 1776 * prop - valid property identifier
1767 1777 * propVal - property value
1768 1778 *
1769 1779 */
1770 1780 int
1771 1781 stmfModifyLuByFname(uint16_t dType, const char *fname, uint32_t prop,
1772 1782 const char *propVal)
1773 1783 {
1774 1784 int ret = STMF_STATUS_SUCCESS;
1775 1785 if (fname == NULL) {
1776 1786 return (STMF_ERROR_INVALID_ARG);
1777 1787 }
1778 1788
1779 1789 if (dType == STMF_DISK) {
1780 1790 ret = modifyDiskLuProp(NULL, fname, prop, propVal);
1781 1791 } else {
1782 1792 return (STMF_ERROR_INVALID_ARG);
1783 1793 }
1784 1794
1785 1795 return (ret);
1786 1796 }
1787 1797
1788 1798 static int
1789 1799 modifyDiskLuProp(stmfGuid *luGuid, const char *fname, uint32_t prop,
1790 1800 const char *propVal)
1791 1801 {
1792 1802 int ret = STMF_STATUS_SUCCESS;
1793 1803 luResource hdl = NULL;
1794 1804 luResourceImpl *luPropsHdl;
1795 1805
1796 1806 ret = stmfCreateLuResource(STMF_DISK, &hdl);
1797 1807 if (ret != STMF_STATUS_SUCCESS) {
1798 1808 return (ret);
1799 1809 }
1800 1810 ret = validateModifyDiskProp(prop);
1801 1811 if (ret != STMF_STATUS_SUCCESS) {
1802 1812 (void) stmfFreeLuResource(hdl);
1803 1813 return (STMF_ERROR_INVALID_PROP);
1804 1814 }
1805 1815 ret = stmfSetLuProp(hdl, prop, propVal);
1806 1816 if (ret != STMF_STATUS_SUCCESS) {
1807 1817 (void) stmfFreeLuResource(hdl);
1808 1818 return (ret);
1809 1819 }
1810 1820 luPropsHdl = hdl;
1811 1821 ret = modifyDiskLu((diskResource *)luPropsHdl->resource, luGuid, fname);
1812 1822 (void) stmfFreeLuResource(hdl);
1813 1823 return (ret);
1814 1824 }
|
↓ open down ↓ |
289 lines elided |
↑ open up ↑ |
1815 1825
1816 1826 static int
1817 1827 validateModifyDiskProp(uint32_t prop)
1818 1828 {
1819 1829 switch (prop) {
1820 1830 case STMF_LU_PROP_ALIAS:
1821 1831 case STMF_LU_PROP_SIZE:
1822 1832 case STMF_LU_PROP_MGMT_URL:
1823 1833 case STMF_LU_PROP_WRITE_PROTECT:
1824 1834 case STMF_LU_PROP_WRITE_CACHE_DISABLE:
1835 + case STMF_LU_PROP_UNMAP:
1825 1836 return (STMF_STATUS_SUCCESS);
1826 1837 break;
1827 1838 default:
1828 1839 return (STMF_STATUS_ERROR);
1829 1840 break;
1830 1841 }
1831 1842 }
1832 1843
1833 1844 static int
1834 1845 modifyDiskLu(diskResource *disk, stmfGuid *luGuid, const char *fname)
1835 1846 {
1836 1847 int ret = STMF_STATUS_SUCCESS;
1837 1848 int luAliasLen = 0;
1838 1849 int luMgmtUrlLen = 0;
1839 1850 int mluBufSize = 0;
1840 1851 int bufOffset = 0;
1841 1852 int fd = 0;
1842 1853 int ioctlRet;
1843 1854 int savedErrno;
1844 1855 int fnameSize = 0;
1845 1856 stmf_iocdata_t sbdIoctl = {0};
1846 1857
1847 1858 sbd_modify_lu_t *sbdLu = NULL;
1848 1859
1849 1860 if (luGuid == NULL && fname == NULL) {
1850 1861 return (STMF_ERROR_INVALID_ARG);
1851 1862 }
1852 1863
1853 1864 if (fname) {
1854 1865 fnameSize = strlen(fname) + 1;
1855 1866 mluBufSize += fnameSize;
1856 1867 }
1857 1868
1858 1869 /*
1859 1870 * Open control node for sbd
1860 1871 */
1861 1872 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
1862 1873 return (ret);
1863 1874
1864 1875 if (disk->luAliasValid) {
1865 1876 luAliasLen = strlen(disk->luAlias);
1866 1877 mluBufSize += luAliasLen + 1;
1867 1878 }
1868 1879
1869 1880 if (disk->luMgmtUrlValid) {
1870 1881 luMgmtUrlLen = strlen(disk->luMgmtUrl);
1871 1882 mluBufSize += luMgmtUrlLen + 1;
1872 1883 }
1873 1884
1874 1885 /*
1875 1886 * 8 is the size of the buffer set aside for
1876 1887 * concatenation of variable length fields
1877 1888 */
1878 1889 sbdLu = (sbd_modify_lu_t *)calloc(1,
1879 1890 sizeof (sbd_modify_lu_t) + mluBufSize - 8 + fnameSize);
1880 1891 if (sbdLu == NULL) {
1881 1892 (void) close(fd);
1882 1893 return (STMF_ERROR_NOMEM);
1883 1894 }
1884 1895
1885 1896 sbdLu->mlu_struct_size = sizeof (sbd_modify_lu_t) +
1886 1897 mluBufSize - 8 + fnameSize;
1887 1898
1888 1899 if (disk->luAliasValid) {
1889 1900 sbdLu->mlu_alias_valid = 1;
1890 1901 sbdLu->mlu_alias_off = bufOffset;
1891 1902 bcopy(disk->luAlias, &(sbdLu->mlu_buf[bufOffset]),
1892 1903 luAliasLen + 1);
1893 1904 bufOffset += luAliasLen + 1;
1894 1905 }
1895 1906
1896 1907 if (disk->luMgmtUrlValid) {
1897 1908 sbdLu->mlu_mgmt_url_valid = 1;
1898 1909 sbdLu->mlu_mgmt_url_off = bufOffset;
|
↓ open down ↓ |
64 lines elided |
↑ open up ↑ |
1899 1910 bcopy(disk->luMgmtUrl, &(sbdLu->mlu_buf[bufOffset]),
1900 1911 luMgmtUrlLen + 1);
1901 1912 bufOffset += luMgmtUrlLen + 1;
1902 1913 }
1903 1914
1904 1915 if (disk->luSizeValid) {
1905 1916 sbdLu->mlu_lu_size_valid = 1;
1906 1917 sbdLu->mlu_lu_size = disk->luSize;
1907 1918 }
1908 1919
1920 + if (disk->unmapValid) {
1921 + sbdLu->mlu_unmap_valid = 1;
1922 + if (disk->unmap)
1923 + sbdLu->mlu_unmap = 1;
1924 + }
1925 +
1909 1926 if (disk->writeProtectEnableValid) {
1910 1927 sbdLu->mlu_write_protected_valid = 1;
1911 1928 if (disk->writeProtectEnable) {
1912 1929 sbdLu->mlu_write_protected = 1;
1913 1930 }
1914 1931 }
1915 1932
1916 1933 if (disk->writebackCacheDisableValid) {
1917 1934 sbdLu->mlu_writeback_cache_disable_valid = 1;
1918 1935 if (disk->writebackCacheDisable) {
1919 1936 sbdLu->mlu_writeback_cache_disable = 1;
1920 1937 }
1921 1938 }
1922 1939
1923 1940 if (luGuid) {
1924 1941 bcopy(luGuid, sbdLu->mlu_input_guid, sizeof (stmfGuid));
1925 1942 sbdLu->mlu_by_guid = 1;
1926 1943 } else {
1927 1944 sbdLu->mlu_fname_off = bufOffset;
1928 1945 bcopy(fname, &(sbdLu->mlu_buf[bufOffset]), fnameSize + 1);
1929 1946 sbdLu->mlu_by_fname = 1;
1930 1947 }
1931 1948
1932 1949 sbdIoctl.stmf_version = STMF_VERSION_1;
1933 1950 sbdIoctl.stmf_ibuf_size = sbdLu->mlu_struct_size;
1934 1951 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdLu;
1935 1952
1936 1953 ioctlRet = ioctl(fd, SBD_IOCTL_MODIFY_LU, &sbdIoctl);
1937 1954 if (ioctlRet != 0) {
1938 1955 savedErrno = errno;
1939 1956 switch (savedErrno) {
1940 1957 case EBUSY:
1941 1958 ret = STMF_ERROR_BUSY;
1942 1959 break;
1943 1960 case EPERM:
1944 1961 case EACCES:
1945 1962 ret = STMF_ERROR_PERM;
1946 1963 break;
1947 1964 default:
1948 1965 diskError(sbdIoctl.stmf_error, &ret);
1949 1966 if (ret == STMF_STATUS_ERROR) {
1950 1967 syslog(LOG_DEBUG,
1951 1968 "modifyDiskLu:ioctl "
1952 1969 "error(%d) (%d) (%d)", ioctlRet,
1953 1970 sbdIoctl.stmf_error, savedErrno);
1954 1971 }
1955 1972 break;
1956 1973 }
1957 1974 }
1958 1975
1959 1976 if (ret != STMF_STATUS_SUCCESS) {
1960 1977 goto done;
1961 1978 }
1962 1979
1963 1980 done:
1964 1981 free(sbdLu);
1965 1982 (void) close(fd);
1966 1983 return (ret);
1967 1984 }
1968 1985
1969 1986 /*
1970 1987 * removeGuidFromDiskStore
1971 1988 *
1972 1989 * Purpose: delete a logical unit from the sbd provider data
1973 1990 */
1974 1991 static int
1975 1992 removeGuidFromDiskStore(stmfGuid *guid)
1976 1993 {
1977 1994 return (persistDiskGuid(guid, NULL, B_FALSE));
1978 1995 }
1979 1996
1980 1997
1981 1998 /*
1982 1999 * addGuidToDiskStore
1983 2000 *
1984 2001 * Purpose: add a logical unit to the sbd provider data
1985 2002 */
1986 2003 static int
1987 2004 addGuidToDiskStore(stmfGuid *guid, char *filename)
1988 2005 {
1989 2006 return (persistDiskGuid(guid, filename, B_TRUE));
1990 2007 }
1991 2008
1992 2009
1993 2010 /*
1994 2011 * persistDiskGuid
1995 2012 *
1996 2013 * Purpose: Persist or unpersist a guid for the sbd provider data
1997 2014 *
1998 2015 */
1999 2016 static int
2000 2017 persistDiskGuid(stmfGuid *guid, char *filename, boolean_t persist)
2001 2018 {
2002 2019 char guidAsciiBuf[LU_ASCII_GUID_SIZE + 1] = {0};
2003 2020 nvlist_t *nvl = NULL;
2004 2021
2005 2022 uint64_t setToken;
2006 2023 boolean_t retryGetProviderData = B_FALSE;
2007 2024 boolean_t newData = B_FALSE;
2008 2025 int ret = STMF_STATUS_SUCCESS;
2009 2026 int retryCnt = 0;
2010 2027 int stmfRet;
2011 2028
2012 2029 /* if we're persisting a guid, there must be a filename */
2013 2030 if (persist && !filename) {
2014 2031 return (1);
2015 2032 }
2016 2033
2017 2034 /* guid is stored in lowercase ascii hex */
2018 2035 (void) snprintf(guidAsciiBuf, sizeof (guidAsciiBuf),
2019 2036 "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"
2020 2037 "%02x%02x%02x%02x%02x%02x",
2021 2038 guid->guid[0], guid->guid[1], guid->guid[2], guid->guid[3],
2022 2039 guid->guid[4], guid->guid[5], guid->guid[6], guid->guid[7],
2023 2040 guid->guid[8], guid->guid[9], guid->guid[10], guid->guid[11],
2024 2041 guid->guid[12], guid->guid[13], guid->guid[14], guid->guid[15]);
2025 2042
2026 2043
2027 2044 do {
2028 2045 retryGetProviderData = B_FALSE;
2029 2046 stmfRet = stmfGetProviderDataProt("sbd", &nvl,
2030 2047 STMF_LU_PROVIDER_TYPE, &setToken);
2031 2048 if (stmfRet != STMF_STATUS_SUCCESS) {
2032 2049 if (persist && stmfRet == STMF_ERROR_NOT_FOUND) {
2033 2050 ret = nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0);
2034 2051 if (ret != 0) {
2035 2052 syslog(LOG_DEBUG,
2036 2053 "unpersistGuid:nvlist_alloc(%d)",
2037 2054 ret);
2038 2055 ret = STMF_STATUS_ERROR;
2039 2056 goto done;
2040 2057 }
2041 2058 newData = B_TRUE;
2042 2059 } else {
2043 2060 /*
2044 2061 * if we're persisting the data, it's
2045 2062 * an error. Otherwise, just return
2046 2063 */
2047 2064 if (persist) {
2048 2065 ret = stmfRet;
2049 2066 }
2050 2067 goto done;
2051 2068 }
2052 2069 }
2053 2070 if (persist) {
2054 2071 ret = nvlist_add_string(nvl, guidAsciiBuf, filename);
2055 2072 } else {
2056 2073 ret = nvlist_remove(nvl, guidAsciiBuf,
2057 2074 DATA_TYPE_STRING);
2058 2075 if (ret == ENOENT) {
2059 2076 ret = 0;
2060 2077 }
2061 2078 }
2062 2079 if (ret == 0) {
2063 2080 if (newData) {
2064 2081 stmfRet = stmfSetProviderDataProt("sbd", nvl,
2065 2082 STMF_LU_PROVIDER_TYPE, NULL);
2066 2083 } else {
2067 2084 stmfRet = stmfSetProviderDataProt("sbd", nvl,
2068 2085 STMF_LU_PROVIDER_TYPE, &setToken);
2069 2086 }
2070 2087 if (stmfRet != STMF_STATUS_SUCCESS) {
2071 2088 if (stmfRet == STMF_ERROR_BUSY) {
2072 2089 /* get/set failed, try again */
2073 2090 retryGetProviderData = B_TRUE;
2074 2091 if (retryCnt++ > MAX_PROVIDER_RETRY) {
2075 2092 ret = stmfRet;
2076 2093 break;
2077 2094 }
2078 2095 continue;
2079 2096 } else if (stmfRet ==
2080 2097 STMF_ERROR_PROV_DATA_STALE) {
2081 2098 /* update failed, try again */
2082 2099 nvlist_free(nvl);
2083 2100 nvl = NULL;
2084 2101 retryGetProviderData = B_TRUE;
2085 2102 if (retryCnt++ > MAX_PROVIDER_RETRY) {
2086 2103 ret = stmfRet;
2087 2104 break;
2088 2105 }
2089 2106 continue;
2090 2107 } else {
2091 2108 syslog(LOG_DEBUG,
2092 2109 "unpersistGuid:error(%x)", stmfRet);
2093 2110 ret = stmfRet;
2094 2111 }
2095 2112 break;
2096 2113 }
2097 2114 } else {
2098 2115 syslog(LOG_DEBUG,
2099 2116 "unpersistGuid:error nvlist_add/remove(%d)",
2100 2117 ret);
2101 2118 ret = STMF_STATUS_ERROR;
2102 2119 }
2103 2120 } while (retryGetProviderData);
2104 2121
2105 2122 done:
2106 2123 nvlist_free(nvl);
2107 2124 return (ret);
2108 2125 }
2109 2126
2110 2127
2111 2128 /*
2112 2129 * stmfGetLuProp
2113 2130 *
2114 2131 * Purpose: Get current value for a resource property
2115 2132 *
2116 2133 * hdl - luResource from a previous call to stmfCreateLuResource
2117 2134 *
2118 2135 * resourceProp - a valid resource property type
2119 2136 *
2120 2137 * propVal - void pointer to a pointer of the value to be retrieved
2121 2138 */
2122 2139 int
2123 2140 stmfGetLuProp(luResource hdl, uint32_t prop, char *propVal, size_t *propLen)
2124 2141 {
2125 2142 int ret = STMF_STATUS_SUCCESS;
2126 2143 luResourceImpl *luPropsHdl = hdl;
2127 2144 if (hdl == NULL || propLen == NULL || propVal == NULL) {
2128 2145 return (STMF_ERROR_INVALID_ARG);
2129 2146 }
2130 2147
2131 2148 if (luPropsHdl->type == STMF_DISK) {
2132 2149 ret = getDiskProp(luPropsHdl, prop, propVal, propLen);
2133 2150 } else {
2134 2151 return (STMF_ERROR_INVALID_ARG);
2135 2152 }
2136 2153
2137 2154 return (ret);
2138 2155 }
2139 2156
2140 2157 /*
2141 2158 * stmfGetLuResource
2142 2159 *
2143 2160 * Purpose: Get a logical unit resource handle for a given logical unit.
2144 2161 *
2145 2162 * hdl - pointer to luResource
2146 2163 */
2147 2164 int
2148 2165 stmfGetLuResource(stmfGuid *luGuid, luResource *hdl)
2149 2166 {
2150 2167 int ret = STMF_STATUS_SUCCESS;
2151 2168 stmfLogicalUnitProperties luProps;
2152 2169
2153 2170 if (hdl == NULL) {
2154 2171 return (STMF_ERROR_INVALID_ARG);
2155 2172 }
2156 2173
2157 2174 /* Check logical unit provider name to call correct dtype function */
2158 2175 if ((ret = stmfGetLogicalUnitProperties(luGuid, &luProps))
2159 2176 != STMF_STATUS_SUCCESS) {
2160 2177 return (ret);
2161 2178 } else {
2162 2179 if (strcmp(luProps.providerName, "sbd") == 0) {
2163 2180 ret = getDiskAllProps(luGuid, hdl);
2164 2181 } else if (luProps.status == STMF_LOGICAL_UNIT_UNREGISTERED) {
2165 2182 return (STMF_ERROR_NOT_FOUND);
2166 2183 } else {
2167 2184 return (STMF_ERROR_INVALID_ARG);
2168 2185 }
2169 2186 }
2170 2187
2171 2188 return (ret);
2172 2189 }
2173 2190
2174 2191 /*
2175 2192 * getDiskAllProps
2176 2193 *
2177 2194 * Purpose: load all disk properties from sbd driver
2178 2195 *
2179 2196 * luGuid - guid of disk device for which properties are to be retrieved
2180 2197 * hdl - allocated luResource into which properties are to be copied
2181 2198 *
2182 2199 */
2183 2200 static int
2184 2201 getDiskAllProps(stmfGuid *luGuid, luResource *hdl)
2185 2202 {
2186 2203 int ret = STMF_STATUS_SUCCESS;
2187 2204 int fd;
2188 2205 sbd_lu_props_t *sbdProps;
2189 2206 int ioctlRet;
2190 2207 int savedErrno;
2191 2208 int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
2192 2209 stmf_iocdata_t sbdIoctl = {0};
2193 2210
2194 2211 /*
2195 2212 * Open control node for sbd
2196 2213 */
2197 2214 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2198 2215 return (ret);
2199 2216
2200 2217
2201 2218 *hdl = calloc(1, sizeof (luResourceImpl));
2202 2219 if (*hdl == NULL) {
2203 2220 (void) close(fd);
2204 2221 return (STMF_ERROR_NOMEM);
2205 2222 }
2206 2223
2207 2224 sbdProps = calloc(1, sbdPropsSize);
2208 2225 if (sbdProps == NULL) {
2209 2226 free(*hdl);
2210 2227 (void) close(fd);
2211 2228 return (STMF_ERROR_NOMEM);
2212 2229 }
2213 2230
2214 2231 ret = createDiskResource((luResourceImpl *)*hdl);
2215 2232 if (ret != STMF_STATUS_SUCCESS) {
2216 2233 free(*hdl);
2217 2234 free(sbdProps);
2218 2235 (void) close(fd);
2219 2236 return (ret);
2220 2237 }
2221 2238
2222 2239 sbdProps->slp_input_guid = 1;
2223 2240 bcopy(luGuid, sbdProps->slp_guid, sizeof (sbdProps->slp_guid));
2224 2241
2225 2242 sbdIoctl.stmf_version = STMF_VERSION_1;
2226 2243 sbdIoctl.stmf_ibuf_size = sbdPropsSize;
2227 2244 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdProps;
2228 2245 sbdIoctl.stmf_obuf_size = sbdPropsSize;
2229 2246 sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
2230 2247 ioctlRet = ioctl(fd, SBD_IOCTL_GET_LU_PROPS, &sbdIoctl);
2231 2248 if (ioctlRet != 0) {
2232 2249 savedErrno = errno;
2233 2250 switch (savedErrno) {
2234 2251 case EBUSY:
2235 2252 ret = STMF_ERROR_BUSY;
2236 2253 break;
2237 2254 case EPERM:
2238 2255 case EACCES:
2239 2256 ret = STMF_ERROR_PERM;
2240 2257 break;
2241 2258 case ENOENT:
2242 2259 ret = STMF_ERROR_NOT_FOUND;
2243 2260 break;
2244 2261 default:
2245 2262 syslog(LOG_DEBUG,
2246 2263 "getDiskAllProps:ioctl error(%d) (%d) (%d)",
2247 2264 ioctlRet, sbdIoctl.stmf_error, savedErrno);
2248 2265 ret = STMF_STATUS_ERROR;
2249 2266 break;
2250 2267 }
2251 2268 }
2252 2269
2253 2270 if (ret == STMF_STATUS_SUCCESS) {
2254 2271 ret = loadDiskPropsFromDriver((luResourceImpl *)*hdl, sbdProps);
2255 2272 }
2256 2273
2257 2274 free(sbdProps);
2258 2275 (void) close(fd);
2259 2276 return (ret);
2260 2277 }
2261 2278
2262 2279 /*
2263 2280 * loadDiskPropsFromDriver
2264 2281 *
2265 2282 * Purpose: Retrieve all disk type properties from sbd driver
2266 2283 *
2267 2284 * hdl - Allocated luResourceImpl
2268 2285 * sbdProps - sbd_lu_props_t structure returned from sbd driver
2269 2286 *
2270 2287 */
2271 2288 static int
2272 2289 loadDiskPropsFromDriver(luResourceImpl *hdl, sbd_lu_props_t *sbdProps)
2273 2290 {
2274 2291 int ret = STMF_STATUS_SUCCESS;
2275 2292 diskResource *diskLu = hdl->resource;
2276 2293 /* copy guid */
2277 2294 diskLu->luGuidValid = B_TRUE;
2278 2295 bcopy(sbdProps->slp_guid, diskLu->luGuid, sizeof (sbdProps->slp_guid));
2279 2296
2280 2297 if (sbdProps->slp_separate_meta && sbdProps->slp_meta_fname_valid) {
2281 2298 diskLu->luMetaFileNameValid = B_TRUE;
2282 2299 if (strlcpy(diskLu->luMetaFileName,
2283 2300 (char *)&(sbdProps->slp_buf[sbdProps->slp_meta_fname_off]),
2284 2301 sizeof (diskLu->luMetaFileName)) >=
2285 2302 sizeof (diskLu->luMetaFileName)) {
2286 2303 return (STMF_STATUS_ERROR);
2287 2304 }
2288 2305 }
2289 2306
2290 2307 if (sbdProps->slp_data_fname_valid) {
2291 2308 diskLu->luDataFileNameValid = B_TRUE;
2292 2309 if (strlcpy(diskLu->luDataFileName,
2293 2310 (char *)&(sbdProps->slp_buf[sbdProps->slp_data_fname_off]),
2294 2311 sizeof (diskLu->luDataFileName)) >=
2295 2312 sizeof (diskLu->luDataFileName)) {
2296 2313 return (STMF_STATUS_ERROR);
2297 2314 }
2298 2315 }
2299 2316
2300 2317 if (sbdProps->slp_serial_valid) {
2301 2318 diskLu->serialNumValid = B_TRUE;
2302 2319 bcopy(&(sbdProps->slp_buf[sbdProps->slp_serial_off]),
2303 2320 diskLu->serialNum, sbdProps->slp_serial_size);
2304 2321 }
2305 2322
2306 2323 if (sbdProps->slp_mgmt_url_valid) {
2307 2324 diskLu->luMgmtUrlValid = B_TRUE;
2308 2325 if (strlcpy(diskLu->luMgmtUrl,
2309 2326 (char *)&(sbdProps->slp_buf[sbdProps->slp_mgmt_url_off]),
2310 2327 sizeof (diskLu->luMgmtUrl)) >=
2311 2328 sizeof (diskLu->luMgmtUrl)) {
2312 2329 return (STMF_STATUS_ERROR);
2313 2330 }
2314 2331 }
2315 2332
2316 2333 if (sbdProps->slp_alias_valid) {
2317 2334 diskLu->luAliasValid = B_TRUE;
2318 2335 if (strlcpy(diskLu->luAlias,
2319 2336 (char *)&(sbdProps->slp_buf[sbdProps->slp_alias_off]),
2320 2337 sizeof (diskLu->luAlias)) >=
2321 2338 sizeof (diskLu->luAlias)) {
2322 2339 return (STMF_STATUS_ERROR);
2323 2340 }
2324 2341 } else { /* set alias to data filename if not set */
2325 2342 if (sbdProps->slp_data_fname_valid) {
2326 2343 diskLu->luAliasValid = B_TRUE;
2327 2344 if (strlcpy(diskLu->luAlias,
2328 2345 (char *)&(sbdProps->slp_buf[
2329 2346 sbdProps->slp_data_fname_off]),
2330 2347 sizeof (diskLu->luAlias)) >=
2331 2348 sizeof (diskLu->luAlias)) {
2332 2349 return (STMF_STATUS_ERROR);
2333 2350 }
2334 2351 }
2335 2352 }
|
↓ open down ↓ |
417 lines elided |
↑ open up ↑ |
2336 2353
2337 2354 diskLu->vidValid = B_TRUE;
2338 2355 bcopy(sbdProps->slp_vid, diskLu->vid, sizeof (diskLu->vid));
2339 2356
2340 2357 diskLu->pidValid = B_TRUE;
2341 2358 bcopy(sbdProps->slp_pid, diskLu->pid, sizeof (diskLu->pid));
2342 2359
2343 2360 diskLu->revValid = B_TRUE;
2344 2361 bcopy(sbdProps->slp_rev, diskLu->rev, sizeof (diskLu->rev));
2345 2362
2363 + diskLu->unmapValid = B_TRUE;
2364 + if (sbdProps->slp_unmap_cur)
2365 + diskLu->unmap = B_TRUE;
2366 +
2346 2367 diskLu->writeProtectEnableValid = B_TRUE;
2347 2368 if (sbdProps->slp_write_protected) {
2348 2369 diskLu->writeProtectEnable = B_TRUE;
2349 2370 }
2350 2371
2351 2372 diskLu->writebackCacheDisableValid = B_TRUE;
2352 2373 if (sbdProps->slp_writeback_cache_disable_cur) {
2353 2374 diskLu->writebackCacheDisable = B_TRUE;
2354 2375 }
2355 2376
2356 2377 diskLu->blkSizeValid = B_TRUE;
2357 2378 diskLu->blkSize = sbdProps->slp_blksize;
2358 2379
2359 2380 diskLu->luSizeValid = B_TRUE;
2360 2381 diskLu->luSize = sbdProps->slp_lu_size;
2361 2382
2362 2383 diskLu->accessState = sbdProps->slp_access_state;
2363 2384
2364 2385 return (ret);
2365 2386 }
2366 2387
2367 2388 /*
2368 2389 * stmfGetGlobalLuProp
2369 2390 *
2370 2391 * Purpose: get a global property for a device type
2371 2392 *
2372 2393 */
2373 2394 int
2374 2395 stmfGetGlobalLuProp(uint16_t dType, uint32_t prop, char *propVal,
2375 2396 size_t *propLen)
2376 2397 {
2377 2398 int ret = STMF_STATUS_SUCCESS;
2378 2399 if (dType != STMF_DISK || propVal == NULL) {
2379 2400 return (STMF_ERROR_INVALID_ARG);
2380 2401 }
2381 2402
2382 2403 ret = getDiskGlobalProp(prop, propVal, propLen);
2383 2404
2384 2405 return (ret);
2385 2406 }
2386 2407
2387 2408 /*
2388 2409 * getDiskGlobalProp
2389 2410 *
2390 2411 * Purpose: get global property from sbd driver
2391 2412 *
2392 2413 */
2393 2414 static int
2394 2415 getDiskGlobalProp(uint32_t prop, char *propVal, size_t *propLen)
2395 2416 {
2396 2417 int ret = STMF_STATUS_SUCCESS;
2397 2418 int fd;
2398 2419 sbd_global_props_t *sbdProps;
2399 2420 void *sbd_realloc;
2400 2421 int retryCnt = 0;
2401 2422 boolean_t retry;
2402 2423 int ioctlRet;
2403 2424 int savedErrno;
2404 2425 int sbdPropsSize = sizeof (*sbdProps) + MAX_SBD_PROPS;
2405 2426 stmf_iocdata_t sbdIoctl = {0};
2406 2427 size_t reqLen;
2407 2428
2408 2429 switch (prop) {
2409 2430 case STMF_LU_PROP_MGMT_URL:
2410 2431 break;
2411 2432 default:
2412 2433 return (STMF_ERROR_INVALID_PROP);
2413 2434 }
2414 2435
2415 2436 /*
2416 2437 * Open control node for sbd
2417 2438 */
2418 2439 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2419 2440 return (ret);
2420 2441
2421 2442 sbdProps = calloc(1, sbdPropsSize);
2422 2443 if (sbdProps == NULL) {
2423 2444 (void) close(fd);
2424 2445 return (STMF_ERROR_NOMEM);
2425 2446 }
2426 2447
2427 2448 do {
2428 2449 retry = B_FALSE;
2429 2450 sbdIoctl.stmf_version = STMF_VERSION_1;
2430 2451 sbdIoctl.stmf_obuf_size = sbdPropsSize;
2431 2452 sbdIoctl.stmf_obuf = (uint64_t)(unsigned long)sbdProps;
2432 2453 ioctlRet = ioctl(fd, SBD_IOCTL_GET_GLOBAL_LU, &sbdIoctl);
2433 2454 if (ioctlRet != 0) {
2434 2455 savedErrno = errno;
2435 2456 switch (savedErrno) {
2436 2457 case EBUSY:
2437 2458 ret = STMF_ERROR_BUSY;
2438 2459 break;
2439 2460 case EPERM:
2440 2461 case EACCES:
2441 2462 ret = STMF_ERROR_PERM;
2442 2463 break;
2443 2464 case ENOMEM:
2444 2465 if (sbdIoctl.stmf_error ==
2445 2466 SBD_RET_INSUFFICIENT_BUF_SPACE &&
2446 2467 retryCnt++ < 3) {
2447 2468 sbdPropsSize =
2448 2469 sizeof (*sbdProps) +
2449 2470 sbdProps->
2450 2471 mlu_buf_size_needed;
2451 2472
2452 2473 sbd_realloc = sbdProps;
2453 2474 sbdProps = realloc(sbdProps,
2454 2475 sbdPropsSize);
2455 2476 if (sbdProps == NULL) {
2456 2477 free(sbd_realloc);
2457 2478 ret = STMF_ERROR_NOMEM;
2458 2479 break;
2459 2480 }
2460 2481 retry = B_TRUE;
2461 2482 } else {
2462 2483 ret = STMF_ERROR_NOMEM;
2463 2484 }
2464 2485 break;
2465 2486 default:
2466 2487 syslog(LOG_DEBUG,
2467 2488 "getDiskGlobalProp:ioctl error(%d)"
2468 2489 "(%d)(%d)", ioctlRet,
2469 2490 sbdIoctl.stmf_error, savedErrno);
2470 2491 ret = STMF_STATUS_ERROR;
2471 2492 break;
2472 2493 }
2473 2494
2474 2495 }
2475 2496 } while (retry);
2476 2497
2477 2498 if (ret != STMF_STATUS_SUCCESS) {
2478 2499 goto done;
2479 2500 }
2480 2501
2481 2502 switch (prop) {
2482 2503 case STMF_LU_PROP_MGMT_URL:
2483 2504 if (sbdProps->mlu_mgmt_url_valid == 0) {
2484 2505 ret = STMF_ERROR_NO_PROP;
2485 2506 goto done;
2486 2507 }
2487 2508 if ((reqLen = strlcpy(propVal, (char *)&(
2488 2509 sbdProps->mlu_buf[sbdProps->mlu_mgmt_url_off]),
2489 2510 *propLen)) >= *propLen) {
2490 2511 *propLen = reqLen + 1;
2491 2512 ret = STMF_ERROR_INVALID_ARG;
2492 2513 goto done;
2493 2514 }
2494 2515 break;
2495 2516 }
2496 2517
2497 2518 done:
2498 2519 free(sbdProps);
2499 2520 (void) close(fd);
2500 2521 return (ret);
2501 2522 }
2502 2523
2503 2524 /*
2504 2525 * stmfSetGlobalLuProp
2505 2526 *
2506 2527 * Purpose: set a global property for a device type
2507 2528 *
2508 2529 */
2509 2530 int
2510 2531 stmfSetGlobalLuProp(uint16_t dType, uint32_t prop, const char *propVal)
2511 2532 {
2512 2533 int ret = STMF_STATUS_SUCCESS;
2513 2534 if (dType != STMF_DISK || propVal == NULL) {
2514 2535 return (STMF_ERROR_INVALID_ARG);
2515 2536 }
2516 2537
2517 2538 ret = setDiskGlobalProp(prop, propVal);
2518 2539
2519 2540 return (ret);
2520 2541 }
2521 2542
2522 2543 /*
2523 2544 * setDiskGlobalProp
2524 2545 *
2525 2546 * Purpose: set properties for resource of type disk
2526 2547 *
2527 2548 * resourceProp - valid resource identifier
2528 2549 * propVal - valid resource value
2529 2550 */
2530 2551 static int
2531 2552 setDiskGlobalProp(uint32_t resourceProp, const char *propVal)
2532 2553 {
2533 2554 int ret = STMF_STATUS_SUCCESS;
2534 2555 sbd_global_props_t *sbdGlobalProps = NULL;
2535 2556 int sbdGlobalPropsSize = 0;
2536 2557 int propLen;
2537 2558 int mluBufSize = 0;
2538 2559 int fd;
2539 2560 int savedErrno;
2540 2561 int ioctlRet;
2541 2562 stmf_iocdata_t sbdIoctl = {0};
2542 2563
2543 2564 switch (resourceProp) {
2544 2565 case STMF_LU_PROP_MGMT_URL:
2545 2566 break;
2546 2567 default:
2547 2568 return (STMF_ERROR_INVALID_PROP);
2548 2569 break;
2549 2570 }
2550 2571
2551 2572 /*
2552 2573 * Open control node for sbd
2553 2574 */
2554 2575 if ((ret = openSbd(OPEN_SBD, &fd)) != STMF_STATUS_SUCCESS)
2555 2576 return (ret);
2556 2577
2557 2578 propLen = strlen(propVal);
2558 2579 mluBufSize += propLen + 1;
2559 2580 sbdGlobalPropsSize += sizeof (sbd_global_props_t) - 8 +
2560 2581 max(8, mluBufSize);
2561 2582 /*
2562 2583 * 8 is the size of the buffer set aside for
2563 2584 * concatenation of variable length fields
2564 2585 */
2565 2586 sbdGlobalProps = (sbd_global_props_t *)calloc(1, sbdGlobalPropsSize);
2566 2587 if (sbdGlobalProps == NULL) {
2567 2588 (void) close(fd);
2568 2589 return (STMF_ERROR_NOMEM);
2569 2590 }
2570 2591
2571 2592 sbdGlobalProps->mlu_struct_size = sbdGlobalPropsSize;
2572 2593
2573 2594 switch (resourceProp) {
2574 2595 case STMF_LU_PROP_MGMT_URL:
2575 2596 sbdGlobalProps->mlu_mgmt_url_valid = 1;
2576 2597 bcopy(propVal, &(sbdGlobalProps->mlu_buf),
2577 2598 propLen + 1);
2578 2599 break;
2579 2600 default:
2580 2601 ret = STMF_ERROR_NO_PROP;
2581 2602 goto done;
2582 2603 }
2583 2604
2584 2605 sbdIoctl.stmf_version = STMF_VERSION_1;
2585 2606 sbdIoctl.stmf_ibuf_size = sbdGlobalProps->mlu_struct_size;
2586 2607 sbdIoctl.stmf_ibuf = (uint64_t)(unsigned long)sbdGlobalProps;
2587 2608
2588 2609 ioctlRet = ioctl(fd, SBD_IOCTL_SET_GLOBAL_LU, &sbdIoctl);
2589 2610 if (ioctlRet != 0) {
2590 2611 savedErrno = errno;
2591 2612 switch (savedErrno) {
2592 2613 case EBUSY:
2593 2614 ret = STMF_ERROR_BUSY;
2594 2615 break;
2595 2616 case EPERM:
2596 2617 case EACCES:
2597 2618 ret = STMF_ERROR_PERM;
2598 2619 break;
2599 2620 default:
2600 2621 diskError(sbdIoctl.stmf_error, &ret);
2601 2622 if (ret == STMF_STATUS_ERROR) {
2602 2623 syslog(LOG_DEBUG,
2603 2624 "modifyDiskLu:ioctl "
2604 2625 "error(%d) (%d) (%d)", ioctlRet,
2605 2626 sbdIoctl.stmf_error, savedErrno);
2606 2627 }
2607 2628 break;
2608 2629 }
2609 2630 }
2610 2631
2611 2632 done:
2612 2633 free(sbdGlobalProps);
2613 2634 (void) close(fd);
2614 2635 return (ret);
2615 2636 }
2616 2637
2617 2638
2618 2639 /*
2619 2640 * stmfSetLuProp
2620 2641 *
2621 2642 * Purpose: set a property on an luResource
2622 2643 *
2623 2644 * hdl - allocated luResource
2624 2645 * prop - property identifier
2625 2646 * propVal - property value to be set
2626 2647 */
2627 2648 int
2628 2649 stmfSetLuProp(luResource hdl, uint32_t prop, const char *propVal)
2629 2650 {
2630 2651 int ret = STMF_STATUS_SUCCESS;
2631 2652 luResourceImpl *luPropsHdl = hdl;
2632 2653 if (hdl == NULL) {
2633 2654 return (STMF_ERROR_INVALID_ARG);
2634 2655 }
2635 2656
2636 2657 if (luPropsHdl->type == STMF_DISK) {
2637 2658 ret = setDiskProp(luPropsHdl, prop, propVal);
2638 2659 } else {
2639 2660 return (STMF_ERROR_INVALID_ARG);
2640 2661 }
2641 2662
2642 2663 return (ret);
2643 2664 }
2644 2665
2645 2666 /*
2646 2667 * getDiskProp
2647 2668 *
2648 2669 * Purpose: retrieve a given property from a logical unit resource of type disk
2649 2670 *
2650 2671 * hdl - allocated luResourceImpl
2651 2672 * prop - property identifier
2652 2673 * propVal - pointer to character to contain the retrieved property value
2653 2674 * propLen - On input this is the length of propVal. On failure, it contains the
2654 2675 * number of bytes required for propVal
2655 2676 */
2656 2677 static int
2657 2678 getDiskProp(luResourceImpl *hdl, uint32_t prop, char *propVal, size_t *propLen)
2658 2679 {
2659 2680 int ret = STMF_STATUS_SUCCESS;
2660 2681 diskResource *diskLu = hdl->resource;
2661 2682 char accessState[20];
2662 2683 size_t reqLen;
2663 2684
2664 2685 if (prop == STMF_LU_PROP_ACCESS_STATE) {
2665 2686 if (diskLu->accessState == SBD_LU_ACTIVE) {
2666 2687 (void) strlcpy(accessState, STMF_ACCESS_ACTIVE,
2667 2688 sizeof (accessState));
2668 2689 } else if (diskLu->accessState == SBD_LU_TRANSITION_TO_ACTIVE) {
2669 2690 (void) strlcpy(accessState,
2670 2691 STMF_ACCESS_STANDBY_TO_ACTIVE,
2671 2692 sizeof (accessState));
2672 2693 } else if (diskLu->accessState == SBD_LU_STANDBY) {
2673 2694 (void) strlcpy(accessState, STMF_ACCESS_STANDBY,
2674 2695 sizeof (accessState));
2675 2696 } else if (diskLu->accessState ==
2676 2697 SBD_LU_TRANSITION_TO_STANDBY) {
2677 2698 (void) strlcpy(accessState,
2678 2699 STMF_ACCESS_ACTIVE_TO_STANDBY,
2679 2700 sizeof (accessState));
2680 2701 }
2681 2702 if ((reqLen = strlcpy(propVal, accessState,
2682 2703 *propLen)) >= *propLen) {
2683 2704 *propLen = reqLen + 1;
2684 2705 return (STMF_ERROR_INVALID_ARG);
2685 2706 }
2686 2707 return (0);
2687 2708 }
2688 2709
2689 2710 if (diskLu->accessState != SBD_LU_ACTIVE) {
2690 2711 return (STMF_ERROR_NO_PROP_STANDBY);
2691 2712 }
2692 2713
2693 2714 switch (prop) {
2694 2715 case STMF_LU_PROP_BLOCK_SIZE:
2695 2716 if (diskLu->blkSizeValid == B_FALSE) {
2696 2717 return (STMF_ERROR_NO_PROP);
2697 2718 }
2698 2719 reqLen = snprintf(propVal, *propLen, "%llu",
2699 2720 (u_longlong_t)diskLu->blkSize);
2700 2721 if (reqLen >= *propLen) {
2701 2722 *propLen = reqLen + 1;
2702 2723 return (STMF_ERROR_INVALID_ARG);
2703 2724 }
2704 2725 break;
2705 2726 case STMF_LU_PROP_FILENAME:
2706 2727 if (diskLu->luDataFileNameValid == B_FALSE) {
2707 2728 return (STMF_ERROR_NO_PROP);
2708 2729 }
2709 2730 if ((reqLen = strlcpy(propVal, diskLu->luDataFileName,
2710 2731 *propLen)) >= *propLen) {
2711 2732 *propLen = reqLen + 1;
2712 2733 return (STMF_ERROR_INVALID_ARG);
2713 2734 }
2714 2735 break;
2715 2736 case STMF_LU_PROP_META_FILENAME:
2716 2737 if (diskLu->luMetaFileNameValid == B_FALSE) {
2717 2738 return (STMF_ERROR_NO_PROP);
2718 2739 }
2719 2740 if ((reqLen = strlcpy(propVal, diskLu->luMetaFileName,
2720 2741 *propLen)) >= *propLen) {
2721 2742 *propLen = reqLen + 1;
2722 2743 return (STMF_ERROR_INVALID_ARG);
2723 2744 }
2724 2745 break;
2725 2746 case STMF_LU_PROP_MGMT_URL:
2726 2747 if (diskLu->luMgmtUrlValid == B_FALSE) {
2727 2748 return (STMF_ERROR_NO_PROP);
2728 2749 }
2729 2750 if ((reqLen = strlcpy(propVal, diskLu->luMgmtUrl,
2730 2751 *propLen)) >= *propLen) {
2731 2752 *propLen = reqLen + 1;
2732 2753 return (STMF_ERROR_INVALID_ARG);
2733 2754 }
2734 2755 break;
2735 2756 case STMF_LU_PROP_GUID:
2736 2757 if (diskLu->luGuidValid == B_FALSE) {
2737 2758 return (STMF_ERROR_NO_PROP);
2738 2759 }
2739 2760 reqLen = snprintf(propVal, *propLen,
2740 2761 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
2741 2762 "%02X%02X%02X%02X",
2742 2763 diskLu->luGuid[0], diskLu->luGuid[1],
2743 2764 diskLu->luGuid[2], diskLu->luGuid[3],
2744 2765 diskLu->luGuid[4], diskLu->luGuid[5],
2745 2766 diskLu->luGuid[6], diskLu->luGuid[7],
2746 2767 diskLu->luGuid[8], diskLu->luGuid[9],
2747 2768 diskLu->luGuid[10], diskLu->luGuid[11],
2748 2769 diskLu->luGuid[12], diskLu->luGuid[13],
2749 2770 diskLu->luGuid[14], diskLu->luGuid[15]);
2750 2771 if (reqLen >= *propLen) {
2751 2772 *propLen = reqLen + 1;
2752 2773 return (STMF_ERROR_INVALID_ARG);
2753 2774 }
2754 2775 break;
2755 2776 case STMF_LU_PROP_SERIAL_NUM:
2756 2777 if (diskLu->serialNumValid == B_FALSE) {
2757 2778 return (STMF_ERROR_NO_PROP);
2758 2779 }
2759 2780 if ((reqLen = strlcpy(propVal, diskLu->serialNum,
2760 2781 *propLen)) >= *propLen) {
2761 2782 *propLen = reqLen + 1;
2762 2783 return (STMF_ERROR_INVALID_ARG);
2763 2784 }
2764 2785 break;
2765 2786 case STMF_LU_PROP_SIZE:
2766 2787 if (diskLu->luSizeValid == B_FALSE) {
2767 2788 return (STMF_ERROR_NO_PROP);
2768 2789 }
2769 2790 (void) snprintf(propVal, *propLen, "%llu",
2770 2791 (u_longlong_t)diskLu->luSize);
2771 2792 break;
2772 2793 case STMF_LU_PROP_ALIAS:
2773 2794 if (diskLu->luAliasValid == B_FALSE) {
2774 2795 return (STMF_ERROR_NO_PROP);
2775 2796 }
2776 2797 if ((reqLen = strlcpy(propVal, diskLu->luAlias,
2777 2798 *propLen)) >= *propLen) {
2778 2799 *propLen = reqLen + 1;
2779 2800 return (STMF_ERROR_INVALID_ARG);
2780 2801 }
2781 2802 break;
2782 2803 case STMF_LU_PROP_VID:
2783 2804 if (diskLu->vidValid == B_FALSE) {
2784 2805 return (STMF_ERROR_NO_PROP);
2785 2806 }
2786 2807 if (*propLen <= sizeof (diskLu->vid)) {
2787 2808 return (STMF_ERROR_INVALID_ARG);
2788 2809 }
2789 2810 bcopy(diskLu->vid, propVal, sizeof (diskLu->vid));
2790 2811 propVal[sizeof (diskLu->vid)] = 0;
2791 2812 break;
2792 2813 case STMF_LU_PROP_PID:
2793 2814 if (diskLu->pidValid == B_FALSE) {
2794 2815 return (STMF_ERROR_NO_PROP);
2795 2816 }
2796 2817 if (*propLen <= sizeof (diskLu->pid)) {
2797 2818 return (STMF_ERROR_INVALID_ARG);
2798 2819 }
2799 2820 bcopy(diskLu->pid, propVal, sizeof (diskLu->pid));
2800 2821 propVal[sizeof (diskLu->pid)] = 0;
2801 2822 break;
2802 2823 case STMF_LU_PROP_WRITE_PROTECT:
2803 2824 if (diskLu->writeProtectEnableValid == B_FALSE) {
2804 2825 return (STMF_ERROR_NO_PROP);
2805 2826 }
2806 2827 if (diskLu->writeProtectEnable) {
2807 2828 if ((reqLen = strlcpy(propVal, "true",
2808 2829 *propLen)) >= *propLen) {
2809 2830 *propLen = reqLen + 1;
|
↓ open down ↓ |
454 lines elided |
↑ open up ↑ |
2810 2831 return (STMF_ERROR_INVALID_ARG);
2811 2832 }
2812 2833 } else {
2813 2834 if ((reqLen = strlcpy(propVal, "false",
2814 2835 *propLen)) >= *propLen) {
2815 2836 *propLen = reqLen + 1;
2816 2837 return (STMF_ERROR_INVALID_ARG);
2817 2838 }
2818 2839 }
2819 2840 break;
2841 + case STMF_LU_PROP_UNMAP:
2842 + if (!diskLu->unmapValid)
2843 + return (STMF_ERROR_NO_PROP);
2844 + if (diskLu->unmap) {
2845 + if ((reqLen = strlcpy(propVal, "true",
2846 + *propLen)) >= *propLen) {
2847 + *propLen = reqLen + 1;
2848 + return (STMF_ERROR_INVALID_ARG);
2849 + }
2850 + } else {
2851 + if ((reqLen = strlcpy(propVal, "false",
2852 + *propLen)) >= *propLen) {
2853 + *propLen = reqLen + 1;
2854 + return (STMF_ERROR_INVALID_ARG);
2855 + }
2856 + }
2857 + break;
2820 2858 case STMF_LU_PROP_WRITE_CACHE_DISABLE:
2821 2859 if (diskLu->writebackCacheDisableValid == B_FALSE) {
2822 2860 return (STMF_ERROR_NO_PROP);
2823 2861 }
2824 2862 if (diskLu->writebackCacheDisable) {
2825 2863 if ((reqLen = strlcpy(propVal, "true",
2826 2864 *propLen)) >= *propLen) {
2827 2865 *propLen = reqLen + 1;
2828 2866 return (STMF_ERROR_INVALID_ARG);
2829 2867 }
2830 2868 } else {
2831 2869 if ((reqLen = strlcpy(propVal, "false",
2832 2870 *propLen)) >= *propLen) {
2833 2871 *propLen = reqLen + 1;
2834 2872 return (STMF_ERROR_INVALID_ARG);
2835 2873 }
2836 2874 }
2837 2875 break;
2838 2876 default:
2839 2877 ret = STMF_ERROR_INVALID_PROP;
2840 2878 break;
2841 2879 }
2842 2880
2843 2881 return (ret);
2844 2882 }
2845 2883
2846 2884 /*
2847 2885 * setDiskProp
2848 2886 *
2849 2887 * Purpose: set properties for resource of type disk
2850 2888 *
2851 2889 * hdl - allocated luResourceImpl
2852 2890 * resourceProp - valid resource identifier
2853 2891 * propVal - valid resource value
2854 2892 */
2855 2893 static int
2856 2894 setDiskProp(luResourceImpl *hdl, uint32_t resourceProp, const char *propVal)
2857 2895 {
2858 2896 int ret = STMF_STATUS_SUCCESS;
2859 2897 int i;
2860 2898 diskResource *diskLu = hdl->resource;
2861 2899 unsigned long long numericProp = 0;
2862 2900 char guidProp[LU_ASCII_GUID_SIZE + 1];
2863 2901 char ouiProp[OUI_ASCII_SIZE + 1];
2864 2902 char hostIdProp[HOST_ID_ASCII_SIZE + 1];
2865 2903 unsigned int oui[OUI_SIZE];
2866 2904 unsigned int hostId[HOST_ID_SIZE];
2867 2905 unsigned int guid[LU_GUID_SIZE];
2868 2906 int propSize;
2869 2907
2870 2908
2871 2909 if (propVal == NULL) {
2872 2910 return (STMF_ERROR_INVALID_ARG);
2873 2911 }
2874 2912
2875 2913 switch (resourceProp) {
2876 2914 case STMF_LU_PROP_ALIAS:
2877 2915 if (strlcpy(diskLu->luAlias, propVal,
2878 2916 sizeof (diskLu->luAlias)) >=
2879 2917 sizeof (diskLu->luAlias)) {
2880 2918 return (STMF_ERROR_INVALID_PROPSIZE);
2881 2919 }
2882 2920 diskLu->luAliasValid = B_TRUE;
2883 2921 break;
2884 2922 case STMF_LU_PROP_BLOCK_SIZE: {
2885 2923 const char *tmp = propVal;
2886 2924 while (*tmp) {
2887 2925 if (!isdigit(*tmp++)) {
2888 2926 return (STMF_ERROR_INVALID_ARG);
2889 2927 }
2890 2928 }
2891 2929 (void) sscanf(propVal, "%llu", &numericProp);
2892 2930 if (numericProp > UINT16_MAX) {
2893 2931 return (STMF_ERROR_INVALID_PROPSIZE);
2894 2932 }
2895 2933 diskLu->blkSize = numericProp;
2896 2934 diskLu->blkSizeValid = B_TRUE;
2897 2935 break;
2898 2936 }
2899 2937 case STMF_LU_PROP_COMPANY_ID:
2900 2938 if ((strlcpy(ouiProp, propVal, sizeof (ouiProp))) >=
2901 2939 sizeof (ouiProp)) {
2902 2940 return (STMF_ERROR_INVALID_ARG);
2903 2941 }
2904 2942 if (checkHexUpper(ouiProp) != 0) {
2905 2943 return (STMF_ERROR_INVALID_ARG);
2906 2944 }
2907 2945 (void) sscanf(ouiProp, "%2X%2X%2X",
2908 2946 &oui[0], &oui[1], &oui[2]);
2909 2947
2910 2948 diskLu->companyId = 0;
2911 2949 diskLu->companyId += oui[0] << 16;
2912 2950 diskLu->companyId += oui[1] << 8;
2913 2951 diskLu->companyId += oui[2];
2914 2952 if (diskLu->companyId == 0) {
2915 2953 return (STMF_ERROR_INVALID_ARG);
2916 2954 }
2917 2955 diskLu->companyIdValid = B_TRUE;
2918 2956 break;
2919 2957 case STMF_LU_PROP_HOST_ID:
2920 2958 if ((strlcpy(hostIdProp, propVal,
2921 2959 sizeof (hostIdProp))) >= sizeof (hostIdProp)) {
2922 2960 return (STMF_ERROR_INVALID_ARG);
2923 2961 }
2924 2962 if (checkHexUpper(hostIdProp) != 0) {
2925 2963 return (STMF_ERROR_INVALID_ARG);
2926 2964 }
2927 2965 (void) sscanf(hostIdProp, "%2X%2X%2X%2X",
2928 2966 &hostId[0], &hostId[1], &hostId[2], &hostId[3]);
2929 2967
2930 2968 diskLu->hostId = 0;
2931 2969 diskLu->hostId += hostId[0] << 24;
2932 2970 diskLu->hostId += hostId[1] << 16;
2933 2971 diskLu->hostId += hostId[2] << 8;
2934 2972 diskLu->hostId += hostId[3];
2935 2973 if (diskLu->hostId == 0) {
2936 2974 return (STMF_ERROR_INVALID_ARG);
2937 2975 }
2938 2976 diskLu->hostIdValid = B_TRUE;
2939 2977 break;
2940 2978 case STMF_LU_PROP_GUID:
2941 2979 if (strlen(propVal) != LU_ASCII_GUID_SIZE) {
2942 2980 return (STMF_ERROR_INVALID_PROPSIZE);
2943 2981 }
2944 2982
2945 2983 if ((strlcpy(guidProp, propVal, sizeof (guidProp))) >=
2946 2984 sizeof (guidProp)) {
2947 2985 return (STMF_ERROR_INVALID_ARG);
2948 2986 }
2949 2987
2950 2988 if (checkHexUpper(guidProp) != 0) {
2951 2989 return (STMF_ERROR_INVALID_ARG);
2952 2990 }
2953 2991
2954 2992 (void) sscanf(guidProp,
2955 2993 "%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X%2X",
2956 2994 &guid[0], &guid[1], &guid[2], &guid[3], &guid[4],
2957 2995 &guid[5], &guid[6], &guid[7], &guid[8], &guid[9],
2958 2996 &guid[10], &guid[11], &guid[12], &guid[13],
2959 2997 &guid[14], &guid[15]);
2960 2998 for (i = 0; i < sizeof (diskLu->luGuid); i++) {
2961 2999 diskLu->luGuid[i] = guid[i];
2962 3000 }
2963 3001 diskLu->luGuidValid = B_TRUE;
2964 3002 break;
2965 3003 case STMF_LU_PROP_FILENAME:
2966 3004 if ((strlcpy(diskLu->luDataFileName, propVal,
2967 3005 sizeof (diskLu->luDataFileName))) >=
2968 3006 sizeof (diskLu->luDataFileName)) {
2969 3007 return (STMF_ERROR_INVALID_PROPSIZE);
2970 3008 }
2971 3009 diskLu->luDataFileNameValid = B_TRUE;
2972 3010 break;
2973 3011 case STMF_LU_PROP_META_FILENAME:
2974 3012 if ((strlcpy(diskLu->luMetaFileName, propVal,
2975 3013 sizeof (diskLu->luMetaFileName))) >=
2976 3014 sizeof (diskLu->luMetaFileName)) {
2977 3015 return (STMF_ERROR_INVALID_PROPSIZE);
2978 3016 }
2979 3017 diskLu->luMetaFileNameValid = B_TRUE;
2980 3018 break;
2981 3019 case STMF_LU_PROP_MGMT_URL:
2982 3020 if ((strlcpy(diskLu->luMgmtUrl, propVal,
2983 3021 sizeof (diskLu->luMgmtUrl))) >=
2984 3022 sizeof (diskLu->luMgmtUrl)) {
2985 3023 return (STMF_ERROR_INVALID_PROPSIZE);
2986 3024 }
2987 3025 diskLu->luMgmtUrlValid = B_TRUE;
2988 3026 break;
2989 3027 case STMF_LU_PROP_PID:
2990 3028 if ((propSize = strlen(propVal)) >
2991 3029 sizeof (diskLu->pid)) {
2992 3030 return (STMF_ERROR_INVALID_PROPSIZE);
2993 3031 }
2994 3032 (void) strncpy(diskLu->pid, propVal, propSize);
2995 3033 diskLu->pidValid = B_TRUE;
2996 3034 break;
2997 3035 case STMF_LU_PROP_SERIAL_NUM:
2998 3036 if ((propSize = strlen(propVal)) >
2999 3037 (sizeof (diskLu->serialNum) - 1)) {
3000 3038 return (STMF_ERROR_INVALID_PROPSIZE);
3001 3039 }
3002 3040 (void) strncpy(diskLu->serialNum, propVal, propSize);
3003 3041 diskLu->serialNumValid = B_TRUE;
3004 3042 break;
3005 3043 case STMF_LU_PROP_SIZE:
3006 3044 if ((niceStrToNum(propVal, &diskLu->luSize) != 0)) {
3007 3045 return (STMF_ERROR_INVALID_ARG);
3008 3046 }
3009 3047 diskLu->luSizeValid = B_TRUE;
3010 3048 break;
3011 3049 case STMF_LU_PROP_VID:
3012 3050 if ((propSize = strlen(propVal)) >
3013 3051 sizeof (diskLu->vid)) {
3014 3052 return (STMF_ERROR_INVALID_PROPSIZE);
3015 3053 }
3016 3054 (void) strncpy(diskLu->vid, propVal, propSize);
3017 3055 diskLu->vidValid = B_TRUE;
3018 3056 break;
3019 3057 case STMF_LU_PROP_WRITE_PROTECT:
3020 3058 if (strcasecmp(propVal, "TRUE") == 0) {
3021 3059 diskLu->writeProtectEnable = B_TRUE;
3022 3060 } else if (strcasecmp(propVal, "FALSE") == 0) {
3023 3061 diskLu->writeProtectEnable = B_FALSE;
3024 3062 } else {
3025 3063 return (STMF_ERROR_INVALID_ARG);
3026 3064 }
3027 3065 diskLu->writeProtectEnableValid = B_TRUE;
3028 3066 break;
|
↓ open down ↓ |
199 lines elided |
↑ open up ↑ |
3029 3067 case STMF_LU_PROP_WRITE_CACHE_DISABLE:
3030 3068 if (strcasecmp(propVal, "TRUE") == 0) {
3031 3069 diskLu->writebackCacheDisable = B_TRUE;
3032 3070 } else if (strcasecmp(propVal, "FALSE") == 0) {
3033 3071 diskLu->writebackCacheDisable = B_FALSE;
3034 3072 } else {
3035 3073 return (STMF_ERROR_INVALID_ARG);
3036 3074 }
3037 3075 diskLu->writebackCacheDisableValid = B_TRUE;
3038 3076 break;
3077 + case STMF_LU_PROP_UNMAP:
3078 + if (strcasecmp(propVal, "TRUE") == 0) {
3079 + diskLu->unmap = B_TRUE;
3080 + } else if (strcasecmp(propVal, "FALSE") == 0) {
3081 + diskLu->unmap = B_FALSE;
3082 + } else {
3083 + return (STMF_ERROR_INVALID_ARG);
3084 + }
3085 + diskLu->unmapValid = B_TRUE;
3086 + break;
3039 3087 case STMF_LU_PROP_ACCESS_STATE:
3040 3088 ret = STMF_ERROR_INVALID_PROP;
3041 3089 break;
3042 3090 default:
3043 3091 ret = STMF_ERROR_INVALID_PROP;
3044 3092 break;
3045 3093 }
3046 3094 return (ret);
3047 3095 }
3048 3096
3049 3097 static int
3050 3098 checkHexUpper(char *buf)
3051 3099 {
3052 3100 int i;
3053 3101
3054 3102 for (i = 0; i < strlen(buf); i++) {
3055 3103 if (isxdigit(buf[i])) {
3056 3104 buf[i] = toupper(buf[i]);
3057 3105 continue;
3058 3106 }
3059 3107 return (-1);
3060 3108 }
3061 3109
3062 3110 return (0);
3063 3111 }
3064 3112
3065 3113 /*
3066 3114 * Given a numeric suffix, convert the value into a number of bits that the
3067 3115 * resulting value must be shifted.
3068 3116 * Code lifted from libzfs_util.c
3069 3117 */
3070 3118 static int
3071 3119 strToShift(const char *buf)
3072 3120 {
3073 3121 const char *ends = "BKMGTPE";
3074 3122 int i;
3075 3123
3076 3124 if (buf[0] == '\0')
3077 3125 return (0);
3078 3126
3079 3127 for (i = 0; i < strlen(ends); i++) {
3080 3128 if (toupper(buf[0]) == ends[i])
3081 3129 return (10*i);
3082 3130 }
3083 3131
3084 3132 return (-1);
3085 3133 }
3086 3134
3087 3135 int
3088 3136 stmfFreeLuResource(luResource hdl)
3089 3137 {
3090 3138 int ret = STMF_STATUS_SUCCESS;
3091 3139 if (hdl == NULL) {
3092 3140 return (STMF_ERROR_INVALID_ARG);
3093 3141 }
3094 3142
3095 3143 luResourceImpl *hdlImpl = hdl;
3096 3144 free(hdlImpl->resource);
3097 3145 free(hdlImpl);
3098 3146 return (ret);
3099 3147 }
3100 3148
3101 3149 /*
3102 3150 * Convert a string of the form '100G' into a real number. Used when setting
3103 3151 * the size of a logical unit.
3104 3152 * Code lifted from libzfs_util.c
3105 3153 */
3106 3154 static int
3107 3155 niceStrToNum(const char *value, uint64_t *num)
3108 3156 {
3109 3157 char *end;
3110 3158 int shift;
3111 3159
3112 3160 *num = 0;
3113 3161
3114 3162 /* Check to see if this looks like a number. */
3115 3163 if ((value[0] < '0' || value[0] > '9') && value[0] != '.') {
3116 3164 return (-1);
3117 3165 }
3118 3166
3119 3167 /* Rely on stroull() to process the numeric portion. */
3120 3168 errno = 0;
3121 3169 *num = strtoull(value, &end, 10);
3122 3170
3123 3171 /*
3124 3172 * Check for ERANGE, which indicates that the value is too large to fit
3125 3173 * in a 64-bit value.
3126 3174 */
3127 3175 if (errno == ERANGE) {
3128 3176 return (-1);
3129 3177 }
3130 3178
3131 3179 /*
3132 3180 * If we have a decimal value, then do the computation with floating
3133 3181 * point arithmetic. Otherwise, use standard arithmetic.
3134 3182 */
3135 3183 if (*end == '.') {
3136 3184 double fval = strtod(value, &end);
3137 3185
3138 3186 if ((shift = strToShift(end)) == -1) {
3139 3187 return (-1);
3140 3188 }
3141 3189
3142 3190 fval *= pow(2, shift);
3143 3191
3144 3192 if (fval > UINT64_MAX) {
3145 3193 return (-1);
3146 3194 }
3147 3195
3148 3196 *num = (uint64_t)fval;
3149 3197 } else {
3150 3198 if ((shift = strToShift(end)) == -1) {
3151 3199 return (-1);
3152 3200 }
3153 3201
3154 3202 /* Check for overflow */
3155 3203 if (shift >= 64 || (*num << shift) >> shift != *num) {
3156 3204 return (-1);
3157 3205 }
3158 3206
3159 3207 *num <<= shift;
3160 3208 }
3161 3209
3162 3210 return (0);
3163 3211 }
3164 3212
3165 3213 /*
3166 3214 * stmfCreateTargetGroup
3167 3215 *
3168 3216 * Purpose: Create a local port group
3169 3217 *
3170 3218 * targetGroupName - name of local port group to create
3171 3219 */
3172 3220 int
3173 3221 stmfCreateTargetGroup(stmfGroupName *targetGroupName)
3174 3222 {
3175 3223 int ret;
3176 3224 int fd;
3177 3225
3178 3226 if (targetGroupName == NULL ||
3179 3227 (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
3180 3228 == sizeof (stmfGroupName))) {
3181 3229 return (STMF_ERROR_INVALID_ARG);
3182 3230 }
3183 3231
3184 3232 /* Check to ensure service exists */
3185 3233 if (psCheckService() != STMF_STATUS_SUCCESS) {
3186 3234 return (STMF_ERROR_SERVICE_NOT_FOUND);
3187 3235 }
3188 3236
3189 3237 /* call init */
3190 3238 ret = initializeConfig();
3191 3239 if (ret != STMF_STATUS_SUCCESS) {
3192 3240 return (ret);
3193 3241 }
3194 3242
3195 3243 /*
3196 3244 * Open control node for stmf
3197 3245 */
3198 3246 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3199 3247 return (ret);
3200 3248
3201 3249 /*
3202 3250 * Add the group to the driver
3203 3251 */
3204 3252 if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
3205 3253 targetGroupName)) != STMF_STATUS_SUCCESS) {
3206 3254 goto done;
3207 3255 }
3208 3256
3209 3257 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3210 3258 goto done;
3211 3259 }
3212 3260
3213 3261 /*
3214 3262 * If the add to the driver was successful, add it to the persistent
3215 3263 * store.
3216 3264 */
3217 3265 ret = psCreateTargetGroup((char *)targetGroupName);
3218 3266 switch (ret) {
3219 3267 case STMF_PS_SUCCESS:
3220 3268 ret = STMF_STATUS_SUCCESS;
3221 3269 break;
3222 3270 case STMF_PS_ERROR_EXISTS:
3223 3271 ret = STMF_ERROR_EXISTS;
3224 3272 break;
3225 3273 case STMF_PS_ERROR_BUSY:
3226 3274 ret = STMF_ERROR_BUSY;
3227 3275 break;
3228 3276 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3229 3277 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3230 3278 break;
3231 3279 case STMF_PS_ERROR_VERSION_MISMATCH:
3232 3280 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3233 3281 break;
3234 3282 default:
3235 3283 syslog(LOG_DEBUG,
3236 3284 "stmfCreateTargetGroup:psCreateTargetGroup"
3237 3285 ":error(%d)", ret);
3238 3286 ret = STMF_STATUS_ERROR;
3239 3287 break;
3240 3288 }
3241 3289
3242 3290 done:
3243 3291 (void) close(fd);
3244 3292 return (ret);
3245 3293 }
3246 3294
3247 3295 /*
3248 3296 * stmfDeleteHostGroup
3249 3297 *
3250 3298 * Purpose: Delete an initiator or local port group
3251 3299 *
3252 3300 * hostGroupName - group to delete
3253 3301 */
3254 3302 int
3255 3303 stmfDeleteHostGroup(stmfGroupName *hostGroupName)
3256 3304 {
3257 3305 int ret;
3258 3306 int fd;
3259 3307
3260 3308 if (hostGroupName == NULL) {
3261 3309 return (STMF_ERROR_INVALID_ARG);
3262 3310 }
3263 3311
3264 3312 /* Check to ensure service exists */
3265 3313 if (psCheckService() != STMF_STATUS_SUCCESS) {
3266 3314 return (STMF_ERROR_SERVICE_NOT_FOUND);
3267 3315 }
3268 3316
3269 3317 /* call init */
3270 3318 ret = initializeConfig();
3271 3319 if (ret != STMF_STATUS_SUCCESS) {
3272 3320 return (ret);
3273 3321 }
3274 3322
3275 3323 /*
3276 3324 * Open control node for stmf
3277 3325 */
3278 3326 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3279 3327 return (ret);
3280 3328
3281 3329 /*
3282 3330 * Remove the group from the driver
3283 3331 */
3284 3332 if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_HOST_GROUP,
3285 3333 hostGroupName)) != STMF_STATUS_SUCCESS) {
3286 3334 goto done;
3287 3335 }
3288 3336
3289 3337 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3290 3338 goto done;
3291 3339 }
3292 3340
3293 3341 /*
3294 3342 * If the remove from the driver was successful, remove it from the
3295 3343 * persistent store.
3296 3344 */
3297 3345 ret = psDeleteHostGroup((char *)hostGroupName);
3298 3346 switch (ret) {
3299 3347 case STMF_PS_SUCCESS:
3300 3348 ret = STMF_STATUS_SUCCESS;
3301 3349 break;
3302 3350 case STMF_PS_ERROR_NOT_FOUND:
3303 3351 ret = STMF_ERROR_NOT_FOUND;
3304 3352 break;
3305 3353 case STMF_PS_ERROR_BUSY:
3306 3354 ret = STMF_ERROR_BUSY;
3307 3355 break;
3308 3356 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3309 3357 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3310 3358 break;
3311 3359 case STMF_PS_ERROR_VERSION_MISMATCH:
3312 3360 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3313 3361 break;
3314 3362 default:
3315 3363 syslog(LOG_DEBUG,
3316 3364 "stmfDeleteHostGroup:psDeleteHostGroup:error(%d)",
3317 3365 ret);
3318 3366 ret = STMF_STATUS_ERROR;
3319 3367 break;
3320 3368 }
3321 3369
3322 3370 done:
3323 3371 (void) close(fd);
3324 3372 return (ret);
3325 3373 }
3326 3374
3327 3375 /*
3328 3376 * stmfDeleteTargetGroup
3329 3377 *
3330 3378 * Purpose: Delete an initiator or local port group
3331 3379 *
3332 3380 * targetGroupName - group to delete
3333 3381 */
3334 3382 int
3335 3383 stmfDeleteTargetGroup(stmfGroupName *targetGroupName)
3336 3384 {
3337 3385 int ret = STMF_STATUS_SUCCESS;
3338 3386 int fd;
3339 3387
3340 3388 if (targetGroupName == NULL) {
3341 3389 return (STMF_ERROR_INVALID_ARG);
3342 3390 }
3343 3391
3344 3392 /* Check to ensure service exists */
3345 3393 if (psCheckService() != STMF_STATUS_SUCCESS) {
3346 3394 return (STMF_ERROR_SERVICE_NOT_FOUND);
3347 3395 }
3348 3396
3349 3397 /* call init */
3350 3398 ret = initializeConfig();
3351 3399 if (ret != STMF_STATUS_SUCCESS) {
3352 3400 return (ret);
3353 3401 }
3354 3402
3355 3403 /*
3356 3404 * Open control node for stmf
3357 3405 */
3358 3406 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3359 3407 return (ret);
3360 3408
3361 3409 /*
3362 3410 * Remove the group from the driver
3363 3411 */
3364 3412 if ((ret = groupIoctl(fd, STMF_IOCTL_REMOVE_TARGET_GROUP,
3365 3413 targetGroupName)) != STMF_STATUS_SUCCESS) {
3366 3414 goto done;
3367 3415 }
3368 3416
3369 3417 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
3370 3418 goto done;
3371 3419 }
3372 3420
3373 3421 /*
3374 3422 * If the remove from the driver was successful, remove it from the
3375 3423 * persistent store.
3376 3424 */
3377 3425 ret = psDeleteTargetGroup((char *)targetGroupName);
3378 3426 switch (ret) {
3379 3427 case STMF_PS_SUCCESS:
3380 3428 ret = STMF_STATUS_SUCCESS;
3381 3429 break;
3382 3430 case STMF_PS_ERROR_NOT_FOUND:
3383 3431 ret = STMF_ERROR_NOT_FOUND;
3384 3432 break;
3385 3433 case STMF_PS_ERROR_BUSY:
3386 3434 ret = STMF_ERROR_BUSY;
3387 3435 break;
3388 3436 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3389 3437 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3390 3438 break;
3391 3439 case STMF_PS_ERROR_VERSION_MISMATCH:
3392 3440 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3393 3441 break;
3394 3442 default:
3395 3443 syslog(LOG_DEBUG,
3396 3444 "stmfDeleteTargetGroup:psDeleteTargetGroup"
3397 3445 ":error(%d)", ret);
3398 3446 ret = STMF_STATUS_ERROR;
3399 3447 break;
3400 3448 }
3401 3449
3402 3450 done:
3403 3451 (void) close(fd);
3404 3452 return (ret);
3405 3453 }
3406 3454
3407 3455 /*
3408 3456 * stmfDevidFromIscsiName
3409 3457 *
3410 3458 * Purpose: convert an iSCSI name to an stmf devid
3411 3459 *
3412 3460 * iscsiName - unicode nul terminated utf-8 encoded iSCSI name
3413 3461 * devid - on success, contains the converted iscsi name
3414 3462 */
3415 3463 int
3416 3464 stmfDevidFromIscsiName(char *iscsiName, stmfDevid *devid)
3417 3465 {
3418 3466 if (devid == NULL || iscsiName == NULL)
3419 3467 return (STMF_ERROR_INVALID_ARG);
3420 3468
3421 3469 bzero(devid, sizeof (stmfDevid));
3422 3470
3423 3471 /* Validate size of target */
3424 3472 if ((devid->identLength = strlen(iscsiName)) > MAX_ISCSI_NAME ||
3425 3473 devid->identLength < strlen(EUI) ||
3426 3474 devid->identLength < strlen(IQN)) {
3427 3475 return (STMF_ERROR_INVALID_ARG);
3428 3476 }
3429 3477
3430 3478 if ((strncmp(iscsiName, EUI, strlen(EUI)) != 0) &&
3431 3479 strncmp(iscsiName, IQN, strlen(IQN)) != 0) {
3432 3480 return (STMF_ERROR_INVALID_ARG);
3433 3481 }
3434 3482
3435 3483 /* copy UTF-8 bytes to ident */
3436 3484 bcopy(iscsiName, devid->ident, devid->identLength);
3437 3485
3438 3486 return (STMF_STATUS_SUCCESS);
3439 3487 }
3440 3488
3441 3489 /*
3442 3490 * stmfDevidFromWwn
3443 3491 *
3444 3492 * Purpose: convert a WWN to an stmf devid
3445 3493 *
3446 3494 * wwn - 8-byte wwn identifier
3447 3495 * devid - on success, contains the converted wwn
3448 3496 */
3449 3497 int
3450 3498 stmfDevidFromWwn(uchar_t *wwn, stmfDevid *devid)
3451 3499 {
3452 3500 if (wwn == NULL || devid == NULL)
3453 3501 return (STMF_ERROR_INVALID_ARG);
3454 3502
3455 3503 bzero(devid, sizeof (stmfDevid));
3456 3504
3457 3505 /* Copy eui prefix */
3458 3506 (void) bcopy(WWN, devid->ident, strlen(WWN));
3459 3507
3460 3508 /* Convert to ASCII uppercase hexadecimal string */
3461 3509 (void) snprintf((char *)&devid->ident[strlen(WWN)],
3462 3510 sizeof (devid->ident), "%02X%02X%02X%02X%02X%02X%02X%02X",
3463 3511 wwn[0], wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
3464 3512
3465 3513 devid->identLength = strlen((char *)devid->ident);
3466 3514
3467 3515 return (STMF_STATUS_SUCCESS);
3468 3516 }
3469 3517
3470 3518 /*
3471 3519 * stmfFreeMemory
3472 3520 *
3473 3521 * Purpose: Free memory allocated by this library
3474 3522 *
3475 3523 * memory - previously allocated pointer of memory managed by library
3476 3524 */
3477 3525 void
3478 3526 stmfFreeMemory(void *memory)
3479 3527 {
3480 3528 free(memory);
3481 3529 }
3482 3530
3483 3531 /*
3484 3532 * get host group, target group list from stmf
3485 3533 *
3486 3534 * groupType - HOST_GROUP, TARGET_GROUP
3487 3535 */
3488 3536 static int
3489 3537 groupListIoctl(stmfGroupList **groupList, int groupType)
3490 3538 {
3491 3539 int ret;
3492 3540 int fd;
3493 3541 int ioctlRet;
3494 3542 int i;
3495 3543 int cmd;
3496 3544 stmf_iocdata_t stmfIoctl;
3497 3545 /* framework group list */
3498 3546 stmf_group_name_t *iGroupList = NULL;
3499 3547 uint32_t groupListSize;
3500 3548
3501 3549 if (groupList == NULL) {
3502 3550 return (STMF_ERROR_INVALID_ARG);
3503 3551 }
3504 3552
3505 3553 if (groupType == HOST_GROUP) {
3506 3554 cmd = STMF_IOCTL_GET_HG_LIST;
3507 3555 } else if (groupType == TARGET_GROUP) {
3508 3556 cmd = STMF_IOCTL_GET_TG_LIST;
3509 3557 } else {
3510 3558 return (STMF_ERROR_INVALID_ARG);
3511 3559 }
3512 3560
3513 3561 /* call init */
3514 3562 ret = initializeConfig();
3515 3563 if (ret != STMF_STATUS_SUCCESS) {
3516 3564 return (ret);
3517 3565 }
3518 3566
3519 3567 /*
3520 3568 * Open control node for stmf
3521 3569 */
3522 3570 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3523 3571 return (ret);
3524 3572
3525 3573 /*
3526 3574 * Allocate ioctl input buffer
3527 3575 */
3528 3576 groupListSize = ALLOC_GROUP;
3529 3577 groupListSize = groupListSize * (sizeof (stmf_group_name_t));
3530 3578 iGroupList = (stmf_group_name_t *)calloc(1, groupListSize);
3531 3579 if (iGroupList == NULL) {
3532 3580 ret = STMF_ERROR_NOMEM;
3533 3581 goto done;
3534 3582 }
3535 3583
3536 3584 bzero(&stmfIoctl, sizeof (stmfIoctl));
3537 3585 /*
3538 3586 * Issue ioctl to get the group list
3539 3587 */
3540 3588 stmfIoctl.stmf_version = STMF_VERSION_1;
3541 3589 stmfIoctl.stmf_obuf_size = groupListSize;
3542 3590 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3543 3591 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3544 3592 if (ioctlRet != 0) {
3545 3593 switch (errno) {
3546 3594 case EBUSY:
3547 3595 ret = STMF_ERROR_BUSY;
3548 3596 break;
3549 3597 case EPERM:
3550 3598 case EACCES:
3551 3599 ret = STMF_ERROR_PERM;
3552 3600 break;
3553 3601 default:
3554 3602 syslog(LOG_DEBUG,
3555 3603 "groupListIoctl:ioctl errno(%d)",
3556 3604 errno);
3557 3605 ret = STMF_STATUS_ERROR;
3558 3606 break;
3559 3607 }
3560 3608 goto done;
3561 3609 }
3562 3610 /*
3563 3611 * Check whether input buffer was large enough
3564 3612 */
3565 3613 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GROUP) {
3566 3614 groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3567 3615 sizeof (stmf_group_name_t);
3568 3616 iGroupList = realloc(iGroupList, groupListSize);
3569 3617 if (iGroupList == NULL) {
3570 3618 ret = STMF_ERROR_NOMEM;
3571 3619 goto done;
3572 3620 }
3573 3621 stmfIoctl.stmf_obuf_size = groupListSize;
3574 3622 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupList;
3575 3623 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3576 3624 if (ioctlRet != 0) {
3577 3625 switch (errno) {
3578 3626 case EBUSY:
3579 3627 ret = STMF_ERROR_BUSY;
3580 3628 break;
3581 3629 case EPERM:
3582 3630 case EACCES:
3583 3631 ret = STMF_ERROR_PERM;
3584 3632 break;
3585 3633 default:
3586 3634 syslog(LOG_DEBUG,
3587 3635 "groupListIoctl:ioctl errno(%d)",
3588 3636 errno);
3589 3637 ret = STMF_STATUS_ERROR;
3590 3638 break;
3591 3639 }
3592 3640 goto done;
3593 3641 }
3594 3642 }
3595 3643
3596 3644 /* allocate and copy to caller's buffer */
3597 3645 *groupList = (stmfGroupList *)calloc(1, sizeof (stmfGroupList) +
3598 3646 sizeof (stmfGroupName) * stmfIoctl.stmf_obuf_nentries);
3599 3647 if (*groupList == NULL) {
3600 3648 ret = STMF_ERROR_NOMEM;
3601 3649 goto done;
3602 3650 }
3603 3651 (*groupList)->cnt = stmfIoctl.stmf_obuf_nentries;
3604 3652 for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3605 3653 bcopy(iGroupList[i].name, (*groupList)->name[i],
3606 3654 sizeof (stmfGroupName));
3607 3655 }
3608 3656
3609 3657 done:
3610 3658 free(iGroupList);
3611 3659 (void) close(fd);
3612 3660 return (ret);
3613 3661 }
3614 3662
3615 3663 /*
3616 3664 * get host group members, target group members from stmf
3617 3665 *
3618 3666 * groupProps - allocated on success
3619 3667 *
3620 3668 * groupType - HOST_GROUP, TARGET_GROUP
3621 3669 */
3622 3670 static int
3623 3671 groupMemberListIoctl(stmfGroupName *groupName, stmfGroupProperties **groupProps,
3624 3672 int groupType)
3625 3673 {
3626 3674 int ret;
3627 3675 int fd;
3628 3676 int ioctlRet;
3629 3677 int i;
3630 3678 int cmd;
3631 3679 stmf_iocdata_t stmfIoctl;
3632 3680 /* framework group list */
3633 3681 stmf_group_name_t iGroupName;
3634 3682 stmf_ge_ident_t *iGroupMembers;
3635 3683 uint32_t groupListSize;
3636 3684
3637 3685 if (groupName == NULL) {
3638 3686 return (STMF_ERROR_INVALID_ARG);
3639 3687 }
3640 3688
3641 3689 if (groupType == HOST_GROUP) {
3642 3690 cmd = STMF_IOCTL_GET_HG_ENTRIES;
3643 3691 } else if (groupType == TARGET_GROUP) {
3644 3692 cmd = STMF_IOCTL_GET_TG_ENTRIES;
3645 3693 } else {
3646 3694 return (STMF_ERROR_INVALID_ARG);
3647 3695 }
3648 3696
3649 3697 /* call init */
3650 3698 ret = initializeConfig();
3651 3699 if (ret != STMF_STATUS_SUCCESS) {
3652 3700 return (ret);
3653 3701 }
3654 3702
3655 3703 /*
3656 3704 * Open control node for stmf
3657 3705 */
3658 3706 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
3659 3707 return (ret);
3660 3708
3661 3709 bzero(&iGroupName, sizeof (iGroupName));
3662 3710
3663 3711 bcopy(groupName, &iGroupName.name, strlen((char *)groupName));
3664 3712
3665 3713 iGroupName.name_size = strlen((char *)groupName);
3666 3714
3667 3715 /*
3668 3716 * Allocate ioctl input buffer
3669 3717 */
3670 3718 groupListSize = ALLOC_GRP_MEMBER;
3671 3719 groupListSize = groupListSize * (sizeof (stmf_ge_ident_t));
3672 3720 iGroupMembers = (stmf_ge_ident_t *)calloc(1, groupListSize);
3673 3721 if (iGroupMembers == NULL) {
3674 3722 ret = STMF_ERROR_NOMEM;
3675 3723 goto done;
3676 3724 }
3677 3725
3678 3726 bzero(&stmfIoctl, sizeof (stmfIoctl));
3679 3727 /*
3680 3728 * Issue ioctl to get the group list
3681 3729 */
3682 3730 stmfIoctl.stmf_version = STMF_VERSION_1;
3683 3731 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3684 3732 stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3685 3733 stmfIoctl.stmf_obuf_size = groupListSize;
3686 3734 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3687 3735 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3688 3736 if (ioctlRet != 0) {
3689 3737 switch (errno) {
3690 3738 case EBUSY:
3691 3739 ret = STMF_ERROR_BUSY;
3692 3740 break;
3693 3741 case EPERM:
3694 3742 case EACCES:
3695 3743 ret = STMF_ERROR_PERM;
3696 3744 break;
3697 3745 default:
3698 3746 syslog(LOG_DEBUG,
3699 3747 "groupListIoctl:ioctl errno(%d)",
3700 3748 errno);
3701 3749 ret = STMF_STATUS_ERROR;
3702 3750 break;
3703 3751 }
3704 3752 goto done;
3705 3753 }
3706 3754 /*
3707 3755 * Check whether input buffer was large enough
3708 3756 */
3709 3757 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_GRP_MEMBER) {
3710 3758 groupListSize = stmfIoctl.stmf_obuf_max_nentries *
3711 3759 sizeof (stmf_ge_ident_t);
3712 3760 iGroupMembers = realloc(iGroupMembers, groupListSize);
3713 3761 if (iGroupMembers == NULL) {
3714 3762 ret = STMF_ERROR_NOMEM;
3715 3763 goto done;
3716 3764 }
3717 3765 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&iGroupName;
3718 3766 stmfIoctl.stmf_ibuf_size = sizeof (stmf_group_name_t);
3719 3767 stmfIoctl.stmf_obuf_size = groupListSize;
3720 3768 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)iGroupMembers;
3721 3769 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
3722 3770 if (ioctlRet != 0) {
3723 3771 switch (errno) {
3724 3772 case EBUSY:
3725 3773 ret = STMF_ERROR_BUSY;
3726 3774 break;
3727 3775 case EPERM:
3728 3776 case EACCES:
3729 3777 ret = STMF_ERROR_PERM;
3730 3778 break;
3731 3779 default:
3732 3780 syslog(LOG_DEBUG,
3733 3781 "groupListIoctl:ioctl errno(%d)",
3734 3782 errno);
3735 3783 ret = STMF_STATUS_ERROR;
3736 3784 break;
3737 3785 }
3738 3786 goto done;
3739 3787 }
3740 3788 }
3741 3789
3742 3790 /* allocate and copy to caller's buffer */
3743 3791 *groupProps = (stmfGroupProperties *)calloc(1,
3744 3792 sizeof (stmfGroupProperties) +
3745 3793 sizeof (stmfDevid) * stmfIoctl.stmf_obuf_nentries);
3746 3794 if (*groupProps == NULL) {
3747 3795 ret = STMF_ERROR_NOMEM;
3748 3796 goto done;
3749 3797 }
3750 3798 (*groupProps)->cnt = stmfIoctl.stmf_obuf_nentries;
3751 3799 for (i = 0; i < stmfIoctl.stmf_obuf_nentries; i++) {
3752 3800 (*groupProps)->name[i].identLength =
3753 3801 iGroupMembers[i].ident_size;
3754 3802 bcopy(iGroupMembers[i].ident, (*groupProps)->name[i].ident,
3755 3803 iGroupMembers[i].ident_size);
3756 3804 }
3757 3805
3758 3806 done:
3759 3807 free(iGroupMembers);
3760 3808 (void) close(fd);
3761 3809 return (ret);
3762 3810 }
3763 3811
3764 3812 /*
3765 3813 * Purpose: access persistent config data for host groups and target groups
3766 3814 */
3767 3815 static int
3768 3816 iLoadGroupFromPs(stmfGroupList **groupList, int type)
3769 3817 {
3770 3818 int ret;
3771 3819
3772 3820 if (groupList == NULL) {
3773 3821 return (STMF_ERROR_INVALID_ARG);
3774 3822 }
3775 3823
3776 3824 if (type == HOST_GROUP) {
3777 3825 ret = psGetHostGroupList(groupList);
3778 3826 } else if (type == TARGET_GROUP) {
3779 3827 ret = psGetTargetGroupList(groupList);
3780 3828 } else {
3781 3829 return (STMF_ERROR_INVALID_ARG);
3782 3830 }
3783 3831 switch (ret) {
3784 3832 case STMF_PS_SUCCESS:
3785 3833 ret = STMF_STATUS_SUCCESS;
3786 3834 break;
3787 3835 case STMF_PS_ERROR_NOT_FOUND:
3788 3836 ret = STMF_ERROR_NOT_FOUND;
3789 3837 break;
3790 3838 case STMF_PS_ERROR_BUSY:
3791 3839 ret = STMF_ERROR_BUSY;
3792 3840 break;
3793 3841 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3794 3842 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3795 3843 break;
3796 3844 case STMF_PS_ERROR_VERSION_MISMATCH:
3797 3845 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3798 3846 break;
3799 3847 default:
3800 3848 syslog(LOG_DEBUG,
3801 3849 "stmfGetHostGroupList:psGetHostGroupList:error(%d)",
3802 3850 ret);
3803 3851 ret = STMF_STATUS_ERROR;
3804 3852 break;
3805 3853 }
3806 3854
3807 3855 return (ret);
3808 3856 }
3809 3857
3810 3858 /*
3811 3859 * stmfGetHostGroupList
3812 3860 *
3813 3861 * Purpose: Retrieves the list of initiator group oids
3814 3862 *
3815 3863 * hostGroupList - pointer to pointer to hostGroupList structure
3816 3864 * on success, this contains the host group list.
3817 3865 */
3818 3866 int
3819 3867 stmfGetHostGroupList(stmfGroupList **hostGroupList)
3820 3868 {
3821 3869 int ret = STMF_STATUS_ERROR;
3822 3870
3823 3871 if (hostGroupList == NULL) {
3824 3872 return (STMF_ERROR_INVALID_ARG);
3825 3873 }
3826 3874
3827 3875 ret = groupListIoctl(hostGroupList, HOST_GROUP);
3828 3876 return (ret);
3829 3877 }
3830 3878
3831 3879
3832 3880 /*
3833 3881 * Purpose: access persistent config data for host groups and target groups
3834 3882 */
3835 3883 static int
3836 3884 iLoadGroupMembersFromPs(stmfGroupName *groupName,
3837 3885 stmfGroupProperties **groupProp, int type)
3838 3886 {
3839 3887 int ret;
3840 3888
3841 3889 if (groupName == NULL) {
3842 3890 return (STMF_ERROR_INVALID_ARG);
3843 3891 }
3844 3892
3845 3893 if (type == HOST_GROUP) {
3846 3894 ret = psGetHostGroupMemberList((char *)groupName, groupProp);
3847 3895 } else if (type == TARGET_GROUP) {
3848 3896 ret = psGetTargetGroupMemberList((char *)groupName, groupProp);
3849 3897 } else {
3850 3898 return (STMF_ERROR_INVALID_ARG);
3851 3899 }
3852 3900 switch (ret) {
3853 3901 case STMF_PS_SUCCESS:
3854 3902 ret = STMF_STATUS_SUCCESS;
3855 3903 break;
3856 3904 case STMF_PS_ERROR_NOT_FOUND:
3857 3905 ret = STMF_ERROR_NOT_FOUND;
3858 3906 break;
3859 3907 case STMF_PS_ERROR_BUSY:
3860 3908 ret = STMF_ERROR_BUSY;
3861 3909 break;
3862 3910 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3863 3911 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3864 3912 break;
3865 3913 case STMF_PS_ERROR_VERSION_MISMATCH:
3866 3914 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3867 3915 break;
3868 3916 default:
3869 3917 syslog(LOG_DEBUG,
3870 3918 "iLoadGroupMembersFromPs:psGetHostGroupList:"
3871 3919 "error(%d)", ret);
3872 3920 ret = STMF_STATUS_ERROR;
3873 3921 break;
3874 3922 }
3875 3923
3876 3924 return (ret);
3877 3925 }
3878 3926
3879 3927 /*
3880 3928 * stmfGetHostGroupMembers
3881 3929 *
3882 3930 * Purpose: Retrieves the group properties for a host group
3883 3931 *
3884 3932 * groupName - name of group for which to retrieve host group members.
3885 3933 * groupProp - pointer to pointer to stmfGroupProperties structure
3886 3934 * on success, this contains the list of group members.
3887 3935 */
3888 3936 int
3889 3937 stmfGetHostGroupMembers(stmfGroupName *groupName,
3890 3938 stmfGroupProperties **groupProp)
3891 3939 {
3892 3940 int ret;
3893 3941
3894 3942 if (groupName == NULL || groupProp == NULL) {
3895 3943 return (STMF_ERROR_INVALID_ARG);
3896 3944 }
3897 3945
3898 3946 ret = groupMemberListIoctl(groupName, groupProp, HOST_GROUP);
3899 3947
3900 3948 return (ret);
3901 3949 }
3902 3950
3903 3951 /*
3904 3952 * stmfGetProviderData
3905 3953 *
3906 3954 * Purpose: Get provider data list
3907 3955 *
3908 3956 * providerName - name of provider for which to retrieve the data
3909 3957 * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3910 3958 * retrieved.
3911 3959 * providerType - type of provider for which to retrieve data.
3912 3960 * STMF_LU_PROVIDER_TYPE
3913 3961 * STMF_PORT_PROVIDER_TYPE
3914 3962 */
3915 3963 int
3916 3964 stmfGetProviderData(char *providerName, nvlist_t **nvl, int providerType)
3917 3965 {
3918 3966 return (stmfGetProviderDataProt(providerName, nvl, providerType,
3919 3967 NULL));
3920 3968 }
3921 3969
3922 3970 /*
3923 3971 * stmfGetProviderDataProt
3924 3972 *
3925 3973 * Purpose: Get provider data list with token
3926 3974 *
3927 3975 * providerName - name of provider for which to retrieve the data
3928 3976 * nvl - pointer to nvlist_t pointer which will contain the nvlist data
3929 3977 * retrieved.
3930 3978 * providerType - type of provider for which to retrieve data.
3931 3979 * STMF_LU_PROVIDER_TYPE
3932 3980 * STMF_PORT_PROVIDER_TYPE
3933 3981 * setToken - Returns the stale data token
3934 3982 */
3935 3983 int
3936 3984 stmfGetProviderDataProt(char *providerName, nvlist_t **nvl, int providerType,
3937 3985 uint64_t *setToken)
3938 3986 {
3939 3987 int ret;
3940 3988
3941 3989 if (providerName == NULL || nvl == NULL) {
3942 3990 return (STMF_ERROR_INVALID_ARG);
3943 3991 }
3944 3992 if (providerType != STMF_LU_PROVIDER_TYPE &&
3945 3993 providerType != STMF_PORT_PROVIDER_TYPE) {
3946 3994 return (STMF_ERROR_INVALID_ARG);
3947 3995 }
3948 3996 /* call init */
3949 3997 ret = initializeConfig();
3950 3998 if (ret != STMF_STATUS_SUCCESS) {
3951 3999 return (ret);
3952 4000 }
3953 4001 return (getProviderData(providerName, nvl, providerType, setToken));
3954 4002 }
3955 4003
3956 4004 /*
3957 4005 * stmfGetProviderDataList
3958 4006 *
3959 4007 * Purpose: Get the list of providers currently persisting data
3960 4008 *
3961 4009 * providerList - pointer to pointer to an stmfProviderList structure allocated
3962 4010 * by the caller. Will contain the list of providers on success.
3963 4011 */
3964 4012 int
3965 4013 stmfGetProviderDataList(stmfProviderList **providerList)
3966 4014 {
3967 4015 int ret;
3968 4016
3969 4017 ret = psGetProviderDataList(providerList);
3970 4018 switch (ret) {
3971 4019 case STMF_PS_SUCCESS:
3972 4020 ret = STMF_STATUS_SUCCESS;
3973 4021 break;
3974 4022 case STMF_PS_ERROR_BUSY:
3975 4023 ret = STMF_ERROR_BUSY;
3976 4024 break;
3977 4025 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
3978 4026 ret = STMF_ERROR_SERVICE_NOT_FOUND;
3979 4027 break;
3980 4028 case STMF_PS_ERROR_VERSION_MISMATCH:
3981 4029 ret = STMF_ERROR_SERVICE_DATA_VERSION;
3982 4030 break;
3983 4031 default:
3984 4032 syslog(LOG_DEBUG,
3985 4033 "stmfGetProviderDataList:psGetProviderDataList"
3986 4034 ":error(%d)", ret);
3987 4035 ret = STMF_STATUS_ERROR;
3988 4036 break;
3989 4037 }
3990 4038
3991 4039 return (ret);
3992 4040 }
3993 4041
3994 4042
3995 4043 /*
3996 4044 * stmfGetSessionList
3997 4045 *
3998 4046 * Purpose: Retrieves the session list for a target (devid)
3999 4047 *
4000 4048 * devid - devid of target for which to retrieve session information.
4001 4049 * sessionList - pointer to pointer to stmfSessionList structure
4002 4050 * on success, this contains the list of initiator sessions.
4003 4051 */
4004 4052 int
4005 4053 stmfGetSessionList(stmfDevid *devid, stmfSessionList **sessionList)
4006 4054 {
4007 4055 int ret = STMF_STATUS_SUCCESS;
4008 4056 int fd;
4009 4057 int ioctlRet;
4010 4058 int cmd = STMF_IOCTL_SESSION_LIST;
4011 4059 int i;
4012 4060 stmf_iocdata_t stmfIoctl;
4013 4061 slist_scsi_session_t *fSessionList, *fSessionListP = NULL;
4014 4062 uint8_t ident[260];
4015 4063 uint32_t fSessionListSize;
4016 4064
4017 4065 if (sessionList == NULL || devid == NULL) {
4018 4066 ret = STMF_ERROR_INVALID_ARG;
4019 4067 }
4020 4068
4021 4069 /* call init */
4022 4070 ret = initializeConfig();
4023 4071 if (ret != STMF_STATUS_SUCCESS) {
4024 4072 return (ret);
4025 4073 }
4026 4074
4027 4075 /*
4028 4076 * Open control node for stmf
4029 4077 */
4030 4078 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4031 4079 return (ret);
4032 4080
4033 4081 /*
4034 4082 * Allocate ioctl input buffer
4035 4083 */
4036 4084 fSessionListSize = ALLOC_SESSION;
4037 4085 fSessionListSize = fSessionListSize * (sizeof (slist_scsi_session_t));
4038 4086 fSessionList = (slist_scsi_session_t *)calloc(1, fSessionListSize);
4039 4087 fSessionListP = fSessionList;
4040 4088 if (fSessionList == NULL) {
4041 4089 ret = STMF_ERROR_NOMEM;
4042 4090 goto done;
4043 4091 }
4044 4092
4045 4093 ident[IDENT_LENGTH_BYTE] = devid->identLength;
4046 4094 bcopy(&(devid->ident), &ident[IDENT_LENGTH_BYTE + 1],
4047 4095 devid->identLength);
4048 4096
4049 4097 bzero(&stmfIoctl, sizeof (stmfIoctl));
4050 4098 /*
4051 4099 * Issue ioctl to get the session list
4052 4100 */
4053 4101 stmfIoctl.stmf_version = STMF_VERSION_1;
4054 4102 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ident;
4055 4103 stmfIoctl.stmf_ibuf_size = sizeof (ident);
4056 4104 stmfIoctl.stmf_obuf_size = fSessionListSize;
4057 4105 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
4058 4106 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4059 4107 if (ioctlRet != 0) {
4060 4108 switch (errno) {
4061 4109 case EBUSY:
4062 4110 ret = STMF_ERROR_BUSY;
4063 4111 break;
4064 4112 case EPERM:
4065 4113 case EACCES:
4066 4114 ret = STMF_ERROR_PERM;
4067 4115 break;
4068 4116 default:
4069 4117 syslog(LOG_DEBUG,
4070 4118 "stmfGetSessionList:ioctl errno(%d)",
4071 4119 errno);
4072 4120 ret = STMF_STATUS_ERROR;
4073 4121 break;
4074 4122 }
4075 4123 goto done;
4076 4124 }
4077 4125 /*
4078 4126 * Check whether input buffer was large enough
4079 4127 */
4080 4128 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_SESSION) {
4081 4129 fSessionListSize = stmfIoctl.stmf_obuf_max_nentries *
4082 4130 sizeof (slist_scsi_session_t);
4083 4131 fSessionList = realloc(fSessionList, fSessionListSize);
4084 4132 if (fSessionList == NULL) {
4085 4133 ret = STMF_ERROR_NOMEM;
4086 4134 goto done;
4087 4135 }
4088 4136 fSessionListP = fSessionList;
4089 4137 stmfIoctl.stmf_obuf_size = fSessionListSize;
4090 4138 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fSessionList;
4091 4139 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4092 4140 if (ioctlRet != 0) {
4093 4141 switch (errno) {
4094 4142 case EBUSY:
4095 4143 ret = STMF_ERROR_BUSY;
4096 4144 break;
4097 4145 case EPERM:
4098 4146 case EACCES:
4099 4147 ret = STMF_ERROR_PERM;
4100 4148 break;
4101 4149 default:
4102 4150 syslog(LOG_DEBUG,
4103 4151 "stmfGetSessionList:ioctl "
4104 4152 "errno(%d)", errno);
4105 4153 ret = STMF_STATUS_ERROR;
4106 4154 break;
4107 4155 }
4108 4156 goto done;
4109 4157 }
4110 4158 }
4111 4159
4112 4160 /*
4113 4161 * allocate caller's buffer with the final size
4114 4162 */
4115 4163 *sessionList = (stmfSessionList *)calloc(1, sizeof (stmfSessionList) +
4116 4164 stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfSession));
4117 4165 if (*sessionList == NULL) {
4118 4166 ret = STMF_ERROR_NOMEM;
4119 4167 free(sessionList);
4120 4168 goto done;
4121 4169 }
4122 4170
4123 4171 (*sessionList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
4124 4172
4125 4173 /*
4126 4174 * copy session info to caller's buffer
4127 4175 */
4128 4176 for (i = 0; i < (*sessionList)->cnt; i++) {
4129 4177 (*sessionList)->session[i].initiator.identLength =
4130 4178 fSessionList->initiator[IDENT_LENGTH_BYTE];
4131 4179 bcopy(&(fSessionList->initiator[IDENT_LENGTH_BYTE + 1]),
4132 4180 (*sessionList)->session[i].initiator.ident,
4133 4181 STMF_IDENT_LENGTH);
4134 4182 bcopy(&(fSessionList->alias),
4135 4183 &((*sessionList)->session[i].alias),
4136 4184 sizeof ((*sessionList)->session[i].alias));
4137 4185 bcopy(&(fSessionList++->creation_time),
4138 4186 &((*sessionList)->session[i].creationTime),
4139 4187 sizeof (time_t));
4140 4188 }
4141 4189 done:
4142 4190 (void) close(fd);
4143 4191 free(fSessionListP);
4144 4192 return (ret);
4145 4193 }
4146 4194
4147 4195 /*
4148 4196 * stmfGetTargetGroupList
4149 4197 *
4150 4198 * Purpose: Retrieves the list of target groups
4151 4199 *
4152 4200 * targetGroupList - pointer to a pointer to an stmfGroupList structure. On
4153 4201 * success, it contains the list of target groups.
4154 4202 */
4155 4203 int
4156 4204 stmfGetTargetGroupList(stmfGroupList **targetGroupList)
4157 4205 {
4158 4206 int ret;
4159 4207
4160 4208 if (targetGroupList == NULL) {
4161 4209 return (STMF_ERROR_INVALID_ARG);
4162 4210 }
4163 4211
4164 4212 ret = groupListIoctl(targetGroupList, TARGET_GROUP);
4165 4213 return (ret);
4166 4214 }
4167 4215
4168 4216 /*
4169 4217 * stmfGetTargetGroupMembers
4170 4218 *
4171 4219 * Purpose: Retrieves the group members for a target group
4172 4220 *
4173 4221 * groupName - name of target group for which to retrieve members.
4174 4222 * groupProp - pointer to pointer to stmfGroupProperties structure
4175 4223 * on success, this contains the list of group members.
4176 4224 */
4177 4225 int
4178 4226 stmfGetTargetGroupMembers(stmfGroupName *groupName,
4179 4227 stmfGroupProperties **groupProp)
4180 4228 {
4181 4229 int ret;
4182 4230
4183 4231 if (groupName == NULL || groupProp == NULL) {
4184 4232 return (STMF_ERROR_INVALID_ARG);
4185 4233 }
4186 4234
4187 4235 ret = groupMemberListIoctl(groupName, groupProp, TARGET_GROUP);
4188 4236
4189 4237 return (ret);
4190 4238 }
4191 4239
4192 4240 /*
4193 4241 * stmfGetTargetList
4194 4242 *
4195 4243 * Purpose: Retrieves the list of target ports
4196 4244 *
4197 4245 * targetList - pointer to a pointer to an stmfDevidList structure.
4198 4246 * On success, it contains the list of local ports (target).
4199 4247 */
4200 4248 int
4201 4249 stmfGetTargetList(stmfDevidList **targetList)
4202 4250 {
4203 4251 int ret;
4204 4252 int fd;
4205 4253 int ioctlRet;
4206 4254 int i;
4207 4255 stmf_iocdata_t stmfIoctl;
4208 4256 /* framework target port list */
4209 4257 slist_target_port_t *fTargetList, *fTargetListP = NULL;
4210 4258 uint32_t fTargetListSize;
4211 4259
4212 4260 if (targetList == NULL) {
4213 4261 return (STMF_ERROR_INVALID_ARG);
4214 4262 }
4215 4263
4216 4264 /* call init */
4217 4265 ret = initializeConfig();
4218 4266 if (ret != STMF_STATUS_SUCCESS) {
4219 4267 return (ret);
4220 4268 }
4221 4269
4222 4270 /*
4223 4271 * Open control node for stmf
4224 4272 */
4225 4273 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4226 4274 return (ret);
4227 4275
4228 4276 /*
4229 4277 * Allocate ioctl input buffer
4230 4278 */
4231 4279 fTargetListSize = ALLOC_TARGET_PORT * sizeof (slist_target_port_t);
4232 4280 fTargetListP = fTargetList =
4233 4281 (slist_target_port_t *)calloc(1, fTargetListSize);
4234 4282 if (fTargetList == NULL) {
4235 4283 ret = STMF_ERROR_NOMEM;
4236 4284 goto done;
4237 4285 }
4238 4286
4239 4287 bzero(&stmfIoctl, sizeof (stmfIoctl));
4240 4288 /*
4241 4289 * Issue ioctl to retrieve target list
4242 4290 */
4243 4291 stmfIoctl.stmf_version = STMF_VERSION_1;
4244 4292 stmfIoctl.stmf_obuf_size = fTargetListSize;
4245 4293 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
4246 4294 ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST, &stmfIoctl);
4247 4295 if (ioctlRet != 0) {
4248 4296 switch (errno) {
4249 4297 case EBUSY:
4250 4298 ret = STMF_ERROR_BUSY;
4251 4299 break;
4252 4300 case EPERM:
4253 4301 case EACCES:
4254 4302 ret = STMF_ERROR_PERM;
4255 4303 break;
4256 4304 default:
4257 4305 syslog(LOG_DEBUG,
4258 4306 "stmfGetTargetList:ioctl errno(%d)", errno);
4259 4307 ret = STMF_STATUS_ERROR;
4260 4308 break;
4261 4309 }
4262 4310 goto done;
4263 4311 }
4264 4312 /*
4265 4313 * Check whether input buffer was large enough
4266 4314 */
4267 4315 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_TARGET_PORT) {
4268 4316 fTargetListSize = stmfIoctl.stmf_obuf_max_nentries *
4269 4317 sizeof (slist_target_port_t);
4270 4318 fTargetListP = fTargetList =
4271 4319 realloc(fTargetList, fTargetListSize);
4272 4320 if (fTargetList == NULL) {
4273 4321 ret = STMF_ERROR_NOMEM;
4274 4322 goto done;
4275 4323 }
4276 4324 stmfIoctl.stmf_obuf_size = fTargetListSize;
4277 4325 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fTargetList;
4278 4326 ioctlRet = ioctl(fd, STMF_IOCTL_TARGET_PORT_LIST,
4279 4327 &stmfIoctl);
4280 4328 if (ioctlRet != 0) {
4281 4329 switch (errno) {
4282 4330 case EBUSY:
4283 4331 ret = STMF_ERROR_BUSY;
4284 4332 break;
4285 4333 case EPERM:
4286 4334 case EACCES:
4287 4335 ret = STMF_ERROR_PERM;
4288 4336 break;
4289 4337 default:
4290 4338 syslog(LOG_DEBUG,
4291 4339 "stmfGetTargetList:ioctl errno(%d)",
4292 4340 errno);
4293 4341 ret = STMF_STATUS_ERROR;
4294 4342 break;
4295 4343 }
4296 4344 goto done;
4297 4345 }
4298 4346 }
4299 4347
4300 4348 *targetList = (stmfDevidList *)calloc(1,
4301 4349 stmfIoctl.stmf_obuf_max_nentries * sizeof (stmfDevid) +
4302 4350 sizeof (stmfDevidList));
4303 4351 if (*targetList == NULL) {
4304 4352 ret = STMF_ERROR_NOMEM;
4305 4353 goto done;
4306 4354 }
4307 4355
4308 4356 (*targetList)->cnt = stmfIoctl.stmf_obuf_max_nentries;
4309 4357 for (i = 0; i < stmfIoctl.stmf_obuf_max_nentries; i++, fTargetList++) {
4310 4358 (*targetList)->devid[i].identLength =
4311 4359 fTargetList->target[IDENT_LENGTH_BYTE];
4312 4360 bcopy(&fTargetList->target[IDENT_LENGTH_BYTE + 1],
4313 4361 &(*targetList)->devid[i].ident,
4314 4362 fTargetList->target[IDENT_LENGTH_BYTE]);
4315 4363 }
4316 4364
4317 4365 done:
4318 4366 (void) close(fd);
4319 4367 free(fTargetListP);
4320 4368 return (ret);
4321 4369 }
4322 4370
4323 4371 /*
4324 4372 * stmfGetTargetProperties
4325 4373 *
4326 4374 * Purpose: Retrieves the properties for a logical unit
4327 4375 *
4328 4376 * devid - devid of the target for which to retrieve properties
4329 4377 * targetProps - pointer to an stmfTargetProperties structure.
4330 4378 * On success, it contains the target properties for
4331 4379 * the specified devid.
4332 4380 */
4333 4381 int
4334 4382 stmfGetTargetProperties(stmfDevid *devid, stmfTargetProperties *targetProps)
4335 4383 {
4336 4384 int ret = STMF_STATUS_SUCCESS;
4337 4385 int fd;
4338 4386 int ioctlRet;
4339 4387 stmf_iocdata_t stmfIoctl;
4340 4388 sioc_target_port_props_t targetProperties;
4341 4389 scsi_devid_desc_t *scsiDevid;
4342 4390
4343 4391 if (devid == NULL || targetProps == NULL) {
4344 4392 return (STMF_ERROR_INVALID_ARG);
4345 4393 }
4346 4394
4347 4395 /* call init */
4348 4396 ret = initializeConfig();
4349 4397 if (ret != STMF_STATUS_SUCCESS) {
4350 4398 return (ret);
4351 4399 }
4352 4400
4353 4401 /*
4354 4402 * Open control node for stmf
4355 4403 */
4356 4404 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4357 4405 return (ret);
4358 4406
4359 4407 targetProperties.tgt_id[IDENT_LENGTH_BYTE] = devid->identLength;
4360 4408 bcopy(&(devid->ident), &targetProperties.tgt_id[IDENT_LENGTH_BYTE + 1],
4361 4409 devid->identLength);
4362 4410
4363 4411 bzero(&stmfIoctl, sizeof (stmfIoctl));
4364 4412 /*
4365 4413 * Issue ioctl to add to the host group
4366 4414 */
4367 4415 stmfIoctl.stmf_version = STMF_VERSION_1;
4368 4416 stmfIoctl.stmf_ibuf_size = sizeof (targetProperties.tgt_id);
4369 4417 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&targetProperties.tgt_id;
4370 4418 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&targetProperties;
4371 4419 stmfIoctl.stmf_obuf_size = sizeof (targetProperties);
4372 4420 ioctlRet = ioctl(fd, STMF_IOCTL_GET_TARGET_PORT_PROPERTIES,
4373 4421 &stmfIoctl);
4374 4422 if (ioctlRet != 0) {
4375 4423 switch (errno) {
4376 4424 case EBUSY:
4377 4425 ret = STMF_ERROR_BUSY;
4378 4426 break;
4379 4427 case EPERM:
4380 4428 case EACCES:
4381 4429 ret = STMF_ERROR_PERM;
4382 4430 break;
4383 4431 case ENOENT:
4384 4432 ret = STMF_ERROR_NOT_FOUND;
4385 4433 break;
4386 4434 default:
4387 4435 syslog(LOG_DEBUG,
4388 4436 "stmfGetTargetProperties:ioctl errno(%d)",
4389 4437 errno);
4390 4438 ret = STMF_STATUS_ERROR;
4391 4439 break;
4392 4440 }
4393 4441 goto done;
4394 4442 }
4395 4443
4396 4444 bcopy(targetProperties.tgt_provider_name, targetProps->providerName,
4397 4445 sizeof (targetProperties.tgt_provider_name));
4398 4446 if (targetProperties.tgt_state == STMF_STATE_ONLINE) {
4399 4447 targetProps->status = STMF_TARGET_PORT_ONLINE;
4400 4448 } else if (targetProperties.tgt_state == STMF_STATE_OFFLINE) {
4401 4449 targetProps->status = STMF_TARGET_PORT_OFFLINE;
4402 4450 } else if (targetProperties.tgt_state == STMF_STATE_ONLINING) {
4403 4451 targetProps->status = STMF_TARGET_PORT_ONLINING;
4404 4452 } else if (targetProperties.tgt_state == STMF_STATE_OFFLINING) {
4405 4453 targetProps->status = STMF_TARGET_PORT_OFFLINING;
4406 4454 }
4407 4455 bcopy(targetProperties.tgt_alias, targetProps->alias,
4408 4456 sizeof (targetProps->alias));
4409 4457
4410 4458 scsiDevid = (scsi_devid_desc_t *)&targetProperties.tgt_id;
4411 4459 targetProps->protocol = scsiDevid->protocol_id;
4412 4460
4413 4461 done:
4414 4462 (void) close(fd);
4415 4463 return (ret);
4416 4464 }
4417 4465
4418 4466 /*
4419 4467 * stmfGetLogicalUnitList
4420 4468 *
4421 4469 * Purpose: Retrieves list of logical unit Object IDs
4422 4470 *
4423 4471 * luList - pointer to a pointer to a stmfGuidList structure. On success,
4424 4472 * it contains the list of logical unit guids.
4425 4473 *
4426 4474 */
4427 4475 int
4428 4476 stmfGetLogicalUnitList(stmfGuidList **luList)
4429 4477 {
4430 4478 int ret;
4431 4479 int fd;
4432 4480 int ioctlRet;
4433 4481 int cmd = STMF_IOCTL_LU_LIST;
4434 4482 int i;
4435 4483 stmf_iocdata_t stmfIoctl;
4436 4484 slist_lu_t *fLuList;
4437 4485 uint32_t fLuListSize;
4438 4486 uint32_t listCnt;
4439 4487
4440 4488 if (luList == NULL) {
4441 4489 return (STMF_ERROR_INVALID_ARG);
4442 4490 }
4443 4491
4444 4492 /* call init */
4445 4493 ret = initializeConfig();
4446 4494 if (ret != STMF_STATUS_SUCCESS) {
4447 4495 return (ret);
4448 4496 }
4449 4497
4450 4498 /*
4451 4499 * Open control node for stmf
4452 4500 */
4453 4501 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4454 4502 return (ret);
4455 4503
4456 4504 /*
4457 4505 * Allocate ioctl input buffer
4458 4506 */
4459 4507 fLuListSize = ALLOC_LU;
4460 4508 fLuListSize = fLuListSize * (sizeof (slist_lu_t));
4461 4509 fLuList = (slist_lu_t *)calloc(1, fLuListSize);
4462 4510 if (fLuList == NULL) {
4463 4511 ret = STMF_ERROR_NOMEM;
4464 4512 goto done;
4465 4513 }
4466 4514
4467 4515 bzero(&stmfIoctl, sizeof (stmfIoctl));
4468 4516 /*
4469 4517 * Issue ioctl to get the LU list
4470 4518 */
4471 4519 stmfIoctl.stmf_version = STMF_VERSION_1;
4472 4520 stmfIoctl.stmf_obuf_size = fLuListSize;
4473 4521 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
4474 4522 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4475 4523 if (ioctlRet != 0) {
4476 4524 switch (errno) {
4477 4525 case EBUSY:
4478 4526 ret = STMF_ERROR_BUSY;
4479 4527 break;
4480 4528 case EPERM:
4481 4529 case EACCES:
4482 4530 ret = STMF_ERROR_PERM;
4483 4531 break;
4484 4532 default:
4485 4533 syslog(LOG_DEBUG,
4486 4534 "stmfGetLogicalUnitList:ioctl errno(%d)",
4487 4535 errno);
4488 4536 ret = STMF_STATUS_ERROR;
4489 4537 break;
4490 4538 }
4491 4539 goto done;
4492 4540 }
4493 4541 /*
4494 4542 * Check whether input buffer was large enough
4495 4543 */
4496 4544 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_LU) {
4497 4545 fLuListSize = stmfIoctl.stmf_obuf_max_nentries *
4498 4546 sizeof (slist_lu_t);
4499 4547 free(fLuList);
4500 4548 fLuList = (slist_lu_t *)calloc(1, fLuListSize);
4501 4549 if (fLuList == NULL) {
4502 4550 ret = STMF_ERROR_NOMEM;
4503 4551 goto done;
4504 4552 }
4505 4553 stmfIoctl.stmf_obuf_size = fLuListSize;
4506 4554 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fLuList;
4507 4555 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4508 4556 if (ioctlRet != 0) {
4509 4557 switch (errno) {
4510 4558 case EBUSY:
4511 4559 ret = STMF_ERROR_BUSY;
4512 4560 break;
4513 4561 case EPERM:
4514 4562 case EACCES:
4515 4563 ret = STMF_ERROR_PERM;
4516 4564 break;
4517 4565 default:
4518 4566 syslog(LOG_DEBUG,
4519 4567 "stmfGetLogicalUnitList:"
4520 4568 "ioctl errno(%d)", errno);
4521 4569 ret = STMF_STATUS_ERROR;
4522 4570 break;
4523 4571 }
4524 4572 goto done;
4525 4573 }
4526 4574 }
4527 4575
4528 4576 if (ret != STMF_STATUS_SUCCESS) {
4529 4577 goto done;
4530 4578 }
4531 4579
4532 4580 listCnt = stmfIoctl.stmf_obuf_nentries;
4533 4581
4534 4582 /*
4535 4583 * allocate caller's buffer with the final size
4536 4584 */
4537 4585 *luList = (stmfGuidList *)calloc(1, sizeof (stmfGuidList) +
4538 4586 listCnt * sizeof (stmfGuid));
4539 4587 if (*luList == NULL) {
4540 4588 ret = STMF_ERROR_NOMEM;
4541 4589 goto done;
4542 4590 }
4543 4591
4544 4592 (*luList)->cnt = listCnt;
4545 4593
4546 4594 /* copy to caller's buffer */
4547 4595 for (i = 0; i < listCnt; i++) {
4548 4596 bcopy(&fLuList[i].lu_guid, (*luList)->guid[i].guid,
4549 4597 sizeof (stmfGuid));
4550 4598 }
4551 4599
4552 4600 /*
4553 4601 * sort the list. This gives a consistent view across gets
4554 4602 */
4555 4603 qsort((void *)&((*luList)->guid[0]), (*luList)->cnt,
4556 4604 sizeof (stmfGuid), guidCompare);
4557 4605
4558 4606 done:
4559 4607 (void) close(fd);
4560 4608 /*
4561 4609 * free internal buffers
4562 4610 */
4563 4611 free(fLuList);
4564 4612 return (ret);
4565 4613 }
4566 4614
4567 4615 /*
4568 4616 * stmfGetLogicalUnitProperties
4569 4617 *
4570 4618 * Purpose: Retrieves the properties for a logical unit
4571 4619 *
4572 4620 * lu - guid of the logical unit for which to retrieve properties
4573 4621 * stmfLuProps - pointer to an stmfLogicalUnitProperties structure. On success,
4574 4622 * it contains the logical unit properties for the specified guid.
4575 4623 */
4576 4624 int
4577 4625 stmfGetLogicalUnitProperties(stmfGuid *lu, stmfLogicalUnitProperties *luProps)
4578 4626 {
4579 4627 int ret = STMF_STATUS_SUCCESS;
4580 4628 int stmfRet;
4581 4629 int fd;
4582 4630 int ioctlRet;
4583 4631 int cmd = STMF_IOCTL_GET_LU_PROPERTIES;
4584 4632 stmfViewEntryList *viewEntryList = NULL;
4585 4633 stmf_iocdata_t stmfIoctl;
4586 4634 sioc_lu_props_t fLuProps;
4587 4635
4588 4636 if (lu == NULL || luProps == NULL) {
4589 4637 return (STMF_ERROR_INVALID_ARG);
4590 4638 }
4591 4639
4592 4640 bzero(luProps, sizeof (stmfLogicalUnitProperties));
4593 4641
4594 4642 /* call init */
4595 4643 ret = initializeConfig();
4596 4644 if (ret != STMF_STATUS_SUCCESS) {
4597 4645 return (ret);
4598 4646 }
4599 4647
4600 4648 /*
4601 4649 * Open control node for stmf
4602 4650 */
4603 4651 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4604 4652 return (ret);
4605 4653
4606 4654 bzero(&stmfIoctl, sizeof (stmfIoctl));
4607 4655 /*
4608 4656 * Issue ioctl to add to the host group
4609 4657 */
4610 4658 stmfIoctl.stmf_version = STMF_VERSION_1;
4611 4659 stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4612 4660 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4613 4661 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&fLuProps;
4614 4662 stmfIoctl.stmf_obuf_size = sizeof (fLuProps);
4615 4663 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4616 4664 if (ioctlRet != 0) {
4617 4665 switch (errno) {
4618 4666 case EBUSY:
4619 4667 ret = STMF_ERROR_BUSY;
4620 4668 break;
4621 4669 case EPERM:
4622 4670 case EACCES:
4623 4671 ret = STMF_ERROR_PERM;
4624 4672 break;
4625 4673 case ENOENT:
4626 4674 stmfRet = stmfGetViewEntryList(lu,
4627 4675 &viewEntryList);
4628 4676 if (stmfRet == STMF_STATUS_SUCCESS) {
4629 4677 luProps->status =
4630 4678 STMF_LOGICAL_UNIT_UNREGISTERED;
4631 4679 if (viewEntryList->cnt > 0) {
4632 4680 ret = STMF_STATUS_SUCCESS;
4633 4681 } else {
4634 4682 ret = STMF_ERROR_NOT_FOUND;
4635 4683 }
4636 4684 } else {
4637 4685 ret = STMF_ERROR_NOT_FOUND;
4638 4686 }
4639 4687 stmfFreeMemory(viewEntryList);
4640 4688 break;
4641 4689 default:
4642 4690 syslog(LOG_DEBUG,
4643 4691 "stmfGetLogicalUnit:ioctl errno(%d)",
4644 4692 errno);
4645 4693 ret = STMF_STATUS_ERROR;
4646 4694 break;
4647 4695 }
4648 4696 goto done;
4649 4697 }
4650 4698
4651 4699 bcopy(fLuProps.lu_provider_name, luProps->providerName,
4652 4700 sizeof (fLuProps.lu_provider_name));
4653 4701 if (fLuProps.lu_state == STMF_STATE_ONLINE) {
4654 4702 luProps->status = STMF_LOGICAL_UNIT_ONLINE;
4655 4703 } else if (fLuProps.lu_state == STMF_STATE_OFFLINE) {
4656 4704 luProps->status = STMF_LOGICAL_UNIT_OFFLINE;
4657 4705 } else if (fLuProps.lu_state == STMF_STATE_ONLINING) {
4658 4706 luProps->status = STMF_LOGICAL_UNIT_ONLINING;
4659 4707 } else if (fLuProps.lu_state == STMF_STATE_OFFLINING) {
4660 4708 luProps->status = STMF_LOGICAL_UNIT_OFFLINING;
4661 4709 }
4662 4710 bcopy(fLuProps.lu_alias, luProps->alias, sizeof (luProps->alias));
4663 4711 done:
4664 4712 (void) close(fd);
4665 4713 return (ret);
4666 4714 }
4667 4715
4668 4716 /*
4669 4717 * stmfGetState
4670 4718 *
4671 4719 * Purpose: retrieve the current state of the stmf module
4672 4720 *
4673 4721 * state - pointer to stmfState structure allocated by the caller
4674 4722 * On success, contains the state of stmf
4675 4723 */
4676 4724 int
4677 4725 stmfGetState(stmfState *state)
4678 4726 {
4679 4727 int ret;
4680 4728 stmf_state_desc_t iState;
4681 4729
4682 4730 if (state == NULL) {
4683 4731 return (STMF_ERROR_INVALID_ARG);
4684 4732 }
4685 4733
4686 4734 ret = getStmfState(&iState);
4687 4735 if (ret != STMF_STATUS_SUCCESS) {
4688 4736 return (ret);
4689 4737 }
4690 4738 switch (iState.state) {
4691 4739 case STMF_STATE_ONLINE:
4692 4740 state->operationalState =
4693 4741 STMF_SERVICE_STATE_ONLINE;
4694 4742 break;
4695 4743 case STMF_STATE_OFFLINE:
4696 4744 state->operationalState =
4697 4745 STMF_SERVICE_STATE_OFFLINE;
4698 4746 break;
4699 4747 case STMF_STATE_ONLINING:
4700 4748 state->operationalState =
4701 4749 STMF_SERVICE_STATE_ONLINING;
4702 4750 break;
4703 4751 case STMF_STATE_OFFLINING:
4704 4752 state->operationalState =
4705 4753 STMF_SERVICE_STATE_OFFLINING;
4706 4754 break;
4707 4755 default:
4708 4756 state->operationalState =
4709 4757 STMF_SERVICE_STATE_UNKNOWN;
4710 4758 break;
4711 4759 }
4712 4760 switch (iState.config_state) {
4713 4761 case STMF_CONFIG_NONE:
4714 4762 state->configState = STMF_CONFIG_STATE_NONE;
4715 4763 break;
4716 4764 case STMF_CONFIG_INIT:
4717 4765 state->configState = STMF_CONFIG_STATE_INIT;
4718 4766 break;
4719 4767 case STMF_CONFIG_INIT_DONE:
4720 4768 state->configState =
4721 4769 STMF_CONFIG_STATE_INIT_DONE;
4722 4770 break;
4723 4771 default:
4724 4772 state->configState =
4725 4773 STMF_CONFIG_STATE_UNKNOWN;
4726 4774 break;
4727 4775 }
4728 4776 return (STMF_STATUS_SUCCESS);
4729 4777 }
4730 4778
4731 4779 /*
4732 4780 * stmfGetViewEntryList
4733 4781 *
4734 4782 * Purpose: Retrieves the list of view entries for the specified
4735 4783 * logical unit.
4736 4784 *
4737 4785 * lu - the guid of the logical unit for which to retrieve the view entry list
4738 4786 * viewEntryList - a pointer to a pointer to a stmfViewEntryList structure. On
4739 4787 * success, contains the list of view entries.
4740 4788 */
4741 4789 int
4742 4790 stmfGetViewEntryList(stmfGuid *lu, stmfViewEntryList **viewEntryList)
4743 4791 {
4744 4792 int ret;
4745 4793 int fd;
4746 4794 int ioctlRet;
4747 4795 int cmd = STMF_IOCTL_LU_VE_LIST;
4748 4796 int i;
4749 4797 stmf_iocdata_t stmfIoctl;
4750 4798 stmf_view_op_entry_t *fVeList;
4751 4799 uint32_t fVeListSize;
4752 4800 uint32_t listCnt;
4753 4801
4754 4802 if (lu == NULL || viewEntryList == NULL) {
4755 4803 return (STMF_ERROR_INVALID_ARG);
4756 4804 }
4757 4805
4758 4806 /* call init */
4759 4807 ret = initializeConfig();
4760 4808 if (ret != STMF_STATUS_SUCCESS) {
4761 4809 return (ret);
4762 4810 }
4763 4811
4764 4812 /*
4765 4813 * Open control node for stmf
4766 4814 */
4767 4815 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
4768 4816 return (ret);
4769 4817
4770 4818 /*
4771 4819 * Allocate ioctl input buffer
4772 4820 */
4773 4821 fVeListSize = ALLOC_VE;
4774 4822 fVeListSize = fVeListSize * (sizeof (stmf_view_op_entry_t));
4775 4823 fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4776 4824 if (fVeList == NULL) {
4777 4825 ret = STMF_ERROR_NOMEM;
4778 4826 goto done;
4779 4827 }
4780 4828
4781 4829 bzero(&stmfIoctl, sizeof (stmfIoctl));
4782 4830 /*
4783 4831 * Issue ioctl to get the LU list
4784 4832 */
4785 4833 stmfIoctl.stmf_version = STMF_VERSION_1;
4786 4834 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)lu;
4787 4835 stmfIoctl.stmf_ibuf_size = sizeof (stmfGuid);
4788 4836 stmfIoctl.stmf_obuf_size = fVeListSize;
4789 4837 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4790 4838 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4791 4839 if (ioctlRet != 0) {
4792 4840 switch (errno) {
4793 4841 case EBUSY:
4794 4842 ret = STMF_ERROR_BUSY;
4795 4843 break;
4796 4844 case EPERM:
4797 4845 case EACCES:
4798 4846 ret = STMF_ERROR_PERM;
4799 4847 break;
4800 4848 default:
4801 4849 syslog(LOG_DEBUG,
4802 4850 "stmfGetViewEntryList:ioctl errno(%d)",
4803 4851 errno);
4804 4852 ret = STMF_STATUS_ERROR;
4805 4853 break;
4806 4854 }
4807 4855 goto done;
4808 4856 }
4809 4857 /*
4810 4858 * Check whether input buffer was large enough
4811 4859 */
4812 4860 if (stmfIoctl.stmf_obuf_max_nentries > ALLOC_VE) {
4813 4861 bzero(&stmfIoctl, sizeof (stmfIoctl));
4814 4862 fVeListSize = stmfIoctl.stmf_obuf_max_nentries *
4815 4863 sizeof (stmf_view_op_entry_t);
4816 4864 free(fVeList);
4817 4865 fVeList = (stmf_view_op_entry_t *)calloc(1, fVeListSize);
4818 4866 if (fVeList == NULL) {
4819 4867 return (STMF_ERROR_NOMEM);
4820 4868 }
4821 4869 stmfIoctl.stmf_obuf_size = fVeListSize;
4822 4870 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)fVeList;
4823 4871 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
4824 4872 if (ioctlRet != 0) {
4825 4873 switch (errno) {
4826 4874 case EBUSY:
4827 4875 ret = STMF_ERROR_BUSY;
4828 4876 break;
4829 4877 case EPERM:
4830 4878 case EACCES:
4831 4879 ret = STMF_ERROR_PERM;
4832 4880 break;
4833 4881 default:
4834 4882 syslog(LOG_DEBUG,
4835 4883 "stmfGetLogicalUnitList:"
4836 4884 "ioctl errno(%d)", errno);
4837 4885 ret = STMF_STATUS_ERROR;
4838 4886 break;
4839 4887 }
4840 4888 goto done;
4841 4889 }
4842 4890 }
4843 4891
4844 4892 if (ret != STMF_STATUS_SUCCESS) {
4845 4893 goto done;
4846 4894 }
4847 4895
4848 4896 listCnt = stmfIoctl.stmf_obuf_nentries;
4849 4897
4850 4898 /*
4851 4899 * allocate caller's buffer with the final size
4852 4900 */
4853 4901 *viewEntryList = (stmfViewEntryList *)calloc(1,
4854 4902 sizeof (stmfViewEntryList) + listCnt * sizeof (stmfViewEntry));
4855 4903 if (*viewEntryList == NULL) {
4856 4904 ret = STMF_ERROR_NOMEM;
4857 4905 goto done;
4858 4906 }
4859 4907
4860 4908 (*viewEntryList)->cnt = listCnt;
4861 4909
4862 4910 /* copy to caller's buffer */
4863 4911 for (i = 0; i < listCnt; i++) {
4864 4912 (*viewEntryList)->ve[i].veIndexValid = B_TRUE;
4865 4913 (*viewEntryList)->ve[i].veIndex = fVeList[i].ve_ndx;
4866 4914 if (fVeList[i].ve_all_hosts == 1) {
4867 4915 (*viewEntryList)->ve[i].allHosts = B_TRUE;
4868 4916 } else {
4869 4917 bcopy(fVeList[i].ve_host_group.name,
4870 4918 (*viewEntryList)->ve[i].hostGroup,
4871 4919 fVeList[i].ve_host_group.name_size);
4872 4920 }
4873 4921 if (fVeList[i].ve_all_targets == 1) {
4874 4922 (*viewEntryList)->ve[i].allTargets = B_TRUE;
4875 4923 } else {
4876 4924 bcopy(fVeList[i].ve_target_group.name,
4877 4925 (*viewEntryList)->ve[i].targetGroup,
4878 4926 fVeList[i].ve_target_group.name_size);
4879 4927 }
4880 4928 bcopy(fVeList[i].ve_lu_nbr, (*viewEntryList)->ve[i].luNbr,
4881 4929 sizeof ((*viewEntryList)->ve[i].luNbr));
4882 4930 (*viewEntryList)->ve[i].luNbrValid = B_TRUE;
4883 4931 }
4884 4932
4885 4933 /*
4886 4934 * sort the list. This gives a consistent view across gets
4887 4935 */
4888 4936 qsort((void *)&((*viewEntryList)->ve[0]), (*viewEntryList)->cnt,
4889 4937 sizeof (stmfViewEntry), viewEntryCompare);
4890 4938
4891 4939 done:
4892 4940 (void) close(fd);
4893 4941 /*
4894 4942 * free internal buffers
4895 4943 */
4896 4944 free(fVeList);
4897 4945 return (ret);
4898 4946 }
4899 4947
4900 4948
4901 4949 /*
4902 4950 * loadHostGroups
4903 4951 *
4904 4952 * Purpose - issues the ioctl to load the host groups into stmf
4905 4953 *
4906 4954 * fd - file descriptor for the control node of stmf.
4907 4955 * groupList - populated host group list
4908 4956 */
4909 4957 static int
4910 4958 loadHostGroups(int fd, stmfGroupList *groupList)
4911 4959 {
4912 4960 int i, j;
4913 4961 int ret = STMF_STATUS_SUCCESS;
4914 4962 stmfGroupProperties *groupProps = NULL;
4915 4963
4916 4964 for (i = 0; i < groupList->cnt; i++) {
4917 4965 if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_HOST_GROUP,
4918 4966 &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4919 4967 goto out;
4920 4968 }
4921 4969 ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4922 4970 &groupProps, HOST_GROUP);
4923 4971 for (j = 0; j < groupProps->cnt; j++) {
4924 4972 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_HG_ENTRY,
4925 4973 &(groupList->name[i]), &(groupProps->name[j])))
4926 4974 != STMF_STATUS_SUCCESS) {
4927 4975 goto out;
4928 4976 }
4929 4977 }
4930 4978 }
4931 4979
4932 4980
4933 4981 out:
4934 4982 stmfFreeMemory(groupProps);
4935 4983 return (ret);
4936 4984 }
4937 4985
4938 4986 /*
4939 4987 * loadTargetGroups
4940 4988 *
4941 4989 * Purpose - issues the ioctl to load the target groups into stmf
4942 4990 *
4943 4991 * fd - file descriptor for the control node of stmf.
4944 4992 * groupList - populated target group list.
4945 4993 */
4946 4994 static int
4947 4995 loadTargetGroups(int fd, stmfGroupList *groupList)
4948 4996 {
4949 4997 int i, j;
4950 4998 int ret = STMF_STATUS_SUCCESS;
4951 4999 stmfGroupProperties *groupProps = NULL;
4952 5000
4953 5001 for (i = 0; i < groupList->cnt; i++) {
4954 5002 if ((ret = groupIoctl(fd, STMF_IOCTL_CREATE_TARGET_GROUP,
4955 5003 &(groupList->name[i]))) != STMF_STATUS_SUCCESS) {
4956 5004 goto out;
4957 5005 }
4958 5006 ret = iLoadGroupMembersFromPs(&(groupList->name[i]),
4959 5007 &groupProps, TARGET_GROUP);
4960 5008 for (j = 0; j < groupProps->cnt; j++) {
4961 5009 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_ADD_TG_ENTRY,
4962 5010 &(groupList->name[i]), &(groupProps->name[j])))
4963 5011 != STMF_STATUS_SUCCESS) {
4964 5012 goto out;
4965 5013 }
4966 5014 }
4967 5015 }
4968 5016
4969 5017
4970 5018 out:
4971 5019 stmfFreeMemory(groupProps);
4972 5020 return (ret);
4973 5021 }
4974 5022
4975 5023
4976 5024 /*
4977 5025 * loadStore
4978 5026 *
4979 5027 * Purpose: Load the configuration data from the store
4980 5028 *
4981 5029 * First load the host groups and target groups, then the view entries
4982 5030 * and finally the provider data
4983 5031 *
4984 5032 * fd - file descriptor of control node for stmf.
4985 5033 */
4986 5034 static int
4987 5035 loadStore(int fd)
4988 5036 {
4989 5037 int ret;
4990 5038 int i, j;
4991 5039 stmfGroupList *groupList = NULL;
4992 5040 stmfGuidList *guidList = NULL;
4993 5041 stmfViewEntryList *viewEntryList = NULL;
4994 5042 stmfProviderList *providerList = NULL;
4995 5043 int providerType;
4996 5044 nvlist_t *nvl = NULL;
4997 5045
4998 5046
4999 5047
5000 5048 /* load host groups */
5001 5049 ret = iLoadGroupFromPs(&groupList, HOST_GROUP);
5002 5050 if (ret != STMF_STATUS_SUCCESS) {
5003 5051 return (ret);
5004 5052 }
5005 5053 ret = loadHostGroups(fd, groupList);
5006 5054 if (ret != STMF_STATUS_SUCCESS) {
5007 5055 goto out;
5008 5056 }
5009 5057
5010 5058 stmfFreeMemory(groupList);
5011 5059 groupList = NULL;
5012 5060
5013 5061 /* load target groups */
5014 5062 ret = iLoadGroupFromPs(&groupList, TARGET_GROUP);
5015 5063 if (ret != STMF_STATUS_SUCCESS) {
5016 5064 goto out;
5017 5065 }
5018 5066 ret = loadTargetGroups(fd, groupList);
5019 5067 if (ret != STMF_STATUS_SUCCESS) {
5020 5068 goto out;
5021 5069 }
5022 5070
5023 5071 stmfFreeMemory(groupList);
5024 5072 groupList = NULL;
5025 5073
5026 5074 /* Get the guid list */
5027 5075 ret = psGetLogicalUnitList(&guidList);
5028 5076 switch (ret) {
5029 5077 case STMF_PS_SUCCESS:
5030 5078 ret = STMF_STATUS_SUCCESS;
5031 5079 break;
5032 5080 case STMF_PS_ERROR_NOT_FOUND:
5033 5081 ret = STMF_ERROR_NOT_FOUND;
5034 5082 break;
5035 5083 case STMF_PS_ERROR_BUSY:
5036 5084 ret = STMF_ERROR_BUSY;
5037 5085 break;
5038 5086 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5039 5087 ret = STMF_ERROR_SERVICE_NOT_FOUND;
5040 5088 break;
5041 5089 case STMF_PS_ERROR_VERSION_MISMATCH:
5042 5090 ret = STMF_ERROR_SERVICE_DATA_VERSION;
5043 5091 break;
5044 5092 default:
5045 5093 ret = STMF_STATUS_ERROR;
5046 5094 break;
5047 5095 }
5048 5096
5049 5097 if (ret != STMF_STATUS_SUCCESS) {
5050 5098 goto out;
5051 5099 }
5052 5100
5053 5101 /*
5054 5102 * We have the guid list, now get the corresponding
5055 5103 * view entries for each guid
5056 5104 */
5057 5105 for (i = 0; i < guidList->cnt; i++) {
5058 5106 ret = psGetViewEntryList(&guidList->guid[i], &viewEntryList);
5059 5107 switch (ret) {
5060 5108 case STMF_PS_SUCCESS:
5061 5109 ret = STMF_STATUS_SUCCESS;
5062 5110 break;
5063 5111 case STMF_PS_ERROR_NOT_FOUND:
5064 5112 ret = STMF_ERROR_NOT_FOUND;
5065 5113 break;
5066 5114 case STMF_PS_ERROR_BUSY:
5067 5115 ret = STMF_ERROR_BUSY;
5068 5116 break;
5069 5117 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5070 5118 ret = STMF_ERROR_SERVICE_NOT_FOUND;
5071 5119 break;
5072 5120 case STMF_PS_ERROR_VERSION_MISMATCH:
5073 5121 ret = STMF_ERROR_SERVICE_DATA_VERSION;
5074 5122 break;
5075 5123 default:
5076 5124 ret = STMF_STATUS_ERROR;
5077 5125 break;
5078 5126 }
5079 5127 if (ret != STMF_STATUS_SUCCESS) {
5080 5128 goto out;
5081 5129 }
5082 5130 for (j = 0; j < viewEntryList->cnt; j++) {
5083 5131 ret = addViewEntryIoctl(fd, &guidList->guid[i],
5084 5132 &viewEntryList->ve[j]);
5085 5133 if (ret != STMF_STATUS_SUCCESS) {
5086 5134 goto out;
5087 5135 }
5088 5136 }
5089 5137 }
5090 5138
5091 5139 /* get the list of providers that have data */
5092 5140 ret = psGetProviderDataList(&providerList);
5093 5141 switch (ret) {
5094 5142 case STMF_PS_SUCCESS:
5095 5143 ret = STMF_STATUS_SUCCESS;
5096 5144 break;
5097 5145 case STMF_PS_ERROR_NOT_FOUND:
5098 5146 ret = STMF_ERROR_NOT_FOUND;
5099 5147 break;
5100 5148 case STMF_PS_ERROR_BUSY:
5101 5149 ret = STMF_ERROR_BUSY;
5102 5150 break;
5103 5151 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5104 5152 ret = STMF_ERROR_SERVICE_NOT_FOUND;
5105 5153 break;
5106 5154 case STMF_PS_ERROR_VERSION_MISMATCH:
5107 5155 ret = STMF_ERROR_SERVICE_DATA_VERSION;
5108 5156 break;
5109 5157 default:
5110 5158 ret = STMF_STATUS_ERROR;
5111 5159 break;
5112 5160 }
5113 5161 if (ret != STMF_STATUS_SUCCESS) {
5114 5162 goto out;
5115 5163 }
5116 5164
5117 5165 for (i = 0; i < providerList->cnt; i++) {
5118 5166 providerType = providerList->provider[i].providerType;
5119 5167 ret = psGetProviderData(providerList->provider[i].name,
5120 5168 &nvl, providerType, NULL);
5121 5169 switch (ret) {
5122 5170 case STMF_PS_SUCCESS:
5123 5171 ret = STMF_STATUS_SUCCESS;
5124 5172 break;
5125 5173 case STMF_PS_ERROR_NOT_FOUND:
5126 5174 ret = STMF_ERROR_NOT_FOUND;
5127 5175 break;
5128 5176 case STMF_PS_ERROR_BUSY:
5129 5177 ret = STMF_ERROR_BUSY;
5130 5178 break;
5131 5179 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5132 5180 ret = STMF_ERROR_SERVICE_NOT_FOUND;
5133 5181 break;
5134 5182 case STMF_PS_ERROR_VERSION_MISMATCH:
5135 5183 ret = STMF_ERROR_SERVICE_DATA_VERSION;
5136 5184 break;
5137 5185 default:
5138 5186 ret = STMF_STATUS_ERROR;
5139 5187 break;
5140 5188 }
5141 5189 if (ret != STMF_STATUS_SUCCESS) {
5142 5190 goto out;
5143 5191 }
5144 5192
5145 5193 /* call setProviderData */
5146 5194 ret = setProviderData(fd, providerList->provider[i].name, nvl,
5147 5195 providerType, NULL);
5148 5196 switch (ret) {
5149 5197 case STMF_PS_SUCCESS:
5150 5198 ret = STMF_STATUS_SUCCESS;
5151 5199 break;
5152 5200 case STMF_PS_ERROR_NOT_FOUND:
5153 5201 ret = STMF_ERROR_NOT_FOUND;
5154 5202 break;
5155 5203 case STMF_PS_ERROR_BUSY:
5156 5204 ret = STMF_ERROR_BUSY;
5157 5205 break;
5158 5206 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
5159 5207 ret = STMF_ERROR_SERVICE_NOT_FOUND;
5160 5208 break;
5161 5209 case STMF_PS_ERROR_VERSION_MISMATCH:
5162 5210 ret = STMF_ERROR_SERVICE_DATA_VERSION;
5163 5211 break;
5164 5212 default:
5165 5213 ret = STMF_STATUS_ERROR;
5166 5214 break;
5167 5215 }
5168 5216 if (ret != STMF_STATUS_SUCCESS) {
5169 5217 goto out;
5170 5218 }
5171 5219
5172 5220 nvlist_free(nvl);
5173 5221 nvl = NULL;
5174 5222 }
5175 5223 out:
5176 5224 if (groupList != NULL) {
5177 5225 free(groupList);
5178 5226 }
5179 5227 if (guidList != NULL) {
5180 5228 free(guidList);
5181 5229 }
5182 5230 if (viewEntryList != NULL) {
5183 5231 free(viewEntryList);
5184 5232 }
5185 5233 if (nvl != NULL) {
5186 5234 nvlist_free(nvl);
5187 5235 }
5188 5236 return (ret);
5189 5237 }
5190 5238
5191 5239 /*
5192 5240 * stmfGetAluaState
5193 5241 *
5194 5242 * Purpose - Get the alua state
5195 5243 *
5196 5244 */
5197 5245 int
5198 5246 stmfGetAluaState(boolean_t *enabled, uint32_t *node)
5199 5247 {
5200 5248 int ret = STMF_STATUS_SUCCESS;
5201 5249 int fd;
5202 5250 stmf_iocdata_t stmfIoctl = {0};
5203 5251 stmf_alua_state_desc_t alua_state = {0};
5204 5252 int ioctlRet;
5205 5253
5206 5254 if (enabled == NULL || node == NULL) {
5207 5255 return (STMF_ERROR_INVALID_ARG);
5208 5256 }
5209 5257
5210 5258 /*
5211 5259 * Open control node for stmf
5212 5260 */
5213 5261 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5214 5262 return (ret);
5215 5263
5216 5264 /*
5217 5265 * Issue ioctl to get the stmf state
5218 5266 */
5219 5267 stmfIoctl.stmf_version = STMF_VERSION_1;
5220 5268 stmfIoctl.stmf_obuf_size = sizeof (alua_state);
5221 5269 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&alua_state;
5222 5270 ioctlRet = ioctl(fd, STMF_IOCTL_GET_ALUA_STATE, &stmfIoctl);
5223 5271
5224 5272 (void) close(fd);
5225 5273
5226 5274 if (ioctlRet != 0) {
5227 5275 switch (errno) {
5228 5276 case EBUSY:
5229 5277 ret = STMF_ERROR_BUSY;
5230 5278 break;
5231 5279 case EPERM:
5232 5280 case EACCES:
5233 5281 ret = STMF_ERROR_PERM;
5234 5282 break;
5235 5283 default:
5236 5284 syslog(LOG_DEBUG,
5237 5285 "getStmfState:ioctl errno(%d)", errno);
5238 5286 ret = STMF_STATUS_ERROR;
5239 5287 break;
5240 5288 }
5241 5289 } else {
5242 5290 if (alua_state.alua_state == 1) {
5243 5291 *enabled = B_TRUE;
5244 5292 } else {
5245 5293 *enabled = B_FALSE;
5246 5294 }
5247 5295 *node = alua_state.alua_node;
5248 5296 }
5249 5297
5250 5298 return (ret);
5251 5299 }
5252 5300
5253 5301 /*
5254 5302 * stmfSetAluaState
5255 5303 *
5256 5304 * Purpose - set the alua state to enabled/disabled
5257 5305 *
5258 5306 */
5259 5307 int
5260 5308 stmfSetAluaState(boolean_t enabled, uint32_t node)
5261 5309 {
5262 5310 int ret = STMF_STATUS_SUCCESS;
5263 5311 int fd;
5264 5312 stmf_iocdata_t stmfIoctl = {0};
5265 5313 stmf_alua_state_desc_t alua_state = {0};
5266 5314 int ioctlRet;
5267 5315
5268 5316 if ((enabled != B_TRUE && enabled != B_FALSE) || (node > 1)) {
5269 5317 return (STMF_ERROR_INVALID_ARG);
5270 5318 }
5271 5319
5272 5320 if (enabled) {
5273 5321 alua_state.alua_state = 1;
5274 5322 }
5275 5323
5276 5324 alua_state.alua_node = node;
5277 5325
5278 5326 /*
5279 5327 * Open control node for stmf
5280 5328 */
5281 5329 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5282 5330 return (ret);
5283 5331
5284 5332 /*
5285 5333 * Issue ioctl to get the stmf state
5286 5334 */
5287 5335 stmfIoctl.stmf_version = STMF_VERSION_1;
5288 5336 stmfIoctl.stmf_ibuf_size = sizeof (alua_state);
5289 5337 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&alua_state;
5290 5338 ioctlRet = ioctl(fd, STMF_IOCTL_SET_ALUA_STATE, &stmfIoctl);
5291 5339
5292 5340 (void) close(fd);
5293 5341
5294 5342 if (ioctlRet != 0) {
5295 5343 switch (errno) {
5296 5344 case EBUSY:
5297 5345 ret = STMF_ERROR_BUSY;
5298 5346 break;
5299 5347 case EPERM:
5300 5348 case EACCES:
5301 5349 ret = STMF_ERROR_PERM;
5302 5350 break;
5303 5351 default:
5304 5352 syslog(LOG_DEBUG,
5305 5353 "getStmfState:ioctl errno(%d)", errno);
5306 5354 ret = STMF_STATUS_ERROR;
5307 5355 break;
5308 5356 }
5309 5357 }
5310 5358 if (!enabled && ret == STMF_STATUS_SUCCESS) {
5311 5359 deleteNonActiveLus();
5312 5360 }
5313 5361
5314 5362 return (ret);
5315 5363 }
5316 5364
5317 5365 static void
5318 5366 deleteNonActiveLus()
5319 5367 {
5320 5368 int stmfRet;
5321 5369 int i;
5322 5370 stmfGuidList *luList;
5323 5371 luResource hdl = NULL;
5324 5372 char propVal[10];
5325 5373 size_t propValSize = sizeof (propVal);
5326 5374
5327 5375 stmfRet = stmfGetLogicalUnitList(&luList);
5328 5376 if (stmfRet != STMF_STATUS_SUCCESS) {
5329 5377 return;
5330 5378 }
5331 5379
5332 5380 for (i = 0; i < luList->cnt; i++) {
5333 5381 stmfRet = stmfGetLuResource(&luList->guid[i], &hdl);
5334 5382 if (stmfRet != STMF_STATUS_SUCCESS) {
5335 5383 goto err;
5336 5384 }
5337 5385 stmfRet = stmfGetLuProp(hdl, STMF_LU_PROP_ACCESS_STATE, propVal,
5338 5386 &propValSize);
5339 5387 if (stmfRet != STMF_STATUS_SUCCESS) {
5340 5388 goto err;
5341 5389 }
5342 5390 if (propVal[0] == '0') {
5343 5391 (void) stmfFreeLuResource(hdl);
5344 5392 hdl = NULL;
5345 5393 continue;
5346 5394 }
5347 5395 (void) stmfDeleteLu(&luList->guid[i]);
5348 5396 (void) stmfFreeLuResource(hdl);
5349 5397 hdl = NULL;
5350 5398 }
5351 5399
5352 5400 err:
5353 5401 stmfFreeMemory(luList);
5354 5402 (void) stmfFreeLuResource(hdl);
5355 5403 }
5356 5404
5357 5405 /*
5358 5406 * stmfLoadConfig
5359 5407 *
5360 5408 * Purpose - load the configuration data from smf into stmf
5361 5409 *
5362 5410 */
5363 5411 int
5364 5412 stmfLoadConfig(void)
5365 5413 {
5366 5414 int ret = STMF_STATUS_SUCCESS;
5367 5415 int fd;
5368 5416 stmf_state_desc_t stmfStateSet;
5369 5417 stmfState state;
5370 5418
5371 5419 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5372 5420 stmfStateSet.state = STMF_STATE_OFFLINE;
5373 5421
5374 5422 if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
5375 5423 != STMF_STATUS_SUCCESS) {
5376 5424 return (ret);
5377 5425 }
5378 5426 /*
5379 5427 * Configuration not stored persistently; nothing to
5380 5428 * initialize so do not set to STMF_CONFIG_INIT.
5381 5429 */
5382 5430 stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
5383 5431 goto done;
5384 5432 }
5385 5433
5386 5434 /* Check to ensure service exists */
5387 5435 if (psCheckService() != STMF_STATUS_SUCCESS) {
5388 5436 return (STMF_ERROR_SERVICE_NOT_FOUND);
5389 5437 }
5390 5438
5391 5439 ret = stmfGetState(&state);
5392 5440 if (ret == STMF_STATUS_SUCCESS) {
5393 5441 if (state.operationalState != STMF_SERVICE_STATE_OFFLINE) {
5394 5442 return (STMF_ERROR_SERVICE_ONLINE);
5395 5443 }
5396 5444 } else {
5397 5445 return (STMF_STATUS_ERROR);
5398 5446 }
5399 5447
5400 5448
5401 5449 stmfStateSet.state = STMF_STATE_OFFLINE;
5402 5450 stmfStateSet.config_state = STMF_CONFIG_INIT;
5403 5451
5404 5452 /*
5405 5453 * Open control node for stmf
5406 5454 */
5407 5455 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5408 5456 return (ret);
5409 5457
5410 5458 ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
5411 5459 if (ret != STMF_STATUS_SUCCESS) {
5412 5460 goto done;
5413 5461 }
5414 5462
5415 5463 /* Load the persistent configuration data */
5416 5464 ret = loadStore(fd);
5417 5465 if (ret != 0) {
5418 5466 goto done;
5419 5467 }
5420 5468
5421 5469 stmfStateSet.state = STMF_STATE_OFFLINE;
5422 5470 stmfStateSet.config_state = STMF_CONFIG_INIT_DONE;
5423 5471
5424 5472 done:
5425 5473 if (ret == STMF_STATUS_SUCCESS) {
5426 5474 ret = setStmfState(fd, &stmfStateSet, STMF_SERVICE_TYPE);
5427 5475 }
5428 5476 (void) close(fd);
5429 5477 return (ret);
5430 5478 }
5431 5479
5432 5480
5433 5481 /*
5434 5482 * getStmfState
5435 5483 *
5436 5484 * stmfState - pointer to stmf_state_desc_t structure. Will contain the state
5437 5485 * information of the stmf service on success.
5438 5486 */
5439 5487 static int
5440 5488 getStmfState(stmf_state_desc_t *stmfState)
5441 5489 {
5442 5490 int ret = STMF_STATUS_SUCCESS;
5443 5491 int fd;
5444 5492 int ioctlRet;
5445 5493 stmf_iocdata_t stmfIoctl;
5446 5494
5447 5495 /*
5448 5496 * Open control node for stmf
5449 5497 */
5450 5498 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5451 5499 return (ret);
5452 5500
5453 5501 bzero(&stmfIoctl, sizeof (stmfIoctl));
5454 5502 /*
5455 5503 * Issue ioctl to get the stmf state
5456 5504 */
5457 5505 stmfIoctl.stmf_version = STMF_VERSION_1;
5458 5506 stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
5459 5507 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
5460 5508 stmfIoctl.stmf_obuf_size = sizeof (stmf_state_desc_t);
5461 5509 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)stmfState;
5462 5510 ioctlRet = ioctl(fd, STMF_IOCTL_GET_STMF_STATE, &stmfIoctl);
5463 5511
5464 5512 (void) close(fd);
5465 5513
5466 5514 if (ioctlRet != 0) {
5467 5515 switch (errno) {
5468 5516 case EBUSY:
5469 5517 ret = STMF_ERROR_BUSY;
5470 5518 break;
5471 5519 case EPERM:
5472 5520 case EACCES:
5473 5521 ret = STMF_ERROR_PERM;
5474 5522 break;
5475 5523 default:
5476 5524 syslog(LOG_DEBUG,
5477 5525 "getStmfState:ioctl errno(%d)", errno);
5478 5526 ret = STMF_STATUS_ERROR;
5479 5527 break;
5480 5528 }
5481 5529 }
5482 5530 return (ret);
5483 5531 }
5484 5532
5485 5533
5486 5534 /*
5487 5535 * setStmfState
5488 5536 *
5489 5537 * stmfState - pointer to caller set state structure
5490 5538 * objectType - one of:
5491 5539 * LOGICAL_UNIT_TYPE
5492 5540 * TARGET_TYPE
5493 5541 * STMF_SERVICE_TYPE
5494 5542 */
5495 5543 static int
5496 5544 setStmfState(int fd, stmf_state_desc_t *stmfState, int objectType)
5497 5545 {
5498 5546 int ret = STMF_STATUS_SUCCESS;
5499 5547 int ioctlRet;
5500 5548 int cmd;
5501 5549 stmf_iocdata_t stmfIoctl;
5502 5550
5503 5551 switch (objectType) {
5504 5552 case LOGICAL_UNIT_TYPE:
5505 5553 cmd = STMF_IOCTL_SET_LU_STATE;
5506 5554 break;
5507 5555 case TARGET_TYPE:
5508 5556 cmd = STMF_IOCTL_SET_TARGET_PORT_STATE;
5509 5557 break;
5510 5558 case STMF_SERVICE_TYPE:
5511 5559 cmd = STMF_IOCTL_SET_STMF_STATE;
5512 5560 break;
5513 5561 default:
5514 5562 ret = STMF_STATUS_ERROR;
5515 5563 goto done;
5516 5564 }
5517 5565
5518 5566 bzero(&stmfIoctl, sizeof (stmfIoctl));
5519 5567 /*
5520 5568 * Issue ioctl to set the stmf state
5521 5569 */
5522 5570 stmfIoctl.stmf_version = STMF_VERSION_1;
5523 5571 stmfIoctl.stmf_ibuf_size = sizeof (stmf_state_desc_t);
5524 5572 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)stmfState;
5525 5573 ioctlRet = ioctl(fd, cmd, &stmfIoctl);
5526 5574 if (ioctlRet != 0) {
5527 5575 switch (errno) {
5528 5576 case EBUSY:
5529 5577 ret = STMF_ERROR_BUSY;
5530 5578 break;
5531 5579 case EPERM:
5532 5580 case EACCES:
5533 5581 ret = STMF_ERROR_PERM;
5534 5582 break;
5535 5583 case ENOENT:
5536 5584 ret = STMF_ERROR_NOT_FOUND;
5537 5585 break;
5538 5586 default:
5539 5587 syslog(LOG_DEBUG,
5540 5588 "setStmfState:ioctl errno(%d)", errno);
5541 5589 ret = STMF_STATUS_ERROR;
5542 5590 break;
5543 5591 }
5544 5592 }
5545 5593 done:
5546 5594 return (ret);
5547 5595 }
5548 5596 int
5549 5597 stmfSetStmfProp(uint8_t propType, char *propVal)
5550 5598 {
5551 5599 int ret = STMF_STATUS_SUCCESS;
5552 5600 switch (propType) {
5553 5601 case STMF_DEFAULT_LU_STATE:
5554 5602 break;
5555 5603 case STMF_DEFAULT_TARGET_PORT_STATE:
5556 5604 break;
5557 5605 default:
5558 5606 return (STMF_ERROR_INVALID_ARG);
5559 5607 }
5560 5608 ret = psSetStmfProp(propType, propVal);
5561 5609 switch (ret) {
5562 5610 case STMF_PS_SUCCESS:
5563 5611 ret = STMF_STATUS_SUCCESS;
5564 5612 break;
5565 5613 case STMF_PS_ERROR_BUSY:
5566 5614 ret = STMF_ERROR_BUSY;
5567 5615 break;
5568 5616 default:
5569 5617 syslog(LOG_DEBUG,
5570 5618 "stmfSetStmfProp:psSetStmfProp:error(%d)",
5571 5619 ret);
5572 5620 ret = STMF_STATUS_ERROR;
5573 5621 break;
5574 5622 }
5575 5623 return (ret);
5576 5624 }
5577 5625
5578 5626
5579 5627 int
5580 5628 stmfGetStmfProp(uint8_t propType, char *propVal, size_t *propLen)
5581 5629 {
5582 5630 int ret = STMF_STATUS_SUCCESS;
5583 5631 char prop[MAXNAMELEN] = {0};
5584 5632 size_t reqLen;
5585 5633
5586 5634 if (propVal == NULL || propLen == NULL) {
5587 5635 return (STMF_ERROR_INVALID_ARG);
5588 5636 }
5589 5637 switch (propType) {
5590 5638 case STMF_DEFAULT_LU_STATE:
5591 5639 break;
5592 5640 case STMF_DEFAULT_TARGET_PORT_STATE:
5593 5641 break;
5594 5642 default:
5595 5643 return (STMF_ERROR_INVALID_ARG);
5596 5644 }
5597 5645 ret = psGetStmfProp(propType, prop);
5598 5646 if ((reqLen = strlcpy(propVal, prop, *propLen)) >= *propLen) {
5599 5647 *propLen = reqLen + 1;
5600 5648 return (STMF_ERROR_INVALID_ARG);
5601 5649 }
5602 5650
5603 5651 switch (ret) {
5604 5652 case STMF_PS_SUCCESS:
5605 5653 ret = STMF_STATUS_SUCCESS;
5606 5654 break;
5607 5655 case STMF_PS_ERROR_BUSY:
5608 5656 ret = STMF_ERROR_BUSY;
5609 5657 break;
5610 5658 case STMF_PS_ERROR_NOT_FOUND:
5611 5659 ret = STMF_ERROR_NOT_FOUND;
5612 5660 break;
5613 5661 default:
5614 5662 syslog(LOG_DEBUG,
5615 5663 "stmfGetStmfProp:psGetStmfProp:error(%d)",
5616 5664 ret);
5617 5665 ret = STMF_STATUS_ERROR;
5618 5666 break;
5619 5667 }
5620 5668 return (ret);
5621 5669 }
5622 5670
5623 5671 static int
5624 5672 setStmfProp(stmf_set_props_t *stmf_set_props)
5625 5673 {
5626 5674 char propVal[MAXNAMELEN] = {0};
5627 5675 int ret;
5628 5676 if ((ret = psGetStmfProp(STMF_DEFAULT_LU_STATE, propVal)) ==
5629 5677 STMF_PS_SUCCESS) {
5630 5678 if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
5631 5679 stmf_set_props->default_lu_state_value =
5632 5680 STMF_STATE_OFFLINE;
5633 5681 } else {
5634 5682 stmf_set_props->default_lu_state_value =
5635 5683 STMF_STATE_ONLINE;
5636 5684 }
5637 5685 } else {
5638 5686 syslog(LOG_DEBUG,
5639 5687 "DefaultLuState:psSetStmfProp:error(%d)", ret);
5640 5688 goto done;
5641 5689 }
5642 5690
5643 5691 if ((ret = psGetStmfProp(STMF_DEFAULT_TARGET_PORT_STATE, propVal)) ==
5644 5692 STMF_PS_SUCCESS) {
5645 5693 if (strncmp(propVal, "offline", strlen(propVal)) == 0) {
5646 5694 stmf_set_props->default_target_state_value =
5647 5695 STMF_STATE_OFFLINE;
5648 5696 } else {
5649 5697 stmf_set_props->default_target_state_value =
5650 5698 STMF_STATE_ONLINE;
5651 5699 }
5652 5700 } else {
5653 5701 syslog(LOG_DEBUG,
5654 5702 "DefaultTargetPortState:psSetStmfProp:error(%d)", ret);
5655 5703 goto done;
5656 5704 }
5657 5705 done:
5658 5706 switch (ret) {
5659 5707 case STMF_PS_SUCCESS:
5660 5708 ret = STMF_STATUS_SUCCESS;
5661 5709 break;
5662 5710 case STMF_PS_ERROR_NOT_FOUND:
5663 5711 ret = STMF_ERROR_NOT_FOUND;
5664 5712 break;
5665 5713 case STMF_PS_ERROR_BUSY:
5666 5714 ret = STMF_ERROR_BUSY;
5667 5715 break;
5668 5716 default:
5669 5717 ret = STMF_STATUS_ERROR;
5670 5718 break;
5671 5719 }
5672 5720 return (ret);
5673 5721 }
5674 5722
5675 5723 static int
5676 5724 loadStmfProp(int fd)
5677 5725 {
5678 5726 int ret = STMF_STATUS_SUCCESS;
5679 5727 int ioctlRet;
5680 5728 stmf_iocdata_t stmfIoctl = {0};
5681 5729 stmf_set_props_t *stmf_set_props = NULL;
5682 5730
5683 5731 stmf_set_props = (stmf_set_props_t *)
5684 5732 calloc(1, (sizeof (stmf_set_props_t)));
5685 5733 if (stmf_set_props == NULL) {
5686 5734 ret = STMF_ERROR_NOMEM;
5687 5735 goto done;
5688 5736 }
5689 5737
5690 5738 /* Loading the default property values from smf */
5691 5739
5692 5740 if ((ret = setStmfProp(stmf_set_props)) != STMF_STATUS_SUCCESS)
5693 5741 goto done;
5694 5742
5695 5743 stmfIoctl.stmf_version = STMF_VERSION_1;
5696 5744 stmfIoctl.stmf_ibuf_size = sizeof (stmf_set_props_t);
5697 5745 stmfIoctl.stmf_ibuf =
5698 5746 (uint64_t)(unsigned long)stmf_set_props;
5699 5747
5700 5748 ioctlRet = ioctl(fd, STMF_IOCTL_SET_STMF_PROPS,
5701 5749 &stmfIoctl);
5702 5750
5703 5751 if (ioctlRet != 0) {
5704 5752 switch (errno) {
5705 5753 case EBUSY:
5706 5754 ret = STMF_ERROR_BUSY;
5707 5755 break;
5708 5756 case EPERM:
5709 5757 case EACCES:
5710 5758 ret = STMF_ERROR_PERM;
5711 5759 break;
5712 5760 case ENOENT:
5713 5761 ret = STMF_ERROR_NOT_FOUND;
5714 5762 break;
5715 5763 default:
5716 5764 syslog(LOG_DEBUG,
5717 5765 "setDefaultStmfState:"
5718 5766 "ioctl errno(%d)", errno);
5719 5767 ret = STMF_STATUS_ERROR;
5720 5768 break;
5721 5769 }
5722 5770 }
5723 5771 done:
5724 5772 if (stmf_set_props != NULL) {
5725 5773 free(stmf_set_props);
5726 5774 }
5727 5775 return (ret);
5728 5776 }
5729 5777
5730 5778 int
5731 5779 stmfLoadStmfProps(void)
5732 5780 {
5733 5781 int ret = STMF_STATUS_SUCCESS;
5734 5782 int fd;
5735 5783 /* open control node for stmf */
5736 5784 if ((ret = openStmf(OPEN_EXCL_STMF, &fd))
5737 5785 != STMF_STATUS_SUCCESS) {
5738 5786 goto done;
5739 5787 }
5740 5788 ret = loadStmfProp(fd);
5741 5789
5742 5790 (void) close(fd);
5743 5791 done:
5744 5792 if (ret != STMF_STATUS_SUCCESS) {
5745 5793 syslog(LOG_DEBUG,
5746 5794 "stmfLoadStmfProps:Failed");
5747 5795 }
5748 5796 return (ret);
5749 5797 }
5750 5798
5751 5799 /*
5752 5800 * stmfOnline
5753 5801 *
5754 5802 * Purpose: Online stmf service
5755 5803 *
5756 5804 */
5757 5805 int
5758 5806 stmfOnline(void)
5759 5807 {
5760 5808 int ret;
5761 5809 int fd;
5762 5810 stmfState state;
5763 5811 stmf_state_desc_t iState;
5764 5812
5765 5813 ret = stmfGetState(&state);
5766 5814 if (ret == STMF_STATUS_SUCCESS) {
5767 5815 if (state.operationalState == STMF_SERVICE_STATE_ONLINE) {
5768 5816 return (STMF_ERROR_SERVICE_ONLINE);
5769 5817 }
5770 5818 } else {
5771 5819 return (STMF_STATUS_ERROR);
5772 5820 }
5773 5821 iState.state = STMF_STATE_ONLINE;
5774 5822 iState.config_state = STMF_CONFIG_NONE;
5775 5823 /*
5776 5824 * Open control node for stmf
5777 5825 * to make call to setStmfState()
5778 5826 */
5779 5827 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5780 5828 return (ret);
5781 5829 ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
5782 5830 (void) close(fd);
5783 5831 return (ret);
5784 5832 }
5785 5833
5786 5834 /*
5787 5835 * stmfOffline
5788 5836 *
5789 5837 * Purpose: Offline stmf service
5790 5838 *
5791 5839 */
5792 5840 int
5793 5841 stmfOffline(void)
5794 5842 {
5795 5843 int ret;
5796 5844 int fd;
5797 5845 stmfState state;
5798 5846 stmf_state_desc_t iState;
5799 5847
5800 5848 ret = stmfGetState(&state);
5801 5849 if (ret == STMF_STATUS_SUCCESS) {
5802 5850 if (state.operationalState == STMF_SERVICE_STATE_OFFLINE) {
5803 5851 return (STMF_ERROR_SERVICE_OFFLINE);
5804 5852 }
5805 5853 } else {
5806 5854 return (STMF_STATUS_ERROR);
5807 5855 }
5808 5856 iState.state = STMF_STATE_OFFLINE;
5809 5857 iState.config_state = STMF_CONFIG_NONE;
5810 5858
5811 5859 /*
5812 5860 * Open control node for stmf
5813 5861 * to make call to setStmfState()
5814 5862 */
5815 5863 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5816 5864 return (ret);
5817 5865 ret = setStmfState(fd, &iState, STMF_SERVICE_TYPE);
5818 5866 (void) close(fd);
5819 5867 return (ret);
5820 5868 }
5821 5869
5822 5870
5823 5871 /*
5824 5872 * stmfOfflineTarget
5825 5873 *
5826 5874 * Purpose: Change state of target to offline
5827 5875 *
5828 5876 * devid - devid of the target to offline
5829 5877 */
5830 5878 int
5831 5879 stmfOfflineTarget(stmfDevid *devid)
5832 5880 {
5833 5881 stmf_state_desc_t targetState;
5834 5882 int ret = STMF_STATUS_SUCCESS;
5835 5883 int fd;
5836 5884
5837 5885 if (devid == NULL) {
5838 5886 return (STMF_ERROR_INVALID_ARG);
5839 5887 }
5840 5888 bzero(&targetState, sizeof (targetState));
5841 5889
5842 5890 targetState.state = STMF_STATE_OFFLINE;
5843 5891 targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
5844 5892 bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
5845 5893 devid->identLength);
5846 5894 /*
5847 5895 * Open control node for stmf
5848 5896 * to make call to setStmfState()
5849 5897 */
5850 5898 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5851 5899 return (ret);
5852 5900 ret = setStmfState(fd, &targetState, TARGET_TYPE);
5853 5901 (void) close(fd);
5854 5902 return (ret);
5855 5903 }
5856 5904
5857 5905 /*
5858 5906 * stmfOfflineLogicalUnit
5859 5907 *
5860 5908 * Purpose: Change state of logical unit to offline
5861 5909 *
5862 5910 * lu - guid of the logical unit to offline
5863 5911 */
5864 5912 int
5865 5913 stmfOfflineLogicalUnit(stmfGuid *lu)
5866 5914 {
5867 5915 stmf_state_desc_t luState;
5868 5916 int ret = STMF_STATUS_SUCCESS;
5869 5917 int fd;
5870 5918
5871 5919 if (lu == NULL) {
5872 5920 return (STMF_ERROR_INVALID_ARG);
5873 5921 }
5874 5922
5875 5923 bzero(&luState, sizeof (luState));
5876 5924
5877 5925 luState.state = STMF_STATE_OFFLINE;
5878 5926 bcopy(lu, &luState.ident, sizeof (stmfGuid));
5879 5927 /*
5880 5928 * Open control node for stmf
5881 5929 * to make call to setStmfState()
5882 5930 */
5883 5931 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5884 5932 return (ret);
5885 5933 ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
5886 5934 (void) close(fd);
5887 5935 return (ret);
5888 5936 }
5889 5937
5890 5938 /*
5891 5939 * stmfOnlineTarget
5892 5940 *
5893 5941 * Purpose: Change state of target to online
5894 5942 *
5895 5943 * devid - devid of the target to online
5896 5944 */
5897 5945 int
5898 5946 stmfOnlineTarget(stmfDevid *devid)
5899 5947 {
5900 5948 stmf_state_desc_t targetState;
5901 5949 int ret = STMF_STATUS_SUCCESS;
5902 5950 int fd;
5903 5951
5904 5952 if (devid == NULL) {
5905 5953 return (STMF_ERROR_INVALID_ARG);
5906 5954 }
5907 5955 bzero(&targetState, sizeof (targetState));
5908 5956
5909 5957 targetState.state = STMF_STATE_ONLINE;
5910 5958 targetState.ident[IDENT_LENGTH_BYTE] = devid->identLength;
5911 5959 bcopy(&(devid->ident), &targetState.ident[IDENT_LENGTH_BYTE + 1],
5912 5960 devid->identLength);
5913 5961 /*
5914 5962 * Open control node for stmf
5915 5963 * to make call to setStmfState()
5916 5964 */
5917 5965 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5918 5966 return (ret);
5919 5967 ret = setStmfState(fd, &targetState, TARGET_TYPE);
5920 5968 (void) close(fd);
5921 5969 return (ret);
5922 5970 }
5923 5971
5924 5972 /*
5925 5973 * stmfOnlineLogicalUnit
5926 5974 *
5927 5975 * Purpose: Change state of logical unit to online
5928 5976 *
5929 5977 * lu - guid of the logical unit to online
5930 5978 */
5931 5979 int
5932 5980 stmfOnlineLogicalUnit(stmfGuid *lu)
5933 5981 {
5934 5982 stmf_state_desc_t luState;
5935 5983 int ret = STMF_STATUS_SUCCESS;
5936 5984 int fd;
5937 5985
5938 5986 if (lu == NULL) {
5939 5987 return (STMF_ERROR_INVALID_ARG);
5940 5988 }
5941 5989
5942 5990 bzero(&luState, sizeof (luState));
5943 5991
5944 5992 luState.state = STMF_STATE_ONLINE;
5945 5993 bcopy(lu, &luState.ident, sizeof (stmfGuid));
5946 5994 /*
5947 5995 * Open control node for stmf
5948 5996 * to make call to setStmfState()
5949 5997 */
5950 5998 if ((ret = openStmf(OPEN_EXCL_STMF, &fd)) != STMF_STATUS_SUCCESS)
5951 5999 return (ret);
5952 6000 ret = setStmfState(fd, &luState, LOGICAL_UNIT_TYPE);
5953 6001 (void) close(fd);
5954 6002 return (ret);
5955 6003 }
5956 6004
5957 6005 /*
5958 6006 * stmfRemoveFromHostGroup
5959 6007 *
5960 6008 * Purpose: Removes an initiator from an initiator group
5961 6009 *
5962 6010 * hostGroupName - name of an initiator group
5963 6011 * hostName - name of host group member to remove
5964 6012 */
5965 6013 int
5966 6014 stmfRemoveFromHostGroup(stmfGroupName *hostGroupName, stmfDevid *hostName)
5967 6015 {
5968 6016 int ret;
5969 6017 int fd;
5970 6018
5971 6019 if (hostGroupName == NULL ||
5972 6020 (strnlen((char *)hostGroupName, sizeof (stmfGroupName))
5973 6021 == sizeof (stmfGroupName)) || hostName == NULL) {
5974 6022 return (STMF_ERROR_INVALID_ARG);
5975 6023 }
5976 6024
5977 6025 /* call init */
5978 6026 ret = initializeConfig();
5979 6027 if (ret != STMF_STATUS_SUCCESS) {
5980 6028 return (ret);
5981 6029 }
5982 6030
5983 6031 /*
5984 6032 * Open control node for stmf
5985 6033 */
5986 6034 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
5987 6035 return (ret);
5988 6036
5989 6037 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_HG_ENTRY,
5990 6038 hostGroupName, hostName)) != STMF_STATUS_SUCCESS) {
5991 6039 goto done;
5992 6040 }
5993 6041
5994 6042 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
5995 6043 goto done;
5996 6044 }
5997 6045
5998 6046 ret = psRemoveHostGroupMember((char *)hostGroupName,
5999 6047 (char *)hostName->ident);
6000 6048 switch (ret) {
6001 6049 case STMF_PS_SUCCESS:
6002 6050 ret = STMF_STATUS_SUCCESS;
6003 6051 break;
6004 6052 case STMF_PS_ERROR_MEMBER_NOT_FOUND:
6005 6053 ret = STMF_ERROR_MEMBER_NOT_FOUND;
6006 6054 break;
6007 6055 case STMF_PS_ERROR_GROUP_NOT_FOUND:
6008 6056 ret = STMF_ERROR_GROUP_NOT_FOUND;
6009 6057 break;
6010 6058 case STMF_PS_ERROR_BUSY:
6011 6059 ret = STMF_ERROR_BUSY;
6012 6060 break;
6013 6061 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6014 6062 ret = STMF_ERROR_SERVICE_NOT_FOUND;
6015 6063 break;
6016 6064 case STMF_PS_ERROR_VERSION_MISMATCH:
6017 6065 ret = STMF_ERROR_SERVICE_DATA_VERSION;
6018 6066 break;
6019 6067 default:
6020 6068 syslog(LOG_DEBUG,
6021 6069 "stmfRemoveFromHostGroup"
6022 6070 "psRemoveHostGroupMember:error(%d)", ret);
6023 6071 ret = STMF_STATUS_ERROR;
6024 6072 break;
6025 6073 }
6026 6074
6027 6075 done:
6028 6076 (void) close(fd);
6029 6077 return (ret);
6030 6078 }
6031 6079
6032 6080 /*
6033 6081 * stmfRemoveFromTargetGroup
6034 6082 *
6035 6083 * Purpose: Removes a local port from a local port group
6036 6084 *
6037 6085 * targetGroupName - name of a target group
6038 6086 * targetName - name of target to remove
6039 6087 */
6040 6088 int
6041 6089 stmfRemoveFromTargetGroup(stmfGroupName *targetGroupName, stmfDevid *targetName)
6042 6090 {
6043 6091 int ret;
6044 6092 int fd;
6045 6093
6046 6094 if (targetGroupName == NULL ||
6047 6095 (strnlen((char *)targetGroupName, sizeof (stmfGroupName))
6048 6096 == sizeof (stmfGroupName)) || targetName == NULL) {
6049 6097 return (STMF_ERROR_INVALID_ARG);
6050 6098 }
6051 6099
6052 6100 /* call init */
6053 6101 ret = initializeConfig();
6054 6102 if (ret != STMF_STATUS_SUCCESS) {
6055 6103 return (ret);
6056 6104 }
6057 6105
6058 6106 /*
6059 6107 * Open control node for stmf
6060 6108 */
6061 6109 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6062 6110 return (ret);
6063 6111
6064 6112 if ((ret = groupMemberIoctl(fd, STMF_IOCTL_REMOVE_TG_ENTRY,
6065 6113 targetGroupName, targetName)) != STMF_STATUS_SUCCESS) {
6066 6114 goto done;
6067 6115 }
6068 6116
6069 6117 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6070 6118 goto done;
6071 6119 }
6072 6120
6073 6121 ret = psRemoveTargetGroupMember((char *)targetGroupName,
6074 6122 (char *)targetName->ident);
6075 6123 switch (ret) {
6076 6124 case STMF_PS_SUCCESS:
6077 6125 ret = STMF_STATUS_SUCCESS;
6078 6126 break;
6079 6127 case STMF_PS_ERROR_MEMBER_NOT_FOUND:
6080 6128 ret = STMF_ERROR_MEMBER_NOT_FOUND;
6081 6129 break;
6082 6130 case STMF_PS_ERROR_GROUP_NOT_FOUND:
6083 6131 ret = STMF_ERROR_GROUP_NOT_FOUND;
6084 6132 break;
6085 6133 case STMF_PS_ERROR_BUSY:
6086 6134 ret = STMF_ERROR_BUSY;
6087 6135 break;
6088 6136 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6089 6137 ret = STMF_ERROR_SERVICE_NOT_FOUND;
6090 6138 break;
6091 6139 case STMF_PS_ERROR_VERSION_MISMATCH:
6092 6140 ret = STMF_ERROR_SERVICE_DATA_VERSION;
6093 6141 break;
6094 6142 default:
6095 6143 syslog(LOG_DEBUG,
6096 6144 "stmfRemoveFromTargetGroup"
6097 6145 "psRemoveTargetGroupMember:error(%d)", ret);
6098 6146 ret = STMF_STATUS_ERROR;
6099 6147 break;
6100 6148 }
6101 6149
6102 6150 done:
6103 6151 (void) close(fd);
6104 6152 return (ret);
6105 6153 }
6106 6154
6107 6155 /*
6108 6156 * stmfRemoveViewEntry
6109 6157 *
6110 6158 * Purpose: Removes a view entry from a logical unit
6111 6159 *
6112 6160 * lu - guid of lu for which view entry is being removed
6113 6161 * viewEntryIndex - index of view entry to remove
6114 6162 *
6115 6163 */
6116 6164 int
6117 6165 stmfRemoveViewEntry(stmfGuid *lu, uint32_t viewEntryIndex)
6118 6166 {
6119 6167 int ret = STMF_STATUS_SUCCESS;
6120 6168 int fd;
6121 6169 int ioctlRet;
6122 6170 stmf_iocdata_t stmfIoctl;
6123 6171 stmf_view_op_entry_t ioctlViewEntry;
6124 6172
6125 6173 if (lu == NULL) {
6126 6174 return (STMF_ERROR_INVALID_ARG);
6127 6175 }
6128 6176
6129 6177 /* call init */
6130 6178 ret = initializeConfig();
6131 6179 if (ret != STMF_STATUS_SUCCESS) {
6132 6180 return (ret);
6133 6181 }
6134 6182
6135 6183 /*
6136 6184 * Open control node for stmf
6137 6185 */
6138 6186 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6139 6187 return (ret);
6140 6188
6141 6189 bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6142 6190 ioctlViewEntry.ve_ndx_valid = B_TRUE;
6143 6191 ioctlViewEntry.ve_ndx = viewEntryIndex;
6144 6192 bcopy(lu, &ioctlViewEntry.ve_guid, sizeof (stmfGuid));
6145 6193
6146 6194 bzero(&stmfIoctl, sizeof (stmfIoctl));
6147 6195 /*
6148 6196 * Issue ioctl to add to the view entry
6149 6197 */
6150 6198 stmfIoctl.stmf_version = STMF_VERSION_1;
6151 6199 stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6152 6200 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6153 6201 ioctlRet = ioctl(fd, STMF_IOCTL_REMOVE_VIEW_ENTRY, &stmfIoctl);
6154 6202 if (ioctlRet != 0) {
6155 6203 switch (errno) {
6156 6204 case EBUSY:
6157 6205 ret = STMF_ERROR_BUSY;
6158 6206 break;
6159 6207 case EPERM:
6160 6208 ret = STMF_ERROR_PERM;
6161 6209 break;
6162 6210 case EACCES:
6163 6211 switch (stmfIoctl.stmf_error) {
6164 6212 case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6165 6213 ret = STMF_ERROR_CONFIG_NONE;
6166 6214 break;
6167 6215 default:
6168 6216 ret = STMF_ERROR_PERM;
6169 6217 break;
6170 6218 }
6171 6219 break;
6172 6220 case ENODEV:
6173 6221 case ENOENT:
6174 6222 ret = STMF_ERROR_NOT_FOUND;
6175 6223 break;
6176 6224 default:
6177 6225 syslog(LOG_DEBUG,
6178 6226 "stmfRemoveViewEntry:ioctl errno(%d)",
6179 6227 errno);
6180 6228 ret = STMF_STATUS_ERROR;
6181 6229 break;
6182 6230 }
6183 6231 goto done;
6184 6232 }
6185 6233
6186 6234 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6187 6235 goto done;
6188 6236 }
6189 6237
6190 6238 ret = psRemoveViewEntry(lu, viewEntryIndex);
6191 6239 switch (ret) {
6192 6240 case STMF_PS_SUCCESS:
6193 6241 ret = STMF_STATUS_SUCCESS;
6194 6242 break;
6195 6243 case STMF_PS_ERROR_NOT_FOUND:
6196 6244 ret = STMF_ERROR_NOT_FOUND;
6197 6245 break;
6198 6246 case STMF_PS_ERROR_BUSY:
6199 6247 ret = STMF_ERROR_BUSY;
6200 6248 break;
6201 6249 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6202 6250 ret = STMF_ERROR_SERVICE_NOT_FOUND;
6203 6251 break;
6204 6252 case STMF_PS_ERROR_VERSION_MISMATCH:
6205 6253 ret = STMF_ERROR_SERVICE_DATA_VERSION;
6206 6254 break;
6207 6255 default:
6208 6256 syslog(LOG_DEBUG,
6209 6257 "stmfRemoveViewEntry" "psRemoveViewEntry:error(%d)",
6210 6258 ret);
6211 6259 ret = STMF_STATUS_ERROR;
6212 6260 break;
6213 6261 }
6214 6262
6215 6263 done:
6216 6264 (void) close(fd);
6217 6265 return (ret);
6218 6266 }
6219 6267
6220 6268 /*
6221 6269 * stmfSetProviderData
6222 6270 *
6223 6271 * Purpose: set the provider data
6224 6272 *
6225 6273 * providerName - unique name of provider
6226 6274 * nvl - nvlist to set
6227 6275 * providerType - type of provider for which to set data
6228 6276 * STMF_LU_PROVIDER_TYPE
6229 6277 * STMF_PORT_PROVIDER_TYPE
6230 6278 */
6231 6279 int
6232 6280 stmfSetProviderData(char *providerName, nvlist_t *nvl, int providerType)
6233 6281 {
6234 6282 return (stmfSetProviderDataProt(providerName, nvl, providerType,
6235 6283 NULL));
6236 6284 }
6237 6285
6238 6286 /*
6239 6287 * stmfSetProviderDataProt
6240 6288 *
6241 6289 * Purpose: set the provider data
6242 6290 *
6243 6291 * providerName - unique name of provider
6244 6292 * nvl - nvlist to set
6245 6293 * providerType - type of provider for which to set data
6246 6294 * STMF_LU_PROVIDER_TYPE
6247 6295 * STMF_PORT_PROVIDER_TYPE
6248 6296 * setToken - Stale data token returned in the stmfGetProviderDataProt()
6249 6297 * call or NULL.
6250 6298 */
6251 6299 int
6252 6300 stmfSetProviderDataProt(char *providerName, nvlist_t *nvl, int providerType,
6253 6301 uint64_t *setToken)
6254 6302 {
6255 6303 int ret;
6256 6304 int fd;
6257 6305
6258 6306 if (providerName == NULL || nvl == NULL) {
6259 6307 return (STMF_ERROR_INVALID_ARG);
6260 6308 }
6261 6309
6262 6310 if (providerType != STMF_LU_PROVIDER_TYPE &&
6263 6311 providerType != STMF_PORT_PROVIDER_TYPE) {
6264 6312 return (STMF_ERROR_INVALID_ARG);
6265 6313 }
6266 6314
6267 6315 /* call init */
6268 6316 ret = initializeConfig();
6269 6317 if (ret != STMF_STATUS_SUCCESS) {
6270 6318 return (ret);
6271 6319 }
6272 6320
6273 6321 /*
6274 6322 * Open control node for stmf
6275 6323 */
6276 6324 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6277 6325 return (ret);
6278 6326
6279 6327 ret = setProviderData(fd, providerName, nvl, providerType, setToken);
6280 6328
6281 6329 (void) close(fd);
6282 6330
6283 6331 if (ret != STMF_STATUS_SUCCESS) {
6284 6332 goto done;
6285 6333 }
6286 6334
6287 6335 if (iGetPersistMethod() == STMF_PERSIST_NONE) {
6288 6336 goto done;
6289 6337 }
6290 6338
6291 6339 /* setting driver provider data successful. Now persist it */
6292 6340 ret = psSetProviderData(providerName, nvl, providerType, NULL);
6293 6341 switch (ret) {
6294 6342 case STMF_PS_SUCCESS:
6295 6343 ret = STMF_STATUS_SUCCESS;
6296 6344 break;
6297 6345 case STMF_PS_ERROR_EXISTS:
6298 6346 ret = STMF_ERROR_EXISTS;
6299 6347 break;
6300 6348 case STMF_PS_ERROR_BUSY:
6301 6349 ret = STMF_ERROR_BUSY;
6302 6350 break;
6303 6351 case STMF_PS_ERROR_SERVICE_NOT_FOUND:
6304 6352 ret = STMF_ERROR_SERVICE_NOT_FOUND;
6305 6353 break;
6306 6354 case STMF_PS_ERROR_VERSION_MISMATCH:
6307 6355 ret = STMF_ERROR_SERVICE_DATA_VERSION;
6308 6356 break;
6309 6357 case STMF_PS_ERROR_PROV_DATA_STALE:
6310 6358 ret = STMF_ERROR_PROV_DATA_STALE;
6311 6359 break;
6312 6360 default:
6313 6361 syslog(LOG_DEBUG,
6314 6362 "stmfSetProviderData"
6315 6363 "psSetProviderData:error(%d)", ret);
6316 6364 ret = STMF_STATUS_ERROR;
6317 6365 break;
6318 6366 }
6319 6367
6320 6368 done:
6321 6369 return (ret);
6322 6370 }
6323 6371
6324 6372 /*
6325 6373 * getProviderData
6326 6374 *
6327 6375 * Purpose: set the provider data from stmf
6328 6376 *
6329 6377 * providerName - unique name of provider
6330 6378 * nvl - nvlist to load/retrieve
6331 6379 * providerType - logical unit or port provider
6332 6380 * setToken - returned stale data token
6333 6381 */
6334 6382 int
6335 6383 getProviderData(char *providerName, nvlist_t **nvl, int providerType,
6336 6384 uint64_t *setToken)
6337 6385 {
6338 6386 int ret = STMF_STATUS_SUCCESS;
6339 6387 int fd;
6340 6388 int ioctlRet;
6341 6389 size_t nvlistSize = ALLOC_PP_DATA_SIZE;
6342 6390 int retryCnt = 0;
6343 6391 int retryCntMax = MAX_PROVIDER_RETRY;
6344 6392 stmf_ppioctl_data_t ppi = {0}, *ppi_out = NULL;
6345 6393 boolean_t retry = B_TRUE;
6346 6394 stmf_iocdata_t stmfIoctl;
6347 6395
6348 6396 if (providerName == NULL) {
6349 6397 return (STMF_ERROR_INVALID_ARG);
6350 6398 }
6351 6399
6352 6400 /*
6353 6401 * Open control node for stmf
6354 6402 */
6355 6403 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6356 6404 return (ret);
6357 6405
6358 6406 /* set provider name and provider type */
6359 6407 if (strlcpy(ppi.ppi_name, providerName,
6360 6408 sizeof (ppi.ppi_name)) >=
6361 6409 sizeof (ppi.ppi_name)) {
6362 6410 ret = STMF_ERROR_INVALID_ARG;
6363 6411 goto done;
6364 6412 }
6365 6413 switch (providerType) {
6366 6414 case STMF_LU_PROVIDER_TYPE:
6367 6415 ppi.ppi_lu_provider = 1;
6368 6416 break;
6369 6417 case STMF_PORT_PROVIDER_TYPE:
6370 6418 ppi.ppi_port_provider = 1;
6371 6419 break;
6372 6420 default:
6373 6421 ret = STMF_ERROR_INVALID_ARG;
6374 6422 goto done;
6375 6423 }
6376 6424
6377 6425 do {
6378 6426 /* allocate memory for ioctl */
6379 6427 ppi_out = (stmf_ppioctl_data_t *)calloc(1, nvlistSize +
6380 6428 sizeof (stmf_ppioctl_data_t));
6381 6429 if (ppi_out == NULL) {
6382 6430 ret = STMF_ERROR_NOMEM;
6383 6431 goto done;
6384 6432
6385 6433 }
6386 6434
6387 6435 /* set the size of the ioctl data to allocated buffer */
6388 6436 ppi.ppi_data_size = nvlistSize;
6389 6437
6390 6438 bzero(&stmfIoctl, sizeof (stmfIoctl));
6391 6439
6392 6440 stmfIoctl.stmf_version = STMF_VERSION_1;
6393 6441 stmfIoctl.stmf_ibuf_size = sizeof (stmf_ppioctl_data_t);
6394 6442 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ppi;
6395 6443 stmfIoctl.stmf_obuf_size = sizeof (stmf_ppioctl_data_t) +
6396 6444 nvlistSize;
6397 6445 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)ppi_out;
6398 6446 ioctlRet = ioctl(fd, STMF_IOCTL_GET_PP_DATA, &stmfIoctl);
6399 6447 if (ioctlRet != 0) {
6400 6448 switch (errno) {
6401 6449 case EBUSY:
6402 6450 ret = STMF_ERROR_BUSY;
6403 6451 break;
6404 6452 case EPERM:
6405 6453 case EACCES:
6406 6454 ret = STMF_ERROR_PERM;
6407 6455 break;
6408 6456 case EINVAL:
6409 6457 if (stmfIoctl.stmf_error ==
6410 6458 STMF_IOCERR_INSUFFICIENT_BUF) {
6411 6459 nvlistSize =
6412 6460 ppi_out->ppi_data_size;
6413 6461 free(ppi_out);
6414 6462 ppi_out = NULL;
6415 6463 if (retryCnt++ > retryCntMax) {
6416 6464 retry = B_FALSE;
6417 6465 ret = STMF_ERROR_BUSY;
6418 6466 } else {
6419 6467 ret =
6420 6468 STMF_STATUS_SUCCESS;
6421 6469 }
6422 6470 } else {
6423 6471 syslog(LOG_DEBUG,
6424 6472 "getProviderData:ioctl"
6425 6473 "unable to retrieve "
6426 6474 "nvlist");
6427 6475 ret = STMF_STATUS_ERROR;
6428 6476 }
6429 6477 break;
6430 6478 case ENOENT:
6431 6479 ret = STMF_ERROR_NOT_FOUND;
6432 6480 break;
6433 6481 default:
6434 6482 syslog(LOG_DEBUG,
6435 6483 "getProviderData:ioctl errno(%d)",
6436 6484 errno);
6437 6485 ret = STMF_STATUS_ERROR;
6438 6486 break;
6439 6487 }
6440 6488 if (ret != STMF_STATUS_SUCCESS)
6441 6489 goto done;
6442 6490 }
6443 6491 } while (retry && stmfIoctl.stmf_error == STMF_IOCERR_INSUFFICIENT_BUF);
6444 6492
6445 6493 if ((ret = nvlist_unpack((char *)ppi_out->ppi_data,
6446 6494 ppi_out->ppi_data_size, nvl, 0)) != 0) {
6447 6495 ret = STMF_STATUS_ERROR;
6448 6496 goto done;
6449 6497 }
6450 6498
6451 6499 /* caller has asked for new token */
6452 6500 if (setToken) {
6453 6501 *setToken = ppi_out->ppi_token;
6454 6502 }
6455 6503 done:
6456 6504 free(ppi_out);
6457 6505 (void) close(fd);
6458 6506 return (ret);
6459 6507 }
6460 6508
6461 6509 /*
6462 6510 * setProviderData
6463 6511 *
6464 6512 * Purpose: set the provider data in stmf
6465 6513 *
6466 6514 * providerName - unique name of provider
6467 6515 * nvl - nvlist to set
6468 6516 * providerType - logical unit or port provider
6469 6517 * setToken - stale data token to check if not NULL
6470 6518 */
6471 6519 static int
6472 6520 setProviderData(int fd, char *providerName, nvlist_t *nvl, int providerType,
6473 6521 uint64_t *setToken)
6474 6522 {
6475 6523 int ret = STMF_STATUS_SUCCESS;
6476 6524 int ioctlRet;
6477 6525 size_t nvlistEncodedSize;
6478 6526 stmf_ppioctl_data_t *ppi = NULL;
6479 6527 uint64_t outToken;
6480 6528 char *allocatedNvBuffer;
6481 6529 stmf_iocdata_t stmfIoctl;
6482 6530
6483 6531 if (providerName == NULL) {
6484 6532 return (STMF_ERROR_INVALID_ARG);
6485 6533 }
6486 6534
6487 6535 /* get size of encoded nvlist */
6488 6536 if (nvlist_size(nvl, &nvlistEncodedSize, NV_ENCODE_XDR) != 0) {
6489 6537 return (STMF_STATUS_ERROR);
6490 6538 }
6491 6539
6492 6540 /* allocate memory for ioctl */
6493 6541 ppi = (stmf_ppioctl_data_t *)calloc(1, nvlistEncodedSize +
6494 6542 sizeof (stmf_ppioctl_data_t));
6495 6543 if (ppi == NULL) {
6496 6544 return (STMF_ERROR_NOMEM);
6497 6545 }
6498 6546
6499 6547 if (setToken) {
6500 6548 ppi->ppi_token_valid = 1;
6501 6549 ppi->ppi_token = *setToken;
6502 6550 }
6503 6551
6504 6552 allocatedNvBuffer = (char *)&ppi->ppi_data;
6505 6553 if (nvlist_pack(nvl, &allocatedNvBuffer, &nvlistEncodedSize,
6506 6554 NV_ENCODE_XDR, 0) != 0) {
6507 6555 return (STMF_STATUS_ERROR);
6508 6556 }
6509 6557
6510 6558 /* set provider name and provider type */
6511 6559 (void) strncpy(ppi->ppi_name, providerName, sizeof (ppi->ppi_name));
6512 6560 switch (providerType) {
6513 6561 case STMF_LU_PROVIDER_TYPE:
6514 6562 ppi->ppi_lu_provider = 1;
6515 6563 break;
6516 6564 case STMF_PORT_PROVIDER_TYPE:
6517 6565 ppi->ppi_port_provider = 1;
6518 6566 break;
6519 6567 default:
6520 6568 return (STMF_ERROR_INVALID_ARG);
6521 6569 }
6522 6570
6523 6571 /* set the size of the ioctl data to packed data size */
6524 6572 ppi->ppi_data_size = nvlistEncodedSize;
6525 6573
6526 6574 bzero(&stmfIoctl, sizeof (stmfIoctl));
6527 6575
6528 6576 stmfIoctl.stmf_version = STMF_VERSION_1;
6529 6577 /*
6530 6578 * Subtracting 8 from the size as that is the size of the last member
6531 6579 * of the structure where the packed data resides
6532 6580 */
6533 6581 stmfIoctl.stmf_ibuf_size = nvlistEncodedSize +
6534 6582 sizeof (stmf_ppioctl_data_t) - 8;
6535 6583 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)ppi;
6536 6584 stmfIoctl.stmf_obuf_size = sizeof (uint64_t);
6537 6585 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&outToken;
6538 6586 ioctlRet = ioctl(fd, STMF_IOCTL_LOAD_PP_DATA, &stmfIoctl);
6539 6587 if (ioctlRet != 0) {
6540 6588 switch (errno) {
6541 6589 case EBUSY:
6542 6590 ret = STMF_ERROR_BUSY;
6543 6591 break;
6544 6592 case EPERM:
6545 6593 case EACCES:
6546 6594 ret = STMF_ERROR_PERM;
6547 6595 break;
6548 6596 case EINVAL:
6549 6597 if (stmfIoctl.stmf_error ==
6550 6598 STMF_IOCERR_PPD_UPDATED) {
6551 6599 ret = STMF_ERROR_PROV_DATA_STALE;
6552 6600 } else {
6553 6601 ret = STMF_STATUS_ERROR;
6554 6602 }
6555 6603 break;
6556 6604 default:
6557 6605 syslog(LOG_DEBUG,
6558 6606 "setProviderData:ioctl errno(%d)", errno);
6559 6607 ret = STMF_STATUS_ERROR;
6560 6608 break;
6561 6609 }
6562 6610 if (ret != STMF_STATUS_SUCCESS)
6563 6611 goto done;
6564 6612 }
6565 6613
6566 6614 /* caller has asked for new token */
6567 6615 if (setToken) {
6568 6616 *setToken = outToken;
6569 6617 }
6570 6618 done:
6571 6619 free(ppi);
6572 6620 return (ret);
6573 6621 }
6574 6622
6575 6623 /*
6576 6624 * set the persistence method in the library only or library and service
6577 6625 */
6578 6626 int
6579 6627 stmfSetPersistMethod(uint8_t persistType, boolean_t serviceSet)
6580 6628 {
6581 6629 int ret = STMF_STATUS_SUCCESS;
6582 6630 int oldPersist;
6583 6631
6584 6632 (void) pthread_mutex_lock(&persistenceTypeLock);
6585 6633 oldPersist = iPersistType;
6586 6634 if (persistType == STMF_PERSIST_NONE ||
6587 6635 persistType == STMF_PERSIST_SMF) {
6588 6636 iLibSetPersist = B_TRUE;
6589 6637 iPersistType = persistType;
6590 6638 } else {
6591 6639 (void) pthread_mutex_unlock(&persistenceTypeLock);
6592 6640 return (STMF_ERROR_INVALID_ARG);
6593 6641 }
6594 6642 /* Is this for this library open or in SMF */
6595 6643 if (serviceSet == B_TRUE) {
6596 6644 ret = psSetServicePersist(persistType);
6597 6645 if (ret != STMF_PS_SUCCESS) {
6598 6646 ret = STMF_ERROR_PERSIST_TYPE;
6599 6647 /* Set to old value */
6600 6648 iPersistType = oldPersist;
6601 6649 }
6602 6650 }
6603 6651 (void) pthread_mutex_unlock(&persistenceTypeLock);
6604 6652
6605 6653 return (ret);
6606 6654 }
6607 6655
6608 6656 /*
6609 6657 * Only returns internal state for persist. If unset, goes to ps. If that
6610 6658 * fails, returns default setting
6611 6659 */
6612 6660 static uint8_t
6613 6661 iGetPersistMethod()
6614 6662 {
6615 6663
6616 6664 uint8_t persistType = 0;
6617 6665
6618 6666 (void) pthread_mutex_lock(&persistenceTypeLock);
6619 6667 if (iLibSetPersist) {
6620 6668 persistType = iPersistType;
6621 6669 } else {
6622 6670 int ret;
6623 6671 ret = psGetServicePersist(&persistType);
6624 6672 if (ret != STMF_PS_SUCCESS) {
6625 6673 /* set to default */
6626 6674 persistType = STMF_DEFAULT_PERSIST;
6627 6675 }
6628 6676 }
6629 6677 (void) pthread_mutex_unlock(&persistenceTypeLock);
6630 6678 return (persistType);
6631 6679 }
6632 6680
6633 6681 /*
6634 6682 * Returns either library state or persistent config state depending on
6635 6683 * serviceState
6636 6684 */
6637 6685 int
6638 6686 stmfGetPersistMethod(uint8_t *persistType, boolean_t serviceState)
6639 6687 {
6640 6688 int ret = STMF_STATUS_SUCCESS;
6641 6689
6642 6690 if (persistType == NULL) {
6643 6691 return (STMF_ERROR_INVALID_ARG);
6644 6692 }
6645 6693 if (serviceState) {
6646 6694 ret = psGetServicePersist(persistType);
6647 6695 if (ret != STMF_PS_SUCCESS) {
6648 6696 ret = STMF_ERROR_PERSIST_TYPE;
6649 6697 }
6650 6698 } else {
6651 6699 (void) pthread_mutex_lock(&persistenceTypeLock);
6652 6700 if (iLibSetPersist) {
6653 6701 *persistType = iPersistType;
6654 6702 } else {
6655 6703 *persistType = STMF_DEFAULT_PERSIST;
6656 6704 }
6657 6705 (void) pthread_mutex_unlock(&persistenceTypeLock);
6658 6706 }
6659 6707
6660 6708 return (ret);
6661 6709 }
6662 6710
6663 6711 /*
6664 6712 * stmfPostProxyMsg
6665 6713 *
6666 6714 * Purpose: Post a message to the proxy port provider
6667 6715 *
6668 6716 * buf - buffer containing message to post
6669 6717 * buflen - buffer length
6670 6718 */
6671 6719 int
6672 6720 stmfPostProxyMsg(int hdl, void *buf, uint32_t buflen)
6673 6721 {
6674 6722 int ret = STMF_STATUS_SUCCESS;
6675 6723 int ioctlRet;
6676 6724 pppt_iocdata_t ppptIoctl = {0};
6677 6725
6678 6726 if (buf == NULL) {
6679 6727 return (STMF_ERROR_INVALID_ARG);
6680 6728 }
6681 6729
6682 6730 /*
6683 6731 * Issue ioctl to post the message
6684 6732 */
6685 6733 ppptIoctl.pppt_version = PPPT_VERSION_1;
6686 6734 ppptIoctl.pppt_buf_size = buflen;
6687 6735 ppptIoctl.pppt_buf = (uint64_t)(unsigned long)buf;
6688 6736 ioctlRet = ioctl(hdl, PPPT_MESSAGE, &ppptIoctl);
6689 6737 if (ioctlRet != 0) {
6690 6738 switch (errno) {
6691 6739 case EPERM:
6692 6740 case EACCES:
6693 6741 ret = STMF_ERROR_PERM;
6694 6742 break;
6695 6743 default:
6696 6744 ret = STMF_ERROR_POST_MSG_FAILED;
6697 6745 break;
6698 6746 }
6699 6747 }
6700 6748
6701 6749 return (ret);
6702 6750 }
6703 6751
6704 6752 /*
6705 6753 * stmfInitProxyDoor
6706 6754 *
6707 6755 * Purpose: Install door in proxy
6708 6756 *
6709 6757 * hdl - pointer to returned handle
6710 6758 * fd - door from door_create()
6711 6759 */
6712 6760 int
6713 6761 stmfInitProxyDoor(int *hdl, int door)
6714 6762 {
6715 6763 int ret = STMF_STATUS_SUCCESS;
6716 6764 int ioctlRet;
6717 6765 int fd;
6718 6766 pppt_iocdata_t ppptIoctl = {0};
6719 6767
6720 6768 if (hdl == NULL) {
6721 6769 return (STMF_ERROR_INVALID_ARG);
6722 6770 }
6723 6771
6724 6772 /*
6725 6773 * Open control node for pppt
6726 6774 */
6727 6775 if ((ret = openPppt(OPEN_PPPT, &fd)) != STMF_STATUS_SUCCESS) {
6728 6776 return (ret);
6729 6777 }
6730 6778
6731 6779 /*
6732 6780 * Issue ioctl to install the door
6733 6781 */
6734 6782 ppptIoctl.pppt_version = PPPT_VERSION_1;
6735 6783 ppptIoctl.pppt_door_fd = (uint32_t)door;
6736 6784 ioctlRet = ioctl(fd, PPPT_INSTALL_DOOR, &ppptIoctl);
6737 6785 if (ioctlRet != 0) {
6738 6786 switch (errno) {
6739 6787 case EPERM:
6740 6788 case EACCES:
6741 6789 ret = STMF_ERROR_PERM;
6742 6790 break;
6743 6791 case EINVAL:
6744 6792 ret = STMF_ERROR_INVALID_ARG;
6745 6793 break;
6746 6794 case EBUSY:
6747 6795 ret = STMF_ERROR_DOOR_INSTALLED;
6748 6796 break;
6749 6797 default:
6750 6798 ret = STMF_STATUS_ERROR;
6751 6799 break;
6752 6800 }
6753 6801 }
6754 6802
6755 6803 /* return driver fd to caller */
6756 6804 *hdl = fd;
6757 6805 return (ret);
6758 6806 }
6759 6807
6760 6808 void
6761 6809 stmfDestroyProxyDoor(int hdl)
6762 6810 {
6763 6811 (void) close(hdl);
6764 6812 }
6765 6813
6766 6814 /*
6767 6815 * validateLunNumIoctl
6768 6816 *
6769 6817 * Purpose: Issues ioctl to check and get available lun# in view entry
6770 6818 *
6771 6819 * viewEntry - view entry to use
6772 6820 */
6773 6821 static int
6774 6822 validateLunNumIoctl(int fd, stmfViewEntry *viewEntry)
6775 6823 {
6776 6824 int ret = STMF_STATUS_SUCCESS;
6777 6825 int ioctlRet;
6778 6826 stmf_iocdata_t stmfIoctl;
6779 6827 stmf_view_op_entry_t ioctlViewEntry;
6780 6828
6781 6829 bzero(&ioctlViewEntry, sizeof (ioctlViewEntry));
6782 6830 /*
6783 6831 * don't set ve_ndx or ve_ndx_valid as ve_ndx_valid should be
6784 6832 * false on input
6785 6833 */
6786 6834 ioctlViewEntry.ve_lu_number_valid = viewEntry->luNbrValid;
6787 6835 ioctlViewEntry.ve_all_hosts = viewEntry->allHosts;
6788 6836 ioctlViewEntry.ve_all_targets = viewEntry->allTargets;
6789 6837
6790 6838 if (viewEntry->allHosts == B_FALSE) {
6791 6839 bcopy(viewEntry->hostGroup, &ioctlViewEntry.ve_host_group.name,
6792 6840 sizeof (stmfGroupName));
6793 6841 ioctlViewEntry.ve_host_group.name_size =
6794 6842 strlen((char *)viewEntry->hostGroup);
6795 6843 }
6796 6844 if (viewEntry->allTargets == B_FALSE) {
6797 6845 bcopy(viewEntry->targetGroup,
6798 6846 &ioctlViewEntry.ve_target_group.name,
6799 6847 sizeof (stmfGroupName));
6800 6848 ioctlViewEntry.ve_target_group.name_size =
6801 6849 strlen((char *)viewEntry->targetGroup);
6802 6850 }
6803 6851 /* Validating the lun number */
6804 6852 if (viewEntry->luNbrValid) {
6805 6853 bcopy(viewEntry->luNbr, &ioctlViewEntry.ve_lu_nbr,
6806 6854 sizeof (ioctlViewEntry.ve_lu_nbr));
6807 6855 }
6808 6856
6809 6857 bzero(&stmfIoctl, sizeof (stmfIoctl));
6810 6858 /*
6811 6859 * Issue ioctl to validate lun# in the view entry
6812 6860 */
6813 6861 stmfIoctl.stmf_version = STMF_VERSION_1;
6814 6862 stmfIoctl.stmf_ibuf_size = sizeof (ioctlViewEntry);
6815 6863 stmfIoctl.stmf_ibuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6816 6864 stmfIoctl.stmf_obuf_size = sizeof (ioctlViewEntry);
6817 6865 stmfIoctl.stmf_obuf = (uint64_t)(unsigned long)&ioctlViewEntry;
6818 6866 ioctlRet = ioctl(fd, STMF_IOCTL_VALIDATE_VIEW, &stmfIoctl);
6819 6867
6820 6868 /* save available lun number */
6821 6869 if (!viewEntry->luNbrValid) {
6822 6870 bcopy(ioctlViewEntry.ve_lu_nbr, viewEntry->luNbr,
6823 6871 sizeof (ioctlViewEntry.ve_lu_nbr));
6824 6872 }
6825 6873 if (ioctlRet != 0) {
6826 6874 switch (errno) {
6827 6875 case EBUSY:
6828 6876 ret = STMF_ERROR_BUSY;
6829 6877 break;
6830 6878 case EPERM:
6831 6879 ret = STMF_ERROR_PERM;
6832 6880 break;
6833 6881 case EACCES:
6834 6882 switch (stmfIoctl.stmf_error) {
6835 6883 case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6836 6884 ret = STMF_ERROR_CONFIG_NONE;
6837 6885 break;
6838 6886 default:
6839 6887 ret = STMF_ERROR_PERM;
6840 6888 break;
6841 6889 }
6842 6890 break;
6843 6891 default:
6844 6892 switch (stmfIoctl.stmf_error) {
6845 6893 case STMF_IOCERR_LU_NUMBER_IN_USE:
6846 6894 ret = STMF_ERROR_LUN_IN_USE;
6847 6895 break;
6848 6896 case STMF_IOCERR_VIEW_ENTRY_CONFLICT:
6849 6897 ret = STMF_ERROR_VE_CONFLICT;
6850 6898 break;
6851 6899 case STMF_IOCERR_UPDATE_NEED_CFG_INIT:
6852 6900 ret = STMF_ERROR_CONFIG_NONE;
6853 6901 break;
6854 6902 case STMF_IOCERR_INVALID_HG:
6855 6903 ret = STMF_ERROR_INVALID_HG;
6856 6904 break;
6857 6905 case STMF_IOCERR_INVALID_TG:
6858 6906 ret = STMF_ERROR_INVALID_TG;
6859 6907 break;
6860 6908 default:
6861 6909 syslog(LOG_DEBUG,
6862 6910 "addViewEntryIoctl"
6863 6911 ":error(%d)",
6864 6912 stmfIoctl.stmf_error);
6865 6913 ret = STMF_STATUS_ERROR;
6866 6914 break;
6867 6915 }
6868 6916 break;
6869 6917 }
6870 6918 }
6871 6919 return (ret);
6872 6920 }
6873 6921
6874 6922 /*
6875 6923 * stmfValidateView
6876 6924 *
6877 6925 * Purpose: Validate or get lun # base on TG, HG of view entry
6878 6926 *
6879 6927 * viewEntry - view entry structure to use
6880 6928 */
6881 6929 int
6882 6930 stmfValidateView(stmfViewEntry *viewEntry)
6883 6931 {
6884 6932 int ret;
6885 6933 int fd;
6886 6934 stmfViewEntry iViewEntry;
6887 6935
6888 6936 if (viewEntry == NULL) {
6889 6937 return (STMF_ERROR_INVALID_ARG);
6890 6938 }
6891 6939
6892 6940 /* initialize and set internal view entry */
6893 6941 bzero(&iViewEntry, sizeof (iViewEntry));
6894 6942
6895 6943 if (!viewEntry->allHosts) {
6896 6944 bcopy(viewEntry->hostGroup, iViewEntry.hostGroup,
6897 6945 sizeof (iViewEntry.hostGroup));
6898 6946 } else {
6899 6947 iViewEntry.allHosts = B_TRUE;
6900 6948 }
6901 6949
6902 6950 if (!viewEntry->allTargets) {
6903 6951 bcopy(viewEntry->targetGroup, iViewEntry.targetGroup,
6904 6952 sizeof (iViewEntry.targetGroup));
6905 6953 } else {
6906 6954 iViewEntry.allTargets = B_TRUE;
6907 6955 }
6908 6956
6909 6957 if (viewEntry->luNbrValid) {
6910 6958 iViewEntry.luNbrValid = B_TRUE;
6911 6959 bcopy(viewEntry->luNbr, iViewEntry.luNbr,
6912 6960 sizeof (iViewEntry.luNbr));
6913 6961 }
6914 6962
6915 6963 /*
6916 6964 * set users return view entry index valid flag to false
6917 6965 * in case of failure
6918 6966 */
6919 6967 viewEntry->veIndexValid = B_FALSE;
6920 6968
6921 6969 /* Check to ensure service exists */
6922 6970 if (psCheckService() != STMF_STATUS_SUCCESS) {
6923 6971 return (STMF_ERROR_SERVICE_NOT_FOUND);
6924 6972 }
6925 6973
6926 6974 /* call init */
6927 6975 ret = initializeConfig();
6928 6976 if (ret != STMF_STATUS_SUCCESS) {
6929 6977 return (ret);
6930 6978 }
6931 6979
6932 6980 /*
6933 6981 * Open control node for stmf
6934 6982 */
6935 6983 if ((ret = openStmf(OPEN_STMF, &fd)) != STMF_STATUS_SUCCESS)
6936 6984 return (ret);
6937 6985
6938 6986 /*
6939 6987 * Validate lun# in the view entry from the driver
6940 6988 */
6941 6989 ret = validateLunNumIoctl(fd, &iViewEntry);
6942 6990 (void) close(fd);
6943 6991
6944 6992 /* save available lun number */
6945 6993 if (!viewEntry->luNbrValid) {
6946 6994 bcopy(iViewEntry.luNbr, viewEntry->luNbr,
6947 6995 sizeof (iViewEntry.luNbr));
6948 6996 }
6949 6997
6950 6998 return (ret);
6951 6999 }
|
↓ open down ↓ |
3903 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX