17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*12334SJiri.Svoboda@Sun.COM * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
237836SJohn.Forte@Sun.COM */
247836SJohn.Forte@Sun.COM
257836SJohn.Forte@Sun.COM #include <syslog.h>
267836SJohn.Forte@Sun.COM #include <errno.h>
277836SJohn.Forte@Sun.COM #include <unistd.h>
287836SJohn.Forte@Sun.COM #include <stropts.h>
297836SJohn.Forte@Sun.COM
307836SJohn.Forte@Sun.COM #include "mp_utils.h"
317836SJohn.Forte@Sun.COM
327836SJohn.Forte@Sun.COM #include <libdevinfo.h>
337836SJohn.Forte@Sun.COM
3410696SDavid.Hollister@Sun.COM /*
3510696SDavid.Hollister@Sun.COM * Checks whether there is online path or not.
3610696SDavid.Hollister@Sun.COM * - no path found returns -1.
3710696SDavid.Hollister@Sun.COM * - online/standby path found returns 1.
3810696SDavid.Hollister@Sun.COM * - path exists but no online/standby path found returns 0.
3910696SDavid.Hollister@Sun.COM */
checkAvailablePath(di_node_t node)4010696SDavid.Hollister@Sun.COM static int checkAvailablePath(di_node_t node)
4110696SDavid.Hollister@Sun.COM {
4210696SDavid.Hollister@Sun.COM di_path_t path;
4310696SDavid.Hollister@Sun.COM di_path_state_t state;
4410696SDavid.Hollister@Sun.COM
4510696SDavid.Hollister@Sun.COM if ((path = di_path_client_next_path(node, DI_PATH_NIL))
4610696SDavid.Hollister@Sun.COM == DI_PATH_NIL) {
4710696SDavid.Hollister@Sun.COM log(LOG_INFO, "checkAvailalblePath()",
4810696SDavid.Hollister@Sun.COM " - No path found");
4910696SDavid.Hollister@Sun.COM return (-1);
5010696SDavid.Hollister@Sun.COM }
5110696SDavid.Hollister@Sun.COM
5210696SDavid.Hollister@Sun.COM do {
5310696SDavid.Hollister@Sun.COM /* ignore the path that is neither online nor standby. */
5410696SDavid.Hollister@Sun.COM if (((state = di_path_state(path)) == DI_PATH_STATE_ONLINE) ||
5510696SDavid.Hollister@Sun.COM (state == DI_PATH_STATE_STANDBY)) {
5610696SDavid.Hollister@Sun.COM return (1);
5710696SDavid.Hollister@Sun.COM }
5810696SDavid.Hollister@Sun.COM } while ((path = di_path_client_next_path(node, path)) != DI_PATH_NIL);
5910696SDavid.Hollister@Sun.COM
6010696SDavid.Hollister@Sun.COM /* return 0 for the case that there is no online path to the node. */
6110696SDavid.Hollister@Sun.COM log(LOG_INFO, "checkAvailalblePath()", " - No online path found");
6210696SDavid.Hollister@Sun.COM return (0);
6310696SDavid.Hollister@Sun.COM }
6410696SDavid.Hollister@Sun.COM
getOidList(di_node_t root_node,MP_OID_LIST * pOidList)657836SJohn.Forte@Sun.COM static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList)
667836SJohn.Forte@Sun.COM {
6710696SDavid.Hollister@Sun.COM int numNodes = 0, state;
687836SJohn.Forte@Sun.COM
69*12334SJiri.Svoboda@Sun.COM int instNum;
70*12334SJiri.Svoboda@Sun.COM int majorNum;
71*12334SJiri.Svoboda@Sun.COM MP_UINT64 osn;
727836SJohn.Forte@Sun.COM
737836SJohn.Forte@Sun.COM di_node_t sv_node = DI_NODE_NIL;
747836SJohn.Forte@Sun.COM di_node_t sv_child_node = DI_NODE_NIL;
757836SJohn.Forte@Sun.COM
767836SJohn.Forte@Sun.COM int haveList = (NULL != pOidList);
777836SJohn.Forte@Sun.COM
787836SJohn.Forte@Sun.COM
797836SJohn.Forte@Sun.COM log(LOG_INFO, "getOidList()", " - enter");
807836SJohn.Forte@Sun.COM
817836SJohn.Forte@Sun.COM
827836SJohn.Forte@Sun.COM sv_node = di_drv_first_node("scsi_vhci", root_node);
837836SJohn.Forte@Sun.COM if (DI_NODE_NIL == sv_node) {
847836SJohn.Forte@Sun.COM log(LOG_INFO, "getOidList()",
857836SJohn.Forte@Sun.COM " - di_drv_first_node() failed");
867836SJohn.Forte@Sun.COM
877836SJohn.Forte@Sun.COM return (-1);
887836SJohn.Forte@Sun.COM }
897836SJohn.Forte@Sun.COM
907836SJohn.Forte@Sun.COM sv_child_node = di_child_node(sv_node);
917836SJohn.Forte@Sun.COM
927836SJohn.Forte@Sun.COM while (DI_NODE_NIL != sv_child_node) {
937836SJohn.Forte@Sun.COM
9410696SDavid.Hollister@Sun.COM /* skip the node which is offline, down or detached. */
9510696SDavid.Hollister@Sun.COM state = di_state(sv_child_node);
9610696SDavid.Hollister@Sun.COM if ((state & DI_DEVICE_DOWN) ||
9710696SDavid.Hollister@Sun.COM (state & DI_DEVICE_OFFLINE)) {
9810696SDavid.Hollister@Sun.COM sv_child_node = di_sibling_node(sv_child_node);
9910696SDavid.Hollister@Sun.COM continue;
10010696SDavid.Hollister@Sun.COM }
10110696SDavid.Hollister@Sun.COM
10210696SDavid.Hollister@Sun.COM /*
10310696SDavid.Hollister@Sun.COM * skip if the node doesn't have any path avaialble.
10410696SDavid.Hollister@Sun.COM * If any path is found from the DINFOCACHE snaphost
10510696SDavid.Hollister@Sun.COM * that means the driver keeps track of the path regadless
10610696SDavid.Hollister@Sun.COM * of state.
10710696SDavid.Hollister@Sun.COM */
10810696SDavid.Hollister@Sun.COM if (checkAvailablePath(sv_child_node) == -1) {
10910486SJiri.Svoboda@Sun.COM sv_child_node = di_sibling_node(sv_child_node);
11010486SJiri.Svoboda@Sun.COM continue;
11110486SJiri.Svoboda@Sun.COM }
1127836SJohn.Forte@Sun.COM
11310486SJiri.Svoboda@Sun.COM if (haveList && (numNodes < pOidList->oidCount)) {
114*12334SJiri.Svoboda@Sun.COM instNum = di_instance(sv_child_node);
115*12334SJiri.Svoboda@Sun.COM majorNum = di_driver_major(sv_child_node);
1167836SJohn.Forte@Sun.COM
1177836SJohn.Forte@Sun.COM log(LOG_INFO, "getOidList()",
118*12334SJiri.Svoboda@Sun.COM "instNum = %d", instNum);
119*12334SJiri.Svoboda@Sun.COM log(LOG_INFO, "getOidList()",
120*12334SJiri.Svoboda@Sun.COM "majorNum = %d", majorNum);
121*12334SJiri.Svoboda@Sun.COM
122*12334SJiri.Svoboda@Sun.COM osn = 0;
123*12334SJiri.Svoboda@Sun.COM osn = MP_STORE_INST_TO_ID(instNum, osn);
124*12334SJiri.Svoboda@Sun.COM osn = MP_STORE_MAJOR_TO_ID(majorNum, osn);
1257836SJohn.Forte@Sun.COM
1267836SJohn.Forte@Sun.COM pOidList->oids[numNodes].objectType =
1279782SChris.Liu@Sun.COM MP_OBJECT_TYPE_MULTIPATH_LU;
1287836SJohn.Forte@Sun.COM
1297836SJohn.Forte@Sun.COM pOidList->oids[numNodes].ownerId =
1309782SChris.Liu@Sun.COM g_pluginOwnerID;
1317836SJohn.Forte@Sun.COM
1327836SJohn.Forte@Sun.COM pOidList->oids[numNodes].objectSequenceNumber =
133*12334SJiri.Svoboda@Sun.COM osn;
1347836SJohn.Forte@Sun.COM }
1357836SJohn.Forte@Sun.COM
1367836SJohn.Forte@Sun.COM ++numNodes;
1377836SJohn.Forte@Sun.COM
1387836SJohn.Forte@Sun.COM sv_child_node = di_sibling_node(sv_child_node);
1397836SJohn.Forte@Sun.COM }
1407836SJohn.Forte@Sun.COM
1417836SJohn.Forte@Sun.COM log(LOG_INFO,
1427836SJohn.Forte@Sun.COM "getOidList()",
1437836SJohn.Forte@Sun.COM " - numNodes: %d",
1447836SJohn.Forte@Sun.COM numNodes);
1457836SJohn.Forte@Sun.COM
1467836SJohn.Forte@Sun.COM
1477836SJohn.Forte@Sun.COM
1487836SJohn.Forte@Sun.COM log(LOG_INFO, "getOidList()", " - exit");
1497836SJohn.Forte@Sun.COM
1507836SJohn.Forte@Sun.COM return (numNodes);
1517836SJohn.Forte@Sun.COM }
1527836SJohn.Forte@Sun.COM
1537836SJohn.Forte@Sun.COM
1547836SJohn.Forte@Sun.COM MP_STATUS
MP_GetMultipathLusPlugin(MP_OID_LIST ** ppList)1557836SJohn.Forte@Sun.COM MP_GetMultipathLusPlugin(MP_OID_LIST **ppList)
1567836SJohn.Forte@Sun.COM {
1577836SJohn.Forte@Sun.COM di_node_t root_node = DI_NODE_NIL;
1587836SJohn.Forte@Sun.COM MP_OID_LIST *pOidList = NULL;
1597836SJohn.Forte@Sun.COM
1607836SJohn.Forte@Sun.COM int numNodes = 0;
1617836SJohn.Forte@Sun.COM int i = 0;
1627836SJohn.Forte@Sun.COM
1637836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - enter");
1647836SJohn.Forte@Sun.COM
1657836SJohn.Forte@Sun.COM
1667836SJohn.Forte@Sun.COM root_node = di_init("/", DINFOCACHE);
1677836SJohn.Forte@Sun.COM if (DI_NODE_NIL == root_node) {
1687836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
1697836SJohn.Forte@Sun.COM " - di_init() failed");
1707836SJohn.Forte@Sun.COM
1717836SJohn.Forte@Sun.COM return (MP_STATUS_FAILED);
1727836SJohn.Forte@Sun.COM }
1737836SJohn.Forte@Sun.COM
1747836SJohn.Forte@Sun.COM numNodes = getOidList(root_node, NULL);
1757836SJohn.Forte@Sun.COM
1767836SJohn.Forte@Sun.COM if (numNodes < 0) {
1777836SJohn.Forte@Sun.COM
1787836SJohn.Forte@Sun.COM log(LOG_INFO,
1797836SJohn.Forte@Sun.COM "MP_GetMultipathLusPlugin()",
1807836SJohn.Forte@Sun.COM " - unable to get OID list.");
1817836SJohn.Forte@Sun.COM
1827836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
1837836SJohn.Forte@Sun.COM " - error exit");
1847836SJohn.Forte@Sun.COM
1857836SJohn.Forte@Sun.COM di_fini(root_node);
1867836SJohn.Forte@Sun.COM
1877836SJohn.Forte@Sun.COM return (MP_STATUS_FAILED);
1887836SJohn.Forte@Sun.COM }
1897836SJohn.Forte@Sun.COM
1907836SJohn.Forte@Sun.COM if (0 == numNodes) {
1917836SJohn.Forte@Sun.COM
1927836SJohn.Forte@Sun.COM pOidList = createOidList(1);
1937836SJohn.Forte@Sun.COM if (NULL == pOidList) {
1947836SJohn.Forte@Sun.COM
1957836SJohn.Forte@Sun.COM log(LOG_INFO,
1967836SJohn.Forte@Sun.COM "MP_GetMultipathLusPlugin()",
1977836SJohn.Forte@Sun.COM " - unable to create OID list.");
1987836SJohn.Forte@Sun.COM
1997836SJohn.Forte@Sun.COM di_fini(root_node);
2007836SJohn.Forte@Sun.COM
2017836SJohn.Forte@Sun.COM return (MP_STATUS_INSUFFICIENT_MEMORY);
2027836SJohn.Forte@Sun.COM }
2037836SJohn.Forte@Sun.COM
2047836SJohn.Forte@Sun.COM pOidList->oids[0].objectType =
2059782SChris.Liu@Sun.COM MP_OBJECT_TYPE_MULTIPATH_LU;
2067836SJohn.Forte@Sun.COM
2077836SJohn.Forte@Sun.COM pOidList->oids[0].ownerId =
2089782SChris.Liu@Sun.COM g_pluginOwnerID;
2097836SJohn.Forte@Sun.COM
2107836SJohn.Forte@Sun.COM *ppList = pOidList;
2117836SJohn.Forte@Sun.COM
2127836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2137836SJohn.Forte@Sun.COM " - returning empty list.");
2147836SJohn.Forte@Sun.COM
2157836SJohn.Forte@Sun.COM di_fini(root_node);
2167836SJohn.Forte@Sun.COM
2177836SJohn.Forte@Sun.COM return (MP_STATUS_SUCCESS);
2187836SJohn.Forte@Sun.COM }
2197836SJohn.Forte@Sun.COM
2207836SJohn.Forte@Sun.COM *ppList = createOidList(numNodes);
2217836SJohn.Forte@Sun.COM if (NULL == *ppList) {
2227836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2237836SJohn.Forte@Sun.COM "no memory for *ppList");
2247836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2257836SJohn.Forte@Sun.COM " - error exit");
2267836SJohn.Forte@Sun.COM return (MP_STATUS_INSUFFICIENT_MEMORY);
2277836SJohn.Forte@Sun.COM }
2287836SJohn.Forte@Sun.COM
2297836SJohn.Forte@Sun.COM (*ppList)->oidCount = numNodes;
2307836SJohn.Forte@Sun.COM
2317836SJohn.Forte@Sun.COM numNodes = getOidList(root_node, *ppList);
2327836SJohn.Forte@Sun.COM
2337836SJohn.Forte@Sun.COM for (i = 0; i < (*ppList)->oidCount; i++) {
2347836SJohn.Forte@Sun.COM
2357836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2367836SJohn.Forte@Sun.COM "(*ppList)->oids[%d].objectType = %d",
2377836SJohn.Forte@Sun.COM i, (*ppList)->oids[i].objectType);
2387836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2397836SJohn.Forte@Sun.COM "(*ppList)->oids[%d].ownerId = %d",
2407836SJohn.Forte@Sun.COM i, (*ppList)->oids[i].ownerId);
2417836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()",
2427836SJohn.Forte@Sun.COM "(*ppList)->oids[%d].objectSequenceNumber = %llx",
2437836SJohn.Forte@Sun.COM i, (*ppList)->oids[i].objectSequenceNumber);
2447836SJohn.Forte@Sun.COM }
2457836SJohn.Forte@Sun.COM
2467836SJohn.Forte@Sun.COM
2477836SJohn.Forte@Sun.COM di_fini(root_node);
2487836SJohn.Forte@Sun.COM
2497836SJohn.Forte@Sun.COM log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit");
2507836SJohn.Forte@Sun.COM
2517836SJohn.Forte@Sun.COM return (MP_STATUS_SUCCESS);
2527836SJohn.Forte@Sun.COM
2537836SJohn.Forte@Sun.COM }
254