dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / mpapi / libmpscsi_vhci / common / MP_GetMPLogicalUnitProperties.c
blob5075f377ddf67980879e664be0464e7f0cb5b0fc
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <string.h>
26 #include <syslog.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <stropts.h>
31 #include <libdevinfo.h>
33 #include "mp_utils.h"
36 typedef struct walk_devlink {
37 char *path;
38 size_t len;
39 char **linkpp;
40 } walk_devlink_t;
44 static int
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);
62 char
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;
70 int instNum;
71 int majorNum;
72 MP_UINT64 osn;
74 char *pathName = NULL;
75 char *minorName = "c,raw";
76 char *devLink = NULL;
78 char fullName[512];
80 walk_devlink_t warg;
81 di_devlink_handle_t dlHandle = NULL;
83 int diStatus = 0;
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");
97 return (NULL);
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");
106 di_fini(root_node);
108 return (NULL);
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);
119 osn = 0;
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()",
126 " - found node.");
128 break;
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.");
141 di_fini(root_node);
143 return (NULL);
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));
155 devLink = NULL;
156 warg.linkpp = &devLink;
158 diStatus = di_devlink_walk(dlHandle,
159 NULL,
160 fullName,
161 DI_PRIMARY_LINK,
162 (void *)&warg,
163 get_devlink);
165 if (diStatus != 0) {
167 log(LOG_INFO, "getDeviceFileName()",
168 "diStatus: %d", diStatus);
170 if (diStatus < 0) {
171 diStatus = errno;
174 log(LOG_INFO, "getDeviceFileName()",
175 "diStatus: %d", diStatus);
177 log(LOG_INFO, "getDeviceFileName()",
178 "strerror(diStatus): %s", strerror(diStatus));
181 if (NULL != devLink) {
183 deviceFileName =
184 (char *)calloc(1, strlen(devLink) + 1);
186 (void) strncpy(deviceFileName, devLink,
187 strlen(devLink));
189 } else {
191 log(LOG_INFO, "getDeviceFileName()",
192 " - $ERROR, devLink is NULL.");
194 deviceFileName =
195 (char *)calloc(1, 256);
197 (void) strncpy(deviceFileName, pathName, 255);
200 di_devfs_path_free(pathName);
202 (void) di_devlink_fini(&dlHandle);
207 di_fini(root_node);
209 free(devLink);
211 log(LOG_INFO, "getDeviceFileName()", " - exit");
213 return (deviceFileName);
218 MP_STATUS
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;
227 int ioctlStatus = 0;
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()",
250 " - error exit");
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) {
270 ioctlStatus = errno;
273 if (ioctlStatus != 0) {
274 log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
275 "IOCTL call failed. IOCTL error is: %d",
276 ioctlStatus);
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",
282 mp_ioctl.mp_errno);
284 if (ENOTSUP == ioctlStatus) {
285 mpStatus = MP_STATUS_UNSUPPORTED;
286 } else if (0 == mp_ioctl.mp_errno) {
287 mpStatus = MP_STATUS_FAILED;
288 } else {
289 mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno);
292 log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
293 " - error exit");
295 return (mpStatus);
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",
314 deviceFileName);
316 (void) strncpy(pProps->deviceFileName,
317 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,
344 vendorLength);
346 (void) strncpy(pProps->product,
347 luInfo.prodInfo.product,
348 productLength);
350 (void) strncpy(pProps->revision,
351 luInfo.prodInfo.revision,
352 revisionLength);
354 log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", " - exit");
356 return (MP_STATUS_SUCCESS);