1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <syslog.h> 27 #include <errno.h> 28 #include <unistd.h> 29 #include <stropts.h> 30 31 #include "mp_utils.h" 32 33 #include <libdevinfo.h> 34 35 static int getOidList(di_node_t root_node, MP_OID_LIST *pOidList) 36 { 37 int numNodes = 0; 38 39 MP_UINT64 instNum = 0; 40 41 di_node_t sv_node = DI_NODE_NIL; 42 di_node_t sv_child_node = DI_NODE_NIL; 43 44 int haveList = (NULL != pOidList); 45 46 47 log(LOG_INFO, "getOidList()", " - enter"); 48 49 50 sv_node = di_drv_first_node("scsi_vhci", root_node); 51 if (DI_NODE_NIL == sv_node) { 52 log(LOG_INFO, "getOidList()", 53 " - di_drv_first_node() failed"); 54 55 return (-1); 56 } 57 58 sv_child_node = di_child_node(sv_node); 59 60 while (DI_NODE_NIL != sv_child_node) { 61 62 if (haveList && (numNodes < pOidList->oidCount)) { 63 64 /* skip the node which is not online */ 65 if (di_state(sv_child_node) != 0) { 66 sv_child_node = di_sibling_node(sv_child_node); 67 continue; 68 } 69 70 instNum = 71 (MP_UINT64)di_instance(sv_child_node); 72 73 log(LOG_INFO, "getOidList()", 74 " - instance number is: %llx", 75 instNum); 76 77 pOidList->oids[numNodes].objectType = 78 MP_OBJECT_TYPE_MULTIPATH_LU; 79 80 pOidList->oids[numNodes].ownerId = 81 g_pluginOwnerID; 82 83 pOidList->oids[numNodes].objectSequenceNumber = 84 instNum; 85 } 86 87 ++numNodes; 88 89 sv_child_node = di_sibling_node(sv_child_node); 90 } 91 92 log(LOG_INFO, 93 "getOidList()", 94 " - numNodes: %d", 95 numNodes); 96 97 98 99 log(LOG_INFO, "getOidList()", " - exit"); 100 101 return (numNodes); 102 } 103 104 105 MP_STATUS 106 MP_GetMultipathLusPlugin(MP_OID_LIST **ppList) 107 { 108 di_node_t root_node = DI_NODE_NIL; 109 MP_OID_LIST *pOidList = NULL; 110 111 int numNodes = 0; 112 int i = 0; 113 114 log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - enter"); 115 116 117 root_node = di_init("/", DINFOCACHE); 118 if (DI_NODE_NIL == root_node) { 119 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 120 " - di_init() failed"); 121 122 return (MP_STATUS_FAILED); 123 } 124 125 numNodes = getOidList(root_node, NULL); 126 127 if (numNodes < 0) { 128 129 log(LOG_INFO, 130 "MP_GetMultipathLusPlugin()", 131 " - unable to get OID list."); 132 133 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 134 " - error exit"); 135 136 di_fini(root_node); 137 138 return (MP_STATUS_FAILED); 139 } 140 141 if (0 == numNodes) { 142 143 pOidList = createOidList(1); 144 if (NULL == pOidList) { 145 146 log(LOG_INFO, 147 "MP_GetMultipathLusPlugin()", 148 " - unable to create OID list."); 149 150 di_fini(root_node); 151 152 return (MP_STATUS_INSUFFICIENT_MEMORY); 153 } 154 155 pOidList->oids[0].objectType = 156 MP_OBJECT_TYPE_MULTIPATH_LU; 157 158 pOidList->oids[0].ownerId = 159 g_pluginOwnerID; 160 161 *ppList = pOidList; 162 163 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 164 " - returning empty list."); 165 166 di_fini(root_node); 167 168 return (MP_STATUS_SUCCESS); 169 } 170 171 *ppList = createOidList(numNodes); 172 if (NULL == *ppList) { 173 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 174 "no memory for *ppList"); 175 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 176 " - error exit"); 177 return (MP_STATUS_INSUFFICIENT_MEMORY); 178 } 179 180 (*ppList)->oidCount = numNodes; 181 182 numNodes = getOidList(root_node, *ppList); 183 184 for (i = 0; i < (*ppList)->oidCount; i++) { 185 186 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 187 "(*ppList)->oids[%d].objectType = %d", 188 i, (*ppList)->oids[i].objectType); 189 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 190 "(*ppList)->oids[%d].ownerId = %d", 191 i, (*ppList)->oids[i].ownerId); 192 log(LOG_INFO, "MP_GetMultipathLusPlugin()", 193 "(*ppList)->oids[%d].objectSequenceNumber = %llx", 194 i, (*ppList)->oids[i].objectSequenceNumber); 195 } 196 197 198 di_fini(root_node); 199 200 log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit"); 201 202 return (MP_STATUS_SUCCESS); 203 204 } 205