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.
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.
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]
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
31 #include <libdevinfo.h>
36 typedef struct walk_devlink
{
45 get_devlink(di_devlink_t devlink
, void *arg
) {
47 walk_devlink_t
*warg
= (walk_devlink_t
*)arg
;
50 log(LOG_INFO
, "get_devlink()", " - enter");
53 *(warg
->linkpp
) = strdup(di_devlink_path(devlink
));
56 log(LOG_INFO
, "get_devlink()", " - exit");
58 return (DI_WALK_TERMINATE
);
63 *getDeviceFileName(MP_UINT64 objectSequenceNumber
)
65 char *deviceFileName
= NULL
;
67 di_node_t root_node
= DI_NODE_NIL
;
68 di_node_t cur_node
= DI_NODE_NIL
;
74 char *pathName
= NULL
;
75 char *minorName
= "c,raw";
81 di_devlink_handle_t dlHandle
= NULL
;
86 log(LOG_INFO
, "getDeviceFileName()", " - enter");
88 log(LOG_INFO
, "getDeviceFileName()",
89 " - objectSequenceNumber: %llx",
90 objectSequenceNumber
);
92 root_node
= di_init("/", DINFOCACHE
);
93 if (DI_NODE_NIL
== root_node
) {
94 log(LOG_INFO
, "MP_GetMultipathLusPlugin()",
95 " - $ERROR, di_init() failed");
101 cur_node
= di_drv_first_node("scsi_vhci", root_node
);
102 if (DI_NODE_NIL
== cur_node
) {
103 log(LOG_INFO
, "getDeviceFileName()",
104 " - $ERROR, di_drv_first_node() failed");
112 cur_node
= di_child_node(cur_node
);
114 while (DI_NODE_NIL
!= cur_node
) {
116 instNum
= di_instance(cur_node
);
117 majorNum
= di_driver_major(cur_node
);
120 osn
= MP_STORE_INST_TO_ID(instNum
, osn
);
121 osn
= MP_STORE_MAJOR_TO_ID(majorNum
, osn
);
123 if (osn
== objectSequenceNumber
) {
125 log(LOG_INFO
, "getDeviceFileName()",
131 cur_node
= di_sibling_node(cur_node
);
134 if (DI_NODE_NIL
!= cur_node
) {
136 dlHandle
= di_devlink_init(NULL
, 0);
137 if (NULL
== dlHandle
) {
138 log(LOG_INFO
, "getDeviceFileName()",
139 " - $ERROR, di_devlink_init() failed.");
146 pathName
= di_devfs_path(cur_node
);
148 (void) snprintf(fullName
, 511, "%s:%s", pathName
, minorName
);
150 log(LOG_INFO
, "getDeviceFileName()",
151 " - fullName: {%s]", fullName
);
153 (void) memset(&warg
, 0, sizeof (walk_devlink_t
));
156 warg
.linkpp
= &devLink
;
158 diStatus
= di_devlink_walk(dlHandle
,
167 log(LOG_INFO
, "getDeviceFileName()",
168 "diStatus: %d", diStatus
);
174 log(LOG_INFO
, "getDeviceFileName()",
175 "diStatus: %d", diStatus
);
177 log(LOG_INFO
, "getDeviceFileName()",
178 "strerror(diStatus): %s", strerror(diStatus
));
181 if (NULL
!= devLink
) {
184 (char *)calloc(1, strlen(devLink
) + 1);
186 (void) strncpy(deviceFileName
, devLink
,
191 log(LOG_INFO
, "getDeviceFileName()",
192 " - $ERROR, devLink is NULL.");
195 (char *)calloc(1, 256);
197 (void) strncpy(deviceFileName
, pathName
, 255);
200 di_devfs_path_free(pathName
);
202 (void) di_devlink_fini(&dlHandle
);
211 log(LOG_INFO
, "getDeviceFileName()", " - exit");
213 return (deviceFileName
);
219 MP_GetMPLogicalUnitProperties(MP_OID oid
,
220 MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
*pProps
)
222 mp_iocdata_t mp_ioctl
;
223 mp_logical_unit_prop_t luInfo
;
225 MP_OID overridePathOID
;
229 int vendorLength
= 0;
230 int productLength
= 0;
231 int revisionLength
= 0;
233 char *deviceFileName
= NULL
;
236 MP_STATUS mpStatus
= MP_STATUS_SUCCESS
;
239 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()", " - enter");
242 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
243 "oid.objectSequenceNumber = %llx",
244 oid
.objectSequenceNumber
);
246 if (g_scsi_vhci_fd
< 0) {
247 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
248 "invalid driver file handle");
249 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
251 return (MP_STATUS_FAILED
);
254 (void) memset(&mp_ioctl
, 0, sizeof (mp_iocdata_t
));
255 (void) memset(&luInfo
, 0, sizeof (mp_logical_unit_prop_t
));
257 mp_ioctl
.mp_cmd
= MP_GET_LU_PROP
;
258 mp_ioctl
.mp_ibuf
= (caddr_t
)&oid
.objectSequenceNumber
;
259 mp_ioctl
.mp_ilen
= sizeof (oid
.objectSequenceNumber
);
260 mp_ioctl
.mp_obuf
= (caddr_t
)&luInfo
;
261 mp_ioctl
.mp_olen
= sizeof (mp_logical_unit_prop_t
);
262 mp_ioctl
.mp_xfer
= MP_XFER_READ
;
264 ioctlStatus
= ioctl(g_scsi_vhci_fd
, MP_CMD
, &mp_ioctl
);
266 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
267 " IOCTL call returned: %d", ioctlStatus
);
269 if (ioctlStatus
< 0) {
273 if (ioctlStatus
!= 0) {
274 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
275 "IOCTL call failed. IOCTL error is: %d",
277 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
278 "IOCTL call failed. IOCTL error is: %s",
279 strerror(ioctlStatus
));
280 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
281 "IOCTL call failed. mp_ioctl.mp_errno: %x",
284 if (ENOTSUP
== ioctlStatus
) {
285 mpStatus
= MP_STATUS_UNSUPPORTED
;
286 } else if (0 == mp_ioctl
.mp_errno
) {
287 mpStatus
= MP_STATUS_FAILED
;
289 mpStatus
= getStatus4ErrorCode(mp_ioctl
.mp_errno
);
292 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
298 (void) memset(pProps
, 0, sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES
));
300 pProps
->asymmetric
= luInfo
.asymmetric
;
301 pProps
->autoFailbackEnabled
= luInfo
.autoFailbackEnabled
;
302 pProps
->autoProbingEnabled
= luInfo
.autoProbingEnabled
;
303 pProps
->currentFailbackPollingRate
= luInfo
.currentFailBackPollingRate
;
304 pProps
->currentLoadBalanceType
= luInfo
.currentLoadBalanceType
;
305 pProps
->currentProbingPollingRate
= luInfo
.currentProbingPollingRate
;
308 deviceFileName
= getDeviceFileName(oid
.objectSequenceNumber
);
310 if (NULL
!= deviceFileName
) {
312 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()",
313 "deviceFileName: %s",
316 (void) strncpy(pProps
->deviceFileName
,
318 sizeof (pProps
->deviceFileName
) - 1);
320 free(deviceFileName
);
323 pProps
->failbackPollingRateMax
= luInfo
.failbackPollingRateMax
;
324 pProps
->logicalUnitGroupID
= luInfo
.luGroupID
;
326 (void) strncpy(pProps
->name
, luInfo
.name
, sizeof (pProps
->name
) - 1);
328 pProps
->nameType
= luInfo
.nameType
;
330 overridePathOID
.objectSequenceNumber
= luInfo
.overridePathID
;
331 overridePathOID
.objectType
= MP_OBJECT_TYPE_PATH_LU
;
332 overridePathOID
.ownerId
= g_pluginOwnerID
;
333 (void) memcpy(&pProps
->overridePath
, &overridePathOID
, sizeof (MP_OID
));
335 pProps
->probingPollingRateMax
= luInfo
.probingPollingRateMax
;
338 vendorLength
= sizeof (pProps
->vendor
);
339 productLength
= sizeof (pProps
->product
);
340 revisionLength
= sizeof (pProps
->revision
);
342 (void) strncpy(pProps
->vendor
,
343 luInfo
.prodInfo
.vendor
,
346 (void) strncpy(pProps
->product
,
347 luInfo
.prodInfo
.product
,
350 (void) strncpy(pProps
->revision
,
351 luInfo
.prodInfo
.revision
,
354 log(LOG_INFO
, "MP_GetMPLogicalUnitProperties()", " - exit");
356 return (MP_STATUS_SUCCESS
);