xref: /illumos-gate/usr/src/lib/mpapi/libmpscsi_vhci/common/MP_GetMultipathLusPlugin.c (revision e44e85a7f9935f0428e188393e3da61b17e83884)
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