dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / mpapi / libmpscsi_vhci / common / MP_GetMultipathLusPlugin.c
blob7f3fcf7ceac33051835448405697b9e87496c88e
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <syslog.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <stropts.h>
30 #include "mp_utils.h"
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)
42 di_path_t path;
43 di_path_state_t state;
45 if ((path = di_path_client_next_path(node, DI_PATH_NIL))
46 == DI_PATH_NIL) {
47 log(LOG_INFO, "checkAvailalblePath()",
48 " - No path found");
49 return (-1);
52 do {
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)) {
56 return (1);
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");
62 return (0);
65 static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList)
67 int numNodes = 0, state;
69 int instNum;
70 int majorNum;
71 MP_UINT64 osn;
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");
87 return (-1);
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);
99 continue;
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
106 * of state.
108 if (checkAvailablePath(sv_child_node) == -1) {
109 sv_child_node = di_sibling_node(sv_child_node);
110 continue;
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);
122 osn = 0;
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 =
130 g_pluginOwnerID;
132 pOidList->oids[numNodes].objectSequenceNumber =
133 osn;
136 ++numNodes;
138 sv_child_node = di_sibling_node(sv_child_node);
141 log(LOG_INFO,
142 "getOidList()",
143 " - numNodes: %d",
144 numNodes);
148 log(LOG_INFO, "getOidList()", " - exit");
150 return (numNodes);
154 MP_STATUS
155 MP_GetMultipathLusPlugin(MP_OID_LIST **ppList)
157 di_node_t root_node = DI_NODE_NIL;
158 MP_OID_LIST *pOidList = NULL;
160 int numNodes = 0;
161 int i = 0;
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);
176 if (numNodes < 0) {
178 log(LOG_INFO,
179 "MP_GetMultipathLusPlugin()",
180 " - unable to get OID list.");
182 log(LOG_INFO, "MP_GetMultipathLusPlugin()",
183 " - error exit");
185 di_fini(root_node);
187 return (MP_STATUS_FAILED);
190 if (0 == numNodes) {
192 pOidList = createOidList(1);
193 if (NULL == pOidList) {
195 log(LOG_INFO,
196 "MP_GetMultipathLusPlugin()",
197 " - unable to create OID list.");
199 di_fini(root_node);
201 return (MP_STATUS_INSUFFICIENT_MEMORY);
204 pOidList->oids[0].objectType =
205 MP_OBJECT_TYPE_MULTIPATH_LU;
207 pOidList->oids[0].ownerId =
208 g_pluginOwnerID;
210 *ppList = pOidList;
212 log(LOG_INFO, "MP_GetMultipathLusPlugin()",
213 " - returning empty list.");
215 di_fini(root_node);
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()",
225 " - error exit");
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);
247 di_fini(root_node);
249 log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit");
251 return (MP_STATUS_SUCCESS);