1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte /*
22*0c034175SJiri Svoboda * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23fcf3ce44SJohn Forte */
24fcf3ce44SJohn Forte
25fcf3ce44SJohn Forte #include <syslog.h>
26fcf3ce44SJohn Forte #include <errno.h>
27fcf3ce44SJohn Forte #include <unistd.h>
28fcf3ce44SJohn Forte #include <stropts.h>
29fcf3ce44SJohn Forte
30fcf3ce44SJohn Forte #include "mp_utils.h"
31fcf3ce44SJohn Forte
32fcf3ce44SJohn Forte #include <libdevinfo.h>
33fcf3ce44SJohn Forte
344c06356bSdh /*
354c06356bSdh * Checks whether there is online path or not.
364c06356bSdh * - no path found returns -1.
374c06356bSdh * - online/standby path found returns 1.
384c06356bSdh * - path exists but no online/standby path found returns 0.
394c06356bSdh */
checkAvailablePath(di_node_t node)404c06356bSdh static int checkAvailablePath(di_node_t node)
414c06356bSdh {
424c06356bSdh di_path_t path;
434c06356bSdh di_path_state_t state;
444c06356bSdh
454c06356bSdh if ((path = di_path_client_next_path(node, DI_PATH_NIL))
464c06356bSdh == DI_PATH_NIL) {
474c06356bSdh log(LOG_INFO, "checkAvailalblePath()",
484c06356bSdh " - No path found");
494c06356bSdh return (-1);
504c06356bSdh }
514c06356bSdh
524c06356bSdh do {
534c06356bSdh /* ignore the path that is neither online nor standby. */
544c06356bSdh if (((state = di_path_state(path)) == DI_PATH_STATE_ONLINE) ||
554c06356bSdh (state == DI_PATH_STATE_STANDBY)) {
564c06356bSdh return (1);
574c06356bSdh }
584c06356bSdh } while ((path = di_path_client_next_path(node, path)) != DI_PATH_NIL);
594c06356bSdh
604c06356bSdh /* return 0 for the case that there is no online path to the node. */
614c06356bSdh log(LOG_INFO, "checkAvailalblePath()", " - No online path found");
624c06356bSdh return (0);
634c06356bSdh }
644c06356bSdh
getOidList(di_node_t root_node,MP_OID_LIST * pOidList)65fcf3ce44SJohn Forte static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList)
66fcf3ce44SJohn Forte {
674c06356bSdh int numNodes = 0, state;
68fcf3ce44SJohn Forte
69*0c034175SJiri Svoboda int instNum;
70*0c034175SJiri Svoboda int majorNum;
71*0c034175SJiri Svoboda MP_UINT64 osn;
72fcf3ce44SJohn Forte
73fcf3ce44SJohn Forte di_node_t sv_node = DI_NODE_NIL;
74fcf3ce44SJohn Forte di_node_t sv_child_node = DI_NODE_NIL;
75fcf3ce44SJohn Forte
76fcf3ce44SJohn Forte int haveList = (NULL != pOidList);
77fcf3ce44SJohn Forte
78fcf3ce44SJohn Forte
79fcf3ce44SJohn Forte log(LOG_INFO, "getOidList()", " - enter");
80fcf3ce44SJohn Forte
81fcf3ce44SJohn Forte
82fcf3ce44SJohn Forte sv_node = di_drv_first_node("scsi_vhci", root_node);
83fcf3ce44SJohn Forte if (DI_NODE_NIL == sv_node) {
84fcf3ce44SJohn Forte log(LOG_INFO, "getOidList()",
85fcf3ce44SJohn Forte " - di_drv_first_node() failed");
86fcf3ce44SJohn Forte
87fcf3ce44SJohn Forte return (-1);
88fcf3ce44SJohn Forte }
89fcf3ce44SJohn Forte
90fcf3ce44SJohn Forte sv_child_node = di_child_node(sv_node);
91fcf3ce44SJohn Forte
92fcf3ce44SJohn Forte while (DI_NODE_NIL != sv_child_node) {
93fcf3ce44SJohn Forte
944c06356bSdh /* skip the node which is offline, down or detached. */
954c06356bSdh state = di_state(sv_child_node);
964c06356bSdh if ((state & DI_DEVICE_DOWN) ||
974c06356bSdh (state & DI_DEVICE_OFFLINE)) {
984c06356bSdh sv_child_node = di_sibling_node(sv_child_node);
994c06356bSdh continue;
1004c06356bSdh }
1014c06356bSdh
1024c06356bSdh /*
1034c06356bSdh * skip if the node doesn't have any path avaialble.
1044c06356bSdh * If any path is found from the DINFOCACHE snaphost
1054c06356bSdh * that means the driver keeps track of the path regadless
1064c06356bSdh * of state.
1074c06356bSdh */
1084c06356bSdh if (checkAvailablePath(sv_child_node) == -1) {
109466684c0SJiri Svoboda sv_child_node = di_sibling_node(sv_child_node);
110466684c0SJiri Svoboda continue;
111466684c0SJiri Svoboda }
112fcf3ce44SJohn Forte
113466684c0SJiri Svoboda if (haveList && (numNodes < pOidList->oidCount)) {
114*0c034175SJiri Svoboda instNum = di_instance(sv_child_node);
115*0c034175SJiri Svoboda majorNum = di_driver_major(sv_child_node);
1160c3de118SChris Liu
117fcf3ce44SJohn Forte log(LOG_INFO, "getOidList()",
118*0c034175SJiri Svoboda "instNum = %d", instNum);
119*0c034175SJiri Svoboda log(LOG_INFO, "getOidList()",
120*0c034175SJiri Svoboda "majorNum = %d", majorNum);
121*0c034175SJiri Svoboda
122*0c034175SJiri Svoboda osn = 0;
123*0c034175SJiri Svoboda osn = MP_STORE_INST_TO_ID(instNum, osn);
124*0c034175SJiri Svoboda osn = MP_STORE_MAJOR_TO_ID(majorNum, osn);
125fcf3ce44SJohn Forte
126fcf3ce44SJohn Forte pOidList->oids[numNodes].objectType =
1270c3de118SChris Liu MP_OBJECT_TYPE_MULTIPATH_LU;
128fcf3ce44SJohn Forte
129fcf3ce44SJohn Forte pOidList->oids[numNodes].ownerId =
1300c3de118SChris Liu g_pluginOwnerID;
131fcf3ce44SJohn Forte
132fcf3ce44SJohn Forte pOidList->oids[numNodes].objectSequenceNumber =
133*0c034175SJiri Svoboda osn;
134fcf3ce44SJohn Forte }
135fcf3ce44SJohn Forte
136fcf3ce44SJohn Forte ++numNodes;
137fcf3ce44SJohn Forte
138fcf3ce44SJohn Forte sv_child_node = di_sibling_node(sv_child_node);
139fcf3ce44SJohn Forte }
140fcf3ce44SJohn Forte
141fcf3ce44SJohn Forte log(LOG_INFO,
142fcf3ce44SJohn Forte "getOidList()",
143fcf3ce44SJohn Forte " - numNodes: %d",
144fcf3ce44SJohn Forte numNodes);
145fcf3ce44SJohn Forte
146fcf3ce44SJohn Forte
147fcf3ce44SJohn Forte
148fcf3ce44SJohn Forte log(LOG_INFO, "getOidList()", " - exit");
149fcf3ce44SJohn Forte
150fcf3ce44SJohn Forte return (numNodes);
151fcf3ce44SJohn Forte }
152fcf3ce44SJohn Forte
153fcf3ce44SJohn Forte
154fcf3ce44SJohn Forte MP_STATUS
MP_GetMultipathLusPlugin(MP_OID_LIST ** ppList)155fcf3ce44SJohn Forte MP_GetMultipathLusPlugin(MP_OID_LIST **ppList)
156fcf3ce44SJohn Forte {
157fcf3ce44SJohn Forte di_node_t root_node = DI_NODE_NIL;
158fcf3ce44SJohn Forte MP_OID_LIST *pOidList = NULL;
159fcf3ce44SJohn Forte
160fcf3ce44SJohn Forte int numNodes = 0;
161fcf3ce44SJohn Forte int i = 0;
162fcf3ce44SJohn Forte
163fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - enter");
164fcf3ce44SJohn Forte
165fcf3ce44SJohn Forte
166fcf3ce44SJohn Forte root_node = di_init("/", DINFOCACHE);
167fcf3ce44SJohn Forte if (DI_NODE_NIL == root_node) {
168fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
169fcf3ce44SJohn Forte " - di_init() failed");
170fcf3ce44SJohn Forte
171fcf3ce44SJohn Forte return (MP_STATUS_FAILED);
172fcf3ce44SJohn Forte }
173fcf3ce44SJohn Forte
174fcf3ce44SJohn Forte numNodes = getOidList(root_node, NULL);
175fcf3ce44SJohn Forte
176fcf3ce44SJohn Forte if (numNodes < 0) {
177fcf3ce44SJohn Forte
178fcf3ce44SJohn Forte log(LOG_INFO,
179fcf3ce44SJohn Forte "MP_GetMultipathLusPlugin()",
180fcf3ce44SJohn Forte " - unable to get OID list.");
181fcf3ce44SJohn Forte
182fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
183fcf3ce44SJohn Forte " - error exit");
184fcf3ce44SJohn Forte
185fcf3ce44SJohn Forte di_fini(root_node);
186fcf3ce44SJohn Forte
187fcf3ce44SJohn Forte return (MP_STATUS_FAILED);
188fcf3ce44SJohn Forte }
189fcf3ce44SJohn Forte
190fcf3ce44SJohn Forte if (0 == numNodes) {
191fcf3ce44SJohn Forte
192fcf3ce44SJohn Forte pOidList = createOidList(1);
193fcf3ce44SJohn Forte if (NULL == pOidList) {
194fcf3ce44SJohn Forte
195fcf3ce44SJohn Forte log(LOG_INFO,
196fcf3ce44SJohn Forte "MP_GetMultipathLusPlugin()",
197fcf3ce44SJohn Forte " - unable to create OID list.");
198fcf3ce44SJohn Forte
199fcf3ce44SJohn Forte di_fini(root_node);
200fcf3ce44SJohn Forte
201fcf3ce44SJohn Forte return (MP_STATUS_INSUFFICIENT_MEMORY);
202fcf3ce44SJohn Forte }
203fcf3ce44SJohn Forte
204fcf3ce44SJohn Forte pOidList->oids[0].objectType =
2050c3de118SChris Liu MP_OBJECT_TYPE_MULTIPATH_LU;
206fcf3ce44SJohn Forte
207fcf3ce44SJohn Forte pOidList->oids[0].ownerId =
2080c3de118SChris Liu g_pluginOwnerID;
209fcf3ce44SJohn Forte
210fcf3ce44SJohn Forte *ppList = pOidList;
211fcf3ce44SJohn Forte
212fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
213fcf3ce44SJohn Forte " - returning empty list.");
214fcf3ce44SJohn Forte
215fcf3ce44SJohn Forte di_fini(root_node);
216fcf3ce44SJohn Forte
217fcf3ce44SJohn Forte return (MP_STATUS_SUCCESS);
218fcf3ce44SJohn Forte }
219fcf3ce44SJohn Forte
220fcf3ce44SJohn Forte *ppList = createOidList(numNodes);
221fcf3ce44SJohn Forte if (NULL == *ppList) {
222fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
223fcf3ce44SJohn Forte "no memory for *ppList");
224fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
225fcf3ce44SJohn Forte " - error exit");
226fcf3ce44SJohn Forte return (MP_STATUS_INSUFFICIENT_MEMORY);
227fcf3ce44SJohn Forte }
228fcf3ce44SJohn Forte
229fcf3ce44SJohn Forte (*ppList)->oidCount = numNodes;
230fcf3ce44SJohn Forte
231fcf3ce44SJohn Forte numNodes = getOidList(root_node, *ppList);
232fcf3ce44SJohn Forte
233fcf3ce44SJohn Forte for (i = 0; i < (*ppList)->oidCount; i++) {
234fcf3ce44SJohn Forte
235fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
236fcf3ce44SJohn Forte "(*ppList)->oids[%d].objectType = %d",
237fcf3ce44SJohn Forte i, (*ppList)->oids[i].objectType);
238fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
239fcf3ce44SJohn Forte "(*ppList)->oids[%d].ownerId = %d",
240fcf3ce44SJohn Forte i, (*ppList)->oids[i].ownerId);
241fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
242fcf3ce44SJohn Forte "(*ppList)->oids[%d].objectSequenceNumber = %llx",
243fcf3ce44SJohn Forte i, (*ppList)->oids[i].objectSequenceNumber);
244fcf3ce44SJohn Forte }
245fcf3ce44SJohn Forte
246fcf3ce44SJohn Forte
247fcf3ce44SJohn Forte di_fini(root_node);
248fcf3ce44SJohn Forte
249fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit");
250fcf3ce44SJohn Forte
251fcf3ce44SJohn Forte return (MP_STATUS_SUCCESS);
252fcf3ce44SJohn Forte
253fcf3ce44SJohn Forte }
254