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 2008 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 			instNum =
65 			(MP_UINT64)di_instance(sv_child_node);
66 
67 			log(LOG_INFO, "getOidList()",
68 			    " - instance number is: %llx",
69 			    instNum);
70 
71 			pOidList->oids[numNodes].objectType =
72 			MP_OBJECT_TYPE_MULTIPATH_LU;
73 
74 			pOidList->oids[numNodes].ownerId =
75 			g_pluginOwnerID;
76 
77 			pOidList->oids[numNodes].objectSequenceNumber =
78 			instNum;
79 		}
80 
81 		++numNodes;
82 
83 		sv_child_node = di_sibling_node(sv_child_node);
84 	}
85 
86 	log(LOG_INFO,
87 	    "getOidList()",
88 	    " - numNodes: %d",
89 	    numNodes);
90 
91 
92 
93 	log(LOG_INFO, "getOidList()", " - exit");
94 
95 	return (numNodes);
96 }
97 
98 
99 MP_STATUS
100 MP_GetMultipathLusPlugin(MP_OID_LIST **ppList)
101 {
102 	di_node_t root_node	= DI_NODE_NIL;
103 	MP_OID_LIST *pOidList   = NULL;
104 
105 	int numNodes = 0;
106 	int i = 0;
107 
108 	log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - enter");
109 
110 
111 	root_node = di_init("/", DINFOCACHE);
112 	if (DI_NODE_NIL == root_node) {
113 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
114 		    " - di_init() failed");
115 
116 		return (MP_STATUS_FAILED);
117 	}
118 
119 	numNodes = getOidList(root_node, NULL);
120 
121 	if (numNodes < 0) {
122 
123 		log(LOG_INFO,
124 		    "MP_GetMultipathLusPlugin()",
125 		    " - unable to get OID list.");
126 
127 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
128 		    " - error exit");
129 
130 		di_fini(root_node);
131 
132 		return (MP_STATUS_FAILED);
133 	}
134 
135 	if (0 == numNodes) {
136 
137 		pOidList = createOidList(1);
138 		if (NULL == pOidList) {
139 
140 			log(LOG_INFO,
141 			    "MP_GetMultipathLusPlugin()",
142 			    " - unable to create OID list.");
143 
144 			di_fini(root_node);
145 
146 			return (MP_STATUS_INSUFFICIENT_MEMORY);
147 		}
148 
149 		pOidList->oids[0].objectType =
150 		MP_OBJECT_TYPE_MULTIPATH_LU;
151 
152 		pOidList->oids[0].ownerId =
153 		g_pluginOwnerID;
154 
155 		*ppList = pOidList;
156 
157 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
158 		    " - returning empty list.");
159 
160 		di_fini(root_node);
161 
162 		return (MP_STATUS_SUCCESS);
163 	}
164 
165 	*ppList = createOidList(numNodes);
166 	if (NULL == *ppList) {
167 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
168 		    "no memory for *ppList");
169 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
170 		    " - error exit");
171 		return (MP_STATUS_INSUFFICIENT_MEMORY);
172 	}
173 
174 	(*ppList)->oidCount = numNodes;
175 
176 	numNodes = getOidList(root_node, *ppList);
177 
178 	for (i = 0; i < (*ppList)->oidCount; i++) {
179 
180 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
181 		    "(*ppList)->oids[%d].objectType           = %d",
182 		    i, (*ppList)->oids[i].objectType);
183 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
184 		    "(*ppList)->oids[%d].ownerId              = %d",
185 		    i, (*ppList)->oids[i].ownerId);
186 		log(LOG_INFO, "MP_GetMultipathLusPlugin()",
187 		    "(*ppList)->oids[%d].objectSequenceNumber = %llx",
188 		    i, (*ppList)->oids[i].objectSequenceNumber);
189 	}
190 
191 
192 	di_fini(root_node);
193 
194 	log(LOG_INFO, "MP_GetMultipathLusPlugin()", " - exit");
195 
196 	return (MP_STATUS_SUCCESS);
197 
198 }
199