4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
32 #include <libdevinfo.h>
35 * Checks whether there is online path or not.
36 * - no path found returns -1.
37 * - online/standby path found returns 1.
38 * - path exists but no online/standby path found returns 0.
40 static int checkAvailablePath(di_node_t node
)
43 di_path_state_t state
;
45 if ((path
= di_path_client_next_path(node
, DI_PATH_NIL
))
47 log(LOG_INFO
, "checkAvailalblePath()",
53 /* ignore the path that is neither online nor standby. */
54 if (((state
= di_path_state(path
)) == DI_PATH_STATE_ONLINE
) ||
55 (state
== DI_PATH_STATE_STANDBY
)) {
58 } while ((path
= di_path_client_next_path(node
, path
)) != DI_PATH_NIL
);
60 /* return 0 for the case that there is no online path to the node. */
61 log(LOG_INFO
, "checkAvailalblePath()", " - No online path found");
65 static int getOidList(di_node_t root_node
, MP_OID_LIST
*pOidList
)
67 int numNodes
= 0, state
;
73 di_node_t sv_node
= DI_NODE_NIL
;
74 di_node_t sv_child_node
= DI_NODE_NIL
;
76 int haveList
= (NULL
!= pOidList
);
79 log(LOG_INFO
, "getOidList()", " - enter");
82 sv_node
= di_drv_first_node("scsi_vhci", root_node
);
83 if (DI_NODE_NIL
== sv_node
) {
84 log(LOG_INFO
, "getOidList()",
85 " - di_drv_first_node() failed");
90 sv_child_node
= di_child_node(sv_node
);
92 while (DI_NODE_NIL
!= sv_child_node
) {
94 /* skip the node which is offline, down or detached. */
95 state
= di_state(sv_child_node
);
96 if ((state
& DI_DEVICE_DOWN
) ||
97 (state
& DI_DEVICE_OFFLINE
)) {
98 sv_child_node
= di_sibling_node(sv_child_node
);
103 * skip if the node doesn't have any path avaialble.
104 * If any path is found from the DINFOCACHE snaphost
105 * that means the driver keeps track of the path regadless
108 if (checkAvailablePath(sv_child_node
) == -1) {
109 sv_child_node
= di_sibling_node(sv_child_node
);
113 if (haveList
&& (numNodes
< pOidList
->oidCount
)) {
114 instNum
= di_instance(sv_child_node
);
115 majorNum
= di_driver_major(sv_child_node
);
117 log(LOG_INFO
, "getOidList()",
118 "instNum = %d", instNum
);
119 log(LOG_INFO
, "getOidList()",
120 "majorNum = %d", majorNum
);
123 osn
= MP_STORE_INST_TO_ID(instNum
, osn
);
124 osn
= MP_STORE_MAJOR_TO_ID(majorNum
, osn
);
126 pOidList
->oids
[numNodes
].objectType
=
127 MP_OBJECT_TYPE_MULTIPATH_LU
;
129 pOidList
->oids
[numNodes
].ownerId
=
132 pOidList
->oids
[numNodes
].objectSequenceNumber
=
138 sv_child_node
= di_sibling_node(sv_child_node
);
148 log(LOG_INFO
, "getOidList()", " - exit");
155 MP_GetMultipathLusPlugin(MP_OID_LIST
**ppList
)
157 di_node_t root_node
= DI_NODE_NIL
;
158 MP_OID_LIST
*pOidList
= NULL
;
163 log(LOG_INFO
, "MP_GetMultipathLusPlugin()", " - enter");
166 root_node
= di_init("/", DINFOCACHE
);
167 if (DI_NODE_NIL
== root_node
) {
168 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
169 " - di_init() failed");
171 return (MP_STATUS_FAILED
);
174 numNodes
= getOidList(root_node
, NULL
);
179 "MP_GetMultipathLusPlugin()",
180 " - unable to get OID list.");
182 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
187 return (MP_STATUS_FAILED
);
192 pOidList
= createOidList(1);
193 if (NULL
== pOidList
) {
196 "MP_GetMultipathLusPlugin()",
197 " - unable to create OID list.");
201 return (MP_STATUS_INSUFFICIENT_MEMORY
);
204 pOidList
->oids
[0].objectType
=
205 MP_OBJECT_TYPE_MULTIPATH_LU
;
207 pOidList
->oids
[0].ownerId
=
212 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
213 " - returning empty list.");
217 return (MP_STATUS_SUCCESS
);
220 *ppList
= createOidList(numNodes
);
221 if (NULL
== *ppList
) {
222 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
223 "no memory for *ppList");
224 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
226 return (MP_STATUS_INSUFFICIENT_MEMORY
);
229 (*ppList
)->oidCount
= numNodes
;
231 numNodes
= getOidList(root_node
, *ppList
);
233 for (i
= 0; i
< (*ppList
)->oidCount
; i
++) {
235 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
236 "(*ppList)->oids[%d].objectType = %d",
237 i
, (*ppList
)->oids
[i
].objectType
);
238 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
239 "(*ppList)->oids[%d].ownerId = %d",
240 i
, (*ppList
)->oids
[i
].ownerId
);
241 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
242 "(*ppList)->oids[%d].objectSequenceNumber = %llx",
243 i
, (*ppList
)->oids
[i
].objectSequenceNumber
);
249 log(LOG_INFO
, "MP_GetMultipathLusPlugin()", " - exit");
251 return (MP_STATUS_SUCCESS
);