Print this page
3217 cfgadm should spell "adaptors" correctly
Reviewed by: Alexander Eremin <alexander.r.eremin@gmail.com>
Reviewed by: David Hoeppner <0xffea@gmail.com>
Reviewed by: Gary Mills <gary_mills@fastmail.fm>
Reviewed by: Eric Schrock <Eric.Schrock@delphix.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/sun_fc/common/TgtFCHBA.cc
+++ new/usr/src/lib/sun_fc/common/TgtFCHBA.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 #include <unistd.h>
28 28
29 29 #include <TgtFCHBA.h>
30 30 #include <Exceptions.h>
31 31 #include <Trace.h>
32 32 #include <iostream>
33 33 #include <iomanip>
34 34 #include <cerrno>
35 35 #include <cstring>
36 36 #include <sys/types.h>
37 37 #include <sys/stat.h>
38 38 #include <fcntl.h>
39 39 #include <unistd.h>
40 40 #include <stropts.h>
41 41 #include <sys/fctio.h>
42 42 #include <sys/fibre-channel/impl/fc_error.h>
43 43 #include <TgtFCHBAPort.h>
44 44 #include <HBAList.h>
45 45 #include <sun_fc.h>
46 46 #include <cstdlib>
47 47
48 48 using namespace std;
49 49 const string TgtFCHBA::FCT_DRIVER_PATH = "/devices/pseudo/fct@0:admin";
50 50 const string TgtFCHBA::FCT_ADAPTER_NAME_PREFIX = "/devices/pseudo/fct@0";
51 51 const string TgtFCHBA::FCT_DRIVER_PKG = "SUNWfct";
52 52 const int TgtFCHBA::MAX_FCTIO_MSG_LEN = 256;
53 53
54 54 TgtFCHBA::TgtFCHBA(string path) : HBA()
55 55 {
56 56 Trace log("TgtFCHBA::TgtFCHBA");
57 57 log.debug("Constructing new Target mode HBA (%s)", path.c_str());
58 58
59 59 // Add a target FCHBA port. With fct driver architecuture, all target mode
60 60 // FCHBA will have a single port regardless of the multiport support on
61 61 // FCA layer.
62 62 addPort(new TgtFCHBAPort(path));
63 63 name = "INTERNAL-FAILURE"; // Just in case things go wrong
64 64 try {
65 65 HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
66 66 name = attrs.Manufacturer;
67 67 name += "-";
68 68 name += attrs.Model;
69 69 name += "-Tgt";
70 70
71 71 } catch (HBAException &e) {
72 72 log.debug(
73 73 "Failed to get HBA attribute for %s", path.c_str());
74 74 throw e;
75 75 }
76 76 }
77 77
78 78 std::string TgtFCHBA::getName()
79 79 {
80 80 Trace log("TgtFCHBA::getName");
81 81 return (name);
82 82 }
83 83
84 84 HBA_ADAPTERATTRIBUTES TgtFCHBA::getHBAAttributes()
85 85 {
86 86 Trace log("TgtFCHBA::getHBAAttributes");
87 87 int fd;
88 88
89 89 errno = 0;
90 90 HBAPort *port = getPortByIndex(0);
91 91
92 92 HBA_ADAPTERATTRIBUTES attributes;
93 93 fctio_t fctio;
94 94 fc_tgt_hba_adapter_attributes_t attrs;
95 95 uint64_t portwwn;
96 96
97 97 if ((fd = open(FCT_DRIVER_PATH.c_str(), O_NDELAY | O_RDONLY)) == -1) {
98 98 // Why did we fail?
99 99 if (errno == EBUSY) {
100 100 throw BusyException();
101 101 } else if (errno == EAGAIN) {
102 102 throw TryAgainException();
103 103 } else if (errno == ENOTSUP) {
104 104 throw NotSupportedException();
105 105 } else {
106 106 throw IOError(port);
107 107 }
108 108 }
109 109
110 110 try {
111 111 std::string path = port->getPath();
112 112 string::size_type offset = path.find_last_of(".");
113 113 if (offset >= 0) {
114 114 string portwwnString = path.substr(offset+1);
115 115 portwwn = strtoull(portwwnString.c_str(), NULL, 16);
116 116 }
117 117 } catch (...) {
118 118 throw BadArgumentException();
119 119 }
120 120
121 121 uint64_t en_wwn = htonll(portwwn);
122 122
123 123 memset(&fctio, 0, sizeof (fctio));
124 124 fctio.fctio_cmd = FCTIO_GET_ADAPTER_ATTRIBUTES;
125 125 fctio.fctio_olen = (uint32_t)(sizeof (attrs));
126 126 fctio.fctio_xfer = FCTIO_XFER_READ;
127 127 fctio.fctio_obuf = (uint64_t)(uintptr_t)&attrs;
128 128 fctio.fctio_ilen = 8;
129 129 fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
130 130
131 131 errno = 0;
132 132 if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
133 133 close(fd);
134 134 if (errno == EBUSY) {
135 135 throw BusyException();
136 136 } else if (errno == EAGAIN) {
137 137 throw TryAgainException();
138 138 } else if (errno == ENOTSUP) {
139 139 throw NotSupportedException();
140 140 } else {
141 141 throw IOError("Unable to fetch adapter attributes");
142 142 }
143 143 }
144 144 close(fd);
145 145
146 146 /* Now copy over the payload */
147 147 attributes.NumberOfPorts = attrs.NumberOfPorts;
148 148 attributes.VendorSpecificID = attrs.VendorSpecificID;
149 149 memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
150 150 memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
151 151 memcpy(attributes.Model, attrs.Model, 256);
152 152 memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
153 153 memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
154 154 memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
155 155 memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
156 156 memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
157 157 memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
158 158 memcpy(attributes.DriverName, attrs.DriverName, 256);
159 159 memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
160 160
161 161 return (attributes);
162 162 }
163 163
164 164 int TgtFCHBA::doForceLip()
165 165 {
166 166 Trace log("TgtFCHBA::doForceLip");
167 167 int fd;
168 168 HBAPort *port = getPortByIndex(0);
169 169 fctio_t fctio;
170 170 uint64_t portwwn;
171 171
172 172 errno = 0;
173 173 if ((fd = open(FCT_DRIVER_PATH.c_str(), O_NDELAY | O_RDONLY)) == -1) {
174 174 if (errno == EBUSY) {
175 175 throw BusyException();
176 176 } else if (errno == EAGAIN) {
177 177 throw TryAgainException();
178 178 } else if (errno == ENOTSUP) {
179 179 throw NotSupportedException();
180 180 } else {
181 181 throw IOError(port);
182 182 }
183 183 }
184 184
185 185 try {
186 186 std::string path = port->getPath();
187 187 string::size_type offset = path.find_last_of(".");
188 188 if (offset >= 0) {
189 189 string portwwnString = path.substr(offset+1);
190 190 portwwn = strtoull(portwwnString.c_str(), NULL, 16);
191 191 }
192 192 } catch (...) {
193 193 throw BadArgumentException();
194 194 }
195 195
196 196 uint64_t en_wwn = htonll(portwwn);
197 197 memset(&fctio, 0, sizeof (fctio));
198 198 fctio.fctio_cmd = FCTIO_FORCE_LIP;
199 199 fctio.fctio_xfer = FCTIO_XFER_READ;
200 200 fctio.fctio_ilen = 8;
201 201 fctio.fctio_ibuf = (uint64_t)(uintptr_t)&en_wwn;
202 202
203 203 errno = 0;
204 204 if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
205 205 close(fd);
206 206 if (errno == EBUSY) {
207 207 throw BusyException();
208 208 } else if (errno == EAGAIN) {
209 209 throw TryAgainException();
210 210 } else if (errno == ENOTSUP) {
211 211 throw NotSupportedException();
212 212 } else {
213 213 throw IOError("Unable to reinitialize the link");
214 214 }
215 215 } else {
216 216 close(fd);
217 217 return ((int)fctio.fctio_errno);
218 218 }
219 219 }
220 220
221 221 void TgtFCHBA::loadAdapters(vector<HBA*> &list)
222 222 {
223 223 Trace log("TgtFCHBA::loadAdapters");
224 224 fctio_t fctio;
225 225 fc_tgt_hba_list_t *tgthbaList;
226 226 int fd;
227 227 int size = 64; // default first attempt
228 228 bool retry = false;
229 229 struct stat sb;
230 230 int bufSize;
231 231 char wwnStr[17];
232 232
233 233 /* Before we do anything, let's see if FCT is on the system */
234 234 errno = 0;
235 235 if (stat(FCT_DRIVER_PATH.c_str(), &sb) != 0) {
236 236 if (errno == ENOENT) {
237 237 log.genericIOError(
238 238 "The %s driver is not present."
239 239 " Please install the %s package.",
240 240 FCT_DRIVER_PATH.c_str(), FCT_DRIVER_PKG.c_str());
241 241 throw NotSupportedException();
242 242 } else {
243 243 log.genericIOError(
244 244 "Can not stat the %s driver for reason \"%s\" "
245 245 "Unable to get target mode FC adapters.",
246 246 FCT_DRIVER_PATH.c_str(), strerror(errno));
247 247 throw IOError("Unable to stat FCSM driver");
248 248 }
249 249 }
250 250
251 251
252 252 /* construct fcio struct */
253 253 memset(&fctio, 0, sizeof (fctio_t));
254 254 fctio.fctio_cmd = FCTIO_ADAPTER_LIST;
255 255 fctio.fctio_xfer = FCTIO_XFER_RW;
256 256
257 257 /* open the fcsm node so we can send the ioctl to */
258 258 errno = 0;
259 259 if ((fd = open(FCT_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
260 260 if (errno == EBUSY) {
261 261 throw BusyException();
262 262 } else if (errno == EAGAIN) {
263 263 throw TryAgainException();
264 264 } else if (errno == ENOTSUP) {
265 265 throw NotSupportedException();
266 266 } else if (errno == ENOENT) {
267 267 throw UnavailableException();
268 268 } else {
269 269 throw IOError("Unable to open FCT driver");
270 270 }
271 271 }
272 272
273 273 do {
274 274 retry = false;
275 275 errno = 0;
276 276 bufSize = 8 * (size - 1) + (int) sizeof (fc_tgt_hba_list_t);
277 277 tgthbaList = (fc_tgt_hba_list_t *)new uchar_t[bufSize];
278 278 tgthbaList->numPorts = size;
279 279 fctio.fctio_olen = bufSize;
280 280 fctio.fctio_obuf = (uint64_t)(uintptr_t)tgthbaList;
281 281 if (ioctl(fd, FCTIO_CMD, &fctio) != 0) {
282 282 /* Interpret the fcio error code */
283 283 char fcioErrorString[MAX_FCTIO_MSG_LEN] = "";
284 284
285 285 log.genericIOError(
286 286 "TGT_ADAPTER_LIST failed: "
287 287 "Errno: \"%s\"",
288 288 strerror(errno));
289 289 delete (tgthbaList);
290 290 close(fd);
291 291 if (errno == EBUSY) {
292 292 throw BusyException();
293 293 } else if (errno == EAGAIN) {
294 294 throw TryAgainException();
295 295 } else if (errno == ENOTSUP) {
296 296 throw NotSupportedException();
297 297 } else if (errno == ENOENT) {
298 298 throw UnavailableException();
299 299 } else {
300 300 throw IOError("Unable to build HBA list");
301 301 }
302 302 }
303 303 if (tgthbaList->numPorts > size) {
304 304 log.debug(
305 305 "Buffer too small for number of target mode HBAs. Retrying.");
306 306 size = tgthbaList->numPorts;
307 307 retry = true;
308 308 delete (tgthbaList);
309 309 }
310 310 } while (retry);
311 311
312 312 close(fd);
313 313 log.debug("Detected %d target mode adapters", tgthbaList->numPorts);
314 314 for (int i = 0; i < tgthbaList->numPorts; i++) {
315 315 try {
316 316 std::string hbapath = FCT_ADAPTER_NAME_PREFIX.c_str();
317 317 hbapath += ".";
318 318 // move the row with two dimentional uint8 array for WWN
319 319 uint64_t tmp = ntohll(*((uint64_t *)&tgthbaList->port_wwn[i][0]));
320 320 sprintf(wwnStr, "%llx", tmp);
321 321 hbapath += wwnStr;
322 322
↓ open down ↓ |
322 lines elided |
↑ open up ↑ |
323 323 HBA *hba = new TgtFCHBA(hbapath);
324 324 list.insert(list.begin(), hba);
325 325 } catch (...) {
326 326 log.debug(
327 327 "Ignoring partial failure while loading an HBA");
328 328 }
329 329 }
330 330 if (tgthbaList->numPorts > HBAList::HBA_MAX_PER_LIST) {
331 331 delete(tgthbaList);
332 332 throw InternalError(
333 - "Exceeds max number of adatpers that VSL supports.");
333 + "Exceeds max number of adapters that VSL supports.");
334 334 }
335 335 delete (tgthbaList);
336 336 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX