1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte * CDDL HEADER START
3fcf3ce44SJohn Forte *
4fcf3ce44SJohn Forte * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte *
8fcf3ce44SJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte * and limitations under the License.
12fcf3ce44SJohn Forte *
13fcf3ce44SJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte *
19fcf3ce44SJohn Forte * CDDL HEADER END
20fcf3ce44SJohn Forte */
21fcf3ce44SJohn Forte /*
22*0c034175SJiri Svoboda * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23fcf3ce44SJohn Forte */
24fcf3ce44SJohn Forte
25fcf3ce44SJohn Forte #include <string.h>
26fcf3ce44SJohn Forte #include <syslog.h>
27fcf3ce44SJohn Forte #include <errno.h>
28fcf3ce44SJohn Forte #include <unistd.h>
29fcf3ce44SJohn Forte #include <stropts.h>
30fcf3ce44SJohn Forte
31fcf3ce44SJohn Forte #include <libdevinfo.h>
32fcf3ce44SJohn Forte
33fcf3ce44SJohn Forte #include "mp_utils.h"
34fcf3ce44SJohn Forte
35fcf3ce44SJohn Forte
36fcf3ce44SJohn Forte typedef struct walk_devlink {
37fcf3ce44SJohn Forte char *path;
38fcf3ce44SJohn Forte size_t len;
39fcf3ce44SJohn Forte char **linkpp;
40fcf3ce44SJohn Forte } walk_devlink_t;
41fcf3ce44SJohn Forte
42fcf3ce44SJohn Forte
43fcf3ce44SJohn Forte
44fcf3ce44SJohn Forte static int
get_devlink(di_devlink_t devlink,void * arg)45fcf3ce44SJohn Forte get_devlink(di_devlink_t devlink, void *arg) {
46fcf3ce44SJohn Forte
47fcf3ce44SJohn Forte walk_devlink_t *warg = (walk_devlink_t *)arg;
48fcf3ce44SJohn Forte
49fcf3ce44SJohn Forte
50fcf3ce44SJohn Forte log(LOG_INFO, "get_devlink()", " - enter");
51fcf3ce44SJohn Forte
52fcf3ce44SJohn Forte
53fcf3ce44SJohn Forte *(warg->linkpp) = strdup(di_devlink_path(devlink));
54fcf3ce44SJohn Forte
55fcf3ce44SJohn Forte
56fcf3ce44SJohn Forte log(LOG_INFO, "get_devlink()", " - exit");
57fcf3ce44SJohn Forte
58fcf3ce44SJohn Forte return (DI_WALK_TERMINATE);
59fcf3ce44SJohn Forte }
60fcf3ce44SJohn Forte
61fcf3ce44SJohn Forte
62fcf3ce44SJohn Forte char
getDeviceFileName(MP_UINT64 objectSequenceNumber)63*0c034175SJiri Svoboda *getDeviceFileName(MP_UINT64 objectSequenceNumber)
64fcf3ce44SJohn Forte {
65fcf3ce44SJohn Forte char *deviceFileName = NULL;
66fcf3ce44SJohn Forte
67fcf3ce44SJohn Forte di_node_t root_node = DI_NODE_NIL;
68fcf3ce44SJohn Forte di_node_t cur_node = DI_NODE_NIL;
69fcf3ce44SJohn Forte
70*0c034175SJiri Svoboda int instNum;
71*0c034175SJiri Svoboda int majorNum;
72*0c034175SJiri Svoboda MP_UINT64 osn;
73fcf3ce44SJohn Forte
74fcf3ce44SJohn Forte char *pathName = NULL;
75fcf3ce44SJohn Forte char *minorName = "c,raw";
76fcf3ce44SJohn Forte char *devLink = NULL;
77fcf3ce44SJohn Forte
78fcf3ce44SJohn Forte char fullName[512];
79fcf3ce44SJohn Forte
80fcf3ce44SJohn Forte walk_devlink_t warg;
81fcf3ce44SJohn Forte di_devlink_handle_t dlHandle = NULL;
82fcf3ce44SJohn Forte
83fcf3ce44SJohn Forte int diStatus = 0;
84fcf3ce44SJohn Forte
85fcf3ce44SJohn Forte
86fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()", " - enter");
87fcf3ce44SJohn Forte
88fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
89*0c034175SJiri Svoboda " - objectSequenceNumber: %llx",
90*0c034175SJiri Svoboda objectSequenceNumber);
91fcf3ce44SJohn Forte
92fcf3ce44SJohn Forte root_node = di_init("/", DINFOCACHE);
93fcf3ce44SJohn Forte if (DI_NODE_NIL == root_node) {
94fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMultipathLusPlugin()",
956162934bSRamesh Chitrothu " - $ERROR, di_init() failed");
96fcf3ce44SJohn Forte
97fcf3ce44SJohn Forte return (NULL);
98fcf3ce44SJohn Forte }
99fcf3ce44SJohn Forte
100fcf3ce44SJohn Forte
101fcf3ce44SJohn Forte cur_node = di_drv_first_node("scsi_vhci", root_node);
102fcf3ce44SJohn Forte if (DI_NODE_NIL == cur_node) {
103fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
1046162934bSRamesh Chitrothu " - $ERROR, di_drv_first_node() failed");
105fcf3ce44SJohn Forte
106fcf3ce44SJohn Forte di_fini(root_node);
107fcf3ce44SJohn Forte
108fcf3ce44SJohn Forte return (NULL);
109fcf3ce44SJohn Forte }
110fcf3ce44SJohn Forte
111fcf3ce44SJohn Forte
112fcf3ce44SJohn Forte cur_node = di_child_node(cur_node);
113fcf3ce44SJohn Forte
114fcf3ce44SJohn Forte while (DI_NODE_NIL != cur_node) {
115fcf3ce44SJohn Forte
116*0c034175SJiri Svoboda instNum = di_instance(cur_node);
117*0c034175SJiri Svoboda majorNum = di_driver_major(cur_node);
118fcf3ce44SJohn Forte
119*0c034175SJiri Svoboda osn = 0;
120*0c034175SJiri Svoboda osn = MP_STORE_INST_TO_ID(instNum, osn);
121*0c034175SJiri Svoboda osn = MP_STORE_MAJOR_TO_ID(majorNum, osn);
122*0c034175SJiri Svoboda
123*0c034175SJiri Svoboda if (osn == objectSequenceNumber) {
124fcf3ce44SJohn Forte
125fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
1266162934bSRamesh Chitrothu " - found node.");
127fcf3ce44SJohn Forte
128fcf3ce44SJohn Forte break;
129fcf3ce44SJohn Forte }
130fcf3ce44SJohn Forte
131fcf3ce44SJohn Forte cur_node = di_sibling_node(cur_node);
132fcf3ce44SJohn Forte }
133fcf3ce44SJohn Forte
134fcf3ce44SJohn Forte if (DI_NODE_NIL != cur_node) {
135fcf3ce44SJohn Forte
136fcf3ce44SJohn Forte dlHandle = di_devlink_init(NULL, 0);
137fcf3ce44SJohn Forte if (NULL == dlHandle) {
1386162934bSRamesh Chitrothu log(LOG_INFO, "getDeviceFileName()",
139fcf3ce44SJohn Forte " - $ERROR, di_devlink_init() failed.");
140fcf3ce44SJohn Forte
1416162934bSRamesh Chitrothu di_fini(root_node);
142fcf3ce44SJohn Forte
1436162934bSRamesh Chitrothu return (NULL);
144fcf3ce44SJohn Forte }
145fcf3ce44SJohn Forte
146fcf3ce44SJohn Forte pathName = di_devfs_path(cur_node);
147fcf3ce44SJohn Forte
148fcf3ce44SJohn Forte (void) snprintf(fullName, 511, "%s:%s", pathName, minorName);
149fcf3ce44SJohn Forte
150fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
1516162934bSRamesh Chitrothu " - fullName: {%s]", fullName);
152fcf3ce44SJohn Forte
153fcf3ce44SJohn Forte (void) memset(&warg, 0, sizeof (walk_devlink_t));
154fcf3ce44SJohn Forte
155fcf3ce44SJohn Forte devLink = NULL;
156fcf3ce44SJohn Forte warg.linkpp = &devLink;
157fcf3ce44SJohn Forte
158fcf3ce44SJohn Forte diStatus = di_devlink_walk(dlHandle,
1596162934bSRamesh Chitrothu NULL,
1606162934bSRamesh Chitrothu fullName,
1616162934bSRamesh Chitrothu DI_PRIMARY_LINK,
1626162934bSRamesh Chitrothu (void *)&warg,
1636162934bSRamesh Chitrothu get_devlink);
164fcf3ce44SJohn Forte
165fcf3ce44SJohn Forte if (diStatus != 0) {
166fcf3ce44SJohn Forte
167fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
168fcf3ce44SJohn Forte "diStatus: %d", diStatus);
169fcf3ce44SJohn Forte
170fcf3ce44SJohn Forte if (diStatus < 0) {
171fcf3ce44SJohn Forte diStatus = errno;
172fcf3ce44SJohn Forte }
173fcf3ce44SJohn Forte
174fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
175fcf3ce44SJohn Forte "diStatus: %d", diStatus);
176fcf3ce44SJohn Forte
177fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
178fcf3ce44SJohn Forte "strerror(diStatus): %s", strerror(diStatus));
179fcf3ce44SJohn Forte }
180fcf3ce44SJohn Forte
181fcf3ce44SJohn Forte if (NULL != devLink) {
182fcf3ce44SJohn Forte
183fcf3ce44SJohn Forte deviceFileName =
1846162934bSRamesh Chitrothu (char *)calloc(1, strlen(devLink) + 1);
185fcf3ce44SJohn Forte
186fcf3ce44SJohn Forte (void) strncpy(deviceFileName, devLink,
187fcf3ce44SJohn Forte strlen(devLink));
188fcf3ce44SJohn Forte
189fcf3ce44SJohn Forte } else {
190fcf3ce44SJohn Forte
191fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()",
1926162934bSRamesh Chitrothu " - $ERROR, devLink is NULL.");
193fcf3ce44SJohn Forte
194fcf3ce44SJohn Forte deviceFileName =
1956162934bSRamesh Chitrothu (char *)calloc(1, 256);
196fcf3ce44SJohn Forte
197fcf3ce44SJohn Forte (void) strncpy(deviceFileName, pathName, 255);
198fcf3ce44SJohn Forte }
199fcf3ce44SJohn Forte
200fcf3ce44SJohn Forte di_devfs_path_free(pathName);
201fcf3ce44SJohn Forte
202fcf3ce44SJohn Forte (void) di_devlink_fini(&dlHandle);
203fcf3ce44SJohn Forte
204fcf3ce44SJohn Forte }
205fcf3ce44SJohn Forte
206fcf3ce44SJohn Forte
207fcf3ce44SJohn Forte di_fini(root_node);
208fcf3ce44SJohn Forte
2096162934bSRamesh Chitrothu free(devLink);
210fcf3ce44SJohn Forte
211fcf3ce44SJohn Forte log(LOG_INFO, "getDeviceFileName()", " - exit");
212fcf3ce44SJohn Forte
213fcf3ce44SJohn Forte return (deviceFileName);
214fcf3ce44SJohn Forte }
215fcf3ce44SJohn Forte
216fcf3ce44SJohn Forte
217fcf3ce44SJohn Forte
218fcf3ce44SJohn Forte MP_STATUS
MP_GetMPLogicalUnitProperties(MP_OID oid,MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES * pProps)219fcf3ce44SJohn Forte MP_GetMPLogicalUnitProperties(MP_OID oid,
220fcf3ce44SJohn Forte MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES *pProps)
221fcf3ce44SJohn Forte {
222fcf3ce44SJohn Forte mp_iocdata_t mp_ioctl;
223fcf3ce44SJohn Forte mp_logical_unit_prop_t luInfo;
224fcf3ce44SJohn Forte
225fcf3ce44SJohn Forte MP_OID overridePathOID;
226fcf3ce44SJohn Forte
227fcf3ce44SJohn Forte int ioctlStatus = 0;
228fcf3ce44SJohn Forte
229fcf3ce44SJohn Forte int vendorLength = 0;
230fcf3ce44SJohn Forte int productLength = 0;
231fcf3ce44SJohn Forte int revisionLength = 0;
232fcf3ce44SJohn Forte
233fcf3ce44SJohn Forte char *deviceFileName = NULL;
234fcf3ce44SJohn Forte
235fcf3ce44SJohn Forte
236fcf3ce44SJohn Forte MP_STATUS mpStatus = MP_STATUS_SUCCESS;
237fcf3ce44SJohn Forte
238fcf3ce44SJohn Forte
239fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", " - enter");
240fcf3ce44SJohn Forte
241fcf3ce44SJohn Forte
242fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2436162934bSRamesh Chitrothu "oid.objectSequenceNumber = %llx",
2446162934bSRamesh Chitrothu oid.objectSequenceNumber);
245fcf3ce44SJohn Forte
246fcf3ce44SJohn Forte if (g_scsi_vhci_fd < 0) {
247fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2486162934bSRamesh Chitrothu "invalid driver file handle");
249fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2506162934bSRamesh Chitrothu " - error exit");
251fcf3ce44SJohn Forte return (MP_STATUS_FAILED);
252fcf3ce44SJohn Forte }
253fcf3ce44SJohn Forte
254fcf3ce44SJohn Forte (void) memset(&mp_ioctl, 0, sizeof (mp_iocdata_t));
255fcf3ce44SJohn Forte (void) memset(&luInfo, 0, sizeof (mp_logical_unit_prop_t));
256fcf3ce44SJohn Forte
257fcf3ce44SJohn Forte mp_ioctl.mp_cmd = MP_GET_LU_PROP;
258fcf3ce44SJohn Forte mp_ioctl.mp_ibuf = (caddr_t)&oid.objectSequenceNumber;
259fcf3ce44SJohn Forte mp_ioctl.mp_ilen = sizeof (oid.objectSequenceNumber);
260fcf3ce44SJohn Forte mp_ioctl.mp_obuf = (caddr_t)&luInfo;
261fcf3ce44SJohn Forte mp_ioctl.mp_olen = sizeof (mp_logical_unit_prop_t);
262fcf3ce44SJohn Forte mp_ioctl.mp_xfer = MP_XFER_READ;
263fcf3ce44SJohn Forte
264fcf3ce44SJohn Forte ioctlStatus = ioctl(g_scsi_vhci_fd, MP_CMD, &mp_ioctl);
265fcf3ce44SJohn Forte
266fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2676162934bSRamesh Chitrothu " IOCTL call returned: %d", ioctlStatus);
268fcf3ce44SJohn Forte
269fcf3ce44SJohn Forte if (ioctlStatus < 0) {
270fcf3ce44SJohn Forte ioctlStatus = errno;
271fcf3ce44SJohn Forte }
272fcf3ce44SJohn Forte
273fcf3ce44SJohn Forte if (ioctlStatus != 0) {
274fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2756162934bSRamesh Chitrothu "IOCTL call failed. IOCTL error is: %d",
2766162934bSRamesh Chitrothu ioctlStatus);
277fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2786162934bSRamesh Chitrothu "IOCTL call failed. IOCTL error is: %s",
2796162934bSRamesh Chitrothu strerror(ioctlStatus));
280fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2816162934bSRamesh Chitrothu "IOCTL call failed. mp_ioctl.mp_errno: %x",
2826162934bSRamesh Chitrothu mp_ioctl.mp_errno);
283fcf3ce44SJohn Forte
284fcf3ce44SJohn Forte if (ENOTSUP == ioctlStatus) {
285fcf3ce44SJohn Forte mpStatus = MP_STATUS_UNSUPPORTED;
286fcf3ce44SJohn Forte } else if (0 == mp_ioctl.mp_errno) {
287fcf3ce44SJohn Forte mpStatus = MP_STATUS_FAILED;
288fcf3ce44SJohn Forte } else {
289fcf3ce44SJohn Forte mpStatus = getStatus4ErrorCode(mp_ioctl.mp_errno);
290fcf3ce44SJohn Forte }
291fcf3ce44SJohn Forte
292fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
2936162934bSRamesh Chitrothu " - error exit");
294fcf3ce44SJohn Forte
295fcf3ce44SJohn Forte return (mpStatus);
296fcf3ce44SJohn Forte }
297fcf3ce44SJohn Forte
298fcf3ce44SJohn Forte (void) memset(pProps, 0, sizeof (MP_MULTIPATH_LOGICAL_UNIT_PROPERTIES));
299fcf3ce44SJohn Forte
300fcf3ce44SJohn Forte pProps->asymmetric = luInfo.asymmetric;
301fcf3ce44SJohn Forte pProps->autoFailbackEnabled = luInfo.autoFailbackEnabled;
302fcf3ce44SJohn Forte pProps->autoProbingEnabled = luInfo.autoProbingEnabled;
303fcf3ce44SJohn Forte pProps->currentFailbackPollingRate = luInfo.currentFailBackPollingRate;
304fcf3ce44SJohn Forte pProps->currentLoadBalanceType = luInfo.currentLoadBalanceType;
305fcf3ce44SJohn Forte pProps->currentProbingPollingRate = luInfo.currentProbingPollingRate;
306fcf3ce44SJohn Forte
307fcf3ce44SJohn Forte
308fcf3ce44SJohn Forte deviceFileName = getDeviceFileName(oid.objectSequenceNumber);
309fcf3ce44SJohn Forte
310fcf3ce44SJohn Forte if (NULL != deviceFileName) {
311fcf3ce44SJohn Forte
312fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()",
3136162934bSRamesh Chitrothu "deviceFileName: %s",
3146162934bSRamesh Chitrothu deviceFileName);
315fcf3ce44SJohn Forte
316fcf3ce44SJohn Forte (void) strncpy(pProps->deviceFileName,
3176162934bSRamesh Chitrothu deviceFileName,
3186162934bSRamesh Chitrothu sizeof (pProps->deviceFileName) - 1);
319fcf3ce44SJohn Forte
320fcf3ce44SJohn Forte free(deviceFileName);
321fcf3ce44SJohn Forte }
322fcf3ce44SJohn Forte
323fcf3ce44SJohn Forte pProps->failbackPollingRateMax = luInfo.failbackPollingRateMax;
324fcf3ce44SJohn Forte pProps->logicalUnitGroupID = luInfo.luGroupID;
325fcf3ce44SJohn Forte
326fcf3ce44SJohn Forte (void) strncpy(pProps->name, luInfo.name, sizeof (pProps->name) - 1);
327fcf3ce44SJohn Forte
328fcf3ce44SJohn Forte pProps->nameType = luInfo.nameType;
329fcf3ce44SJohn Forte
330fcf3ce44SJohn Forte overridePathOID.objectSequenceNumber = luInfo.overridePathID;
331fcf3ce44SJohn Forte overridePathOID.objectType = MP_OBJECT_TYPE_PATH_LU;
332fcf3ce44SJohn Forte overridePathOID.ownerId = g_pluginOwnerID;
333fcf3ce44SJohn Forte (void) memcpy(&pProps->overridePath, &overridePathOID, sizeof (MP_OID));
334fcf3ce44SJohn Forte
335fcf3ce44SJohn Forte pProps->probingPollingRateMax = luInfo.probingPollingRateMax;
336fcf3ce44SJohn Forte
337fcf3ce44SJohn Forte
338fcf3ce44SJohn Forte vendorLength = sizeof (pProps->vendor);
339fcf3ce44SJohn Forte productLength = sizeof (pProps->product);
340fcf3ce44SJohn Forte revisionLength = sizeof (pProps->revision);
341fcf3ce44SJohn Forte
342fcf3ce44SJohn Forte (void) strncpy(pProps->vendor,
3436162934bSRamesh Chitrothu luInfo.prodInfo.vendor,
3446162934bSRamesh Chitrothu vendorLength);
345fcf3ce44SJohn Forte
346fcf3ce44SJohn Forte (void) strncpy(pProps->product,
3476162934bSRamesh Chitrothu luInfo.prodInfo.product,
3486162934bSRamesh Chitrothu productLength);
349fcf3ce44SJohn Forte
350fcf3ce44SJohn Forte (void) strncpy(pProps->revision,
3516162934bSRamesh Chitrothu luInfo.prodInfo.revision,
3526162934bSRamesh Chitrothu revisionLength);
353fcf3ce44SJohn Forte
354fcf3ce44SJohn Forte log(LOG_INFO, "MP_GetMPLogicalUnitProperties()", " - exit");
355fcf3ce44SJohn Forte
356fcf3ce44SJohn Forte return (MP_STATUS_SUCCESS);
357fcf3ce44SJohn Forte }
358