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/FCHBA.cc
+++ new/usr/src/lib/sun_fc/common/FCHBA.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 <FCHBA.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/fibre-channel/fcio.h>
42 42 #include <sys/fibre-channel/ulp/fcsm.h>
43 43 #include <FCHBAPort.h>
44 44 #include <HBAList.h>
45 45
46 46 #define EXCPT_RETRY_COUNT 10
47 47
48 48 using namespace std;
49 49 const string FCHBA::FCSM_DRIVER_PATH = "/devices/pseudo/fcsm@0:fcsm";
50 50 const string FCHBA::FCSM_DRIVER_PKG = "SUNWfcsm";
51 51 const int FCHBA::MAX_FCIO_MSG_LEN = 256;
52 52
53 53 FCHBA::FCHBA(string path) : HBA() {
54 54 Trace log("FCHBA::FCHBA");
55 55 log.debug("Constructing new HBA (%s)", path.c_str());
56 56
57 57 // Add first port
58 58 addPort(new FCHBAPort(path));
59 59
60 60 name = "INTERNAL-FAILURE"; // Just in case things go wrong
61 61 try {
62 62 HBA_ADAPTERATTRIBUTES attrs = getHBAAttributes();
63 63 name = attrs.Manufacturer;
64 64 name += "-";
65 65 name += attrs.Model;
66 66
67 67 // Grab any other ports on this adapter
68 68 for (int i = 1; i < attrs.NumberOfPorts; i++) {
69 69 fcio_t fcio;
70 70 int fd;
71 71 char nextPath[MAXPATHLEN];
72 72
73 73 log.debug("Fetching other port %d", i);
74 74
75 75 // construct fcio struct
76 76 memset(&fcio, 0, sizeof (fcio_t));
77 77 memset(nextPath, 0, sizeof (nextPath));
78 78 fcio.fcio_cmd = FCIO_GET_OTHER_ADAPTER_PORTS;
79 79 fcio.fcio_xfer = FCIO_XFER_RW;
80 80
81 81 fcio.fcio_olen = MAXPATHLEN;
82 82 fcio.fcio_obuf = (char *)nextPath;
83 83 fcio.fcio_ilen = sizeof (i);
84 84 fcio.fcio_ibuf = (char *)&i;
85 85
86 86 // open the fcsm node so we can send the ioctl to
87 87 errno = 0;
88 88 HBAPort *port = getPortByIndex(0);
89 89 if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) ==
90 90 -1) {
91 91 log.debug("Unable to open %d opened (%s)", i,
92 92 port->getPath().c_str());
93 93 if (errno == EBUSY) {
94 94 throw BusyException();
95 95 } else if (errno == EAGAIN) {
96 96 throw TryAgainException();
97 97 } else if (errno == ENOTSUP) {
98 98 throw NotSupportedException();
99 99 } else if (errno == ENOENT) {
100 100 throw UnavailableException();
101 101 } else {
102 102 throw IOError("Unable to open FCSM driver");
103 103 }
104 104 }
105 105 log.debug("Other port %d opened", i);
106 106
107 107 errno = 0;
108 108 if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
109 109 // Interpret the fcio error code
110 110 char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
111 111
112 112 log.genericIOError(
113 113 "ADAPTER_LIST failed: "
114 114 "Errno: \"%s\"",
115 115 strerror(errno));
116 116 close(fd);
117 117 if (errno == EBUSY) {
118 118 throw BusyException();
119 119 } else if (errno == EAGAIN) {
120 120 throw TryAgainException();
121 121 } else if (errno == ENOTSUP) {
122 122 throw NotSupportedException();
123 123 } else if (errno == ENOENT) {
124 124 throw UnavailableException();
125 125 } else {
126 126 throw IOError("Unable to build HBA list");
127 127 }
128 128 }
129 129 close(fd);
130 130 log.debug("About to add port %d (%s)", i, nextPath);
131 131 addPort(new FCHBAPort(nextPath));
132 132 }
133 133 } catch (BusyException &e) {
134 134 throw e;
135 135 } catch (TryAgainException &e) {
136 136 throw e;
137 137 } catch (UnavailableException &e) {
138 138 throw e;
139 139 } catch (HBAException &e) {
140 140 log.internalError(
141 141 "Unable to construct HBA.");
142 142 throw e;
143 143 }
144 144 }
145 145
146 146 std::string FCHBA::getName() {
147 147 Trace log("FCHBA::getName");
148 148 return (name);
149 149 }
150 150
151 151 HBA_ADAPTERATTRIBUTES FCHBA::getHBAAttributes() {
152 152 Trace log("FCHBA::getHBAAttributes");
153 153 int fd;
154 154
155 155 errno = 0;
156 156 HBAPort *port = getPortByIndex(0);
157 157 if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
158 158 // Why did we fail?
159 159 if (errno == EBUSY) {
160 160 throw BusyException();
161 161 } else if (errno == EAGAIN) {
162 162 throw TryAgainException();
163 163 } else if (errno == ENOTSUP) {
164 164 throw NotSupportedException();
165 165 } else {
166 166 throw IOError(port);
167 167 }
168 168 }
169 169
170 170 HBA_ADAPTERATTRIBUTES attributes;
171 171 fcio_t fcio;
172 172 fc_hba_adapter_attributes_t attrs;
173 173
174 174 memset(&fcio, 0, sizeof (fcio));
175 175
176 176 fcio.fcio_cmd = FCIO_GET_ADAPTER_ATTRIBUTES;
177 177 fcio.fcio_olen = sizeof (attrs);
178 178 fcio.fcio_xfer = FCIO_XFER_READ;
179 179 fcio.fcio_obuf = (caddr_t)&attrs;
180 180
181 181
182 182 errno = 0;
183 183 if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
184 184 close(fd);
185 185 if (errno == EBUSY) {
186 186 throw BusyException();
187 187 } else if (errno == EAGAIN) {
188 188 throw TryAgainException();
189 189 } else if (errno == ENOTSUP) {
190 190 throw NotSupportedException();
191 191 } else {
192 192 throw IOError("Unable to fetch adapter attributes");
193 193 }
194 194 }
195 195 close(fd);
196 196
197 197 /* Now copy over the payload */
198 198 attributes.NumberOfPorts = attrs.NumberOfPorts;
199 199 attributes.VendorSpecificID = attrs.VendorSpecificID;
200 200 memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
201 201 memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
202 202 memcpy(attributes.Model, attrs.Model, 256);
203 203 memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
204 204 memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
205 205 memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
206 206 memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
207 207 memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
208 208 memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
209 209 memcpy(attributes.DriverName, attrs.DriverName, 256);
210 210 memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
211 211
212 212 return (attributes);
213 213 }
214 214
215 215 int FCHBA::doForceLip() {
216 216 Trace log("FCHBA::doForceLip");
217 217 int fd;
218 218 fcio_t fcio;
219 219 uint64_t wwn = 0;
220 220 HBAPort *port = getPortByIndex(0);
221 221
222 222 errno = 0;
223 223 if ((fd = open(port->getPath().c_str(), O_RDONLY | O_EXCL)) == -1) {
224 224 if (errno == EBUSY) {
225 225 throw BusyException();
226 226 } else if (errno == EAGAIN) {
227 227 throw TryAgainException();
228 228 } else if (errno == ENOTSUP) {
229 229 throw NotSupportedException();
230 230 } else {
231 231 throw IOError(port);
232 232 }
233 233 }
234 234
235 235 memset(&fcio, 0, sizeof (fcio));
236 236 fcio.fcio_cmd = FCIO_RESET_LINK;
237 237 fcio.fcio_xfer = FCIO_XFER_WRITE;
238 238 fcio.fcio_ilen = sizeof (wwn);
239 239 fcio.fcio_ibuf = (caddr_t)&wwn;
240 240
241 241 errno = 0;
242 242 if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
243 243 close(fd);
244 244
245 245 if (errno == EBUSY) {
246 246 throw BusyException();
247 247 } else if (errno == EAGAIN) {
248 248 throw TryAgainException();
249 249 } else if (errno == ENOTSUP) {
250 250 throw NotSupportedException();
251 251 } else {
252 252 throw IOError("Unable to reinitialize the link");
253 253 }
254 254 } else {
255 255 close(fd);
256 256 return (fcio.fcio_errno);
257 257 }
258 258 }
259 259
260 260 HBA_ADAPTERATTRIBUTES FCHBA::npivGetHBAAttributes() {
261 261 Trace log("FCHBA::npivGetHBAAttributes");
262 262 int fd;
263 263
264 264 errno = 0;
265 265 HBAPort *port = getPortByIndex(0);
266 266 if ((fd = open(port->getPath().c_str(), O_NDELAY | O_RDONLY)) == -1) {
267 267 // Why did we fail?
268 268 if (errno == EBUSY) {
269 269 throw BusyException();
270 270 } else if (errno == EAGAIN) {
271 271 throw TryAgainException();
272 272 } else if (errno == ENOTSUP) {
273 273 throw NotSupportedException();
274 274 } else {
275 275 throw IOError(port);
276 276 }
277 277 }
278 278
279 279 HBA_ADAPTERATTRIBUTES attributes;
280 280 fcio_t fcio;
281 281 fc_hba_adapter_attributes_t attrs;
282 282
283 283 memset(&fcio, 0, sizeof (fcio));
284 284 fcio.fcio_cmd = FCIO_NPIV_GET_ADAPTER_ATTRIBUTES;
285 285 fcio.fcio_olen = sizeof (attrs);
286 286 fcio.fcio_xfer = FCIO_XFER_READ;
287 287 fcio.fcio_obuf = (caddr_t)&attrs;
288 288 errno = 0;
289 289
290 290 if (ioctl(fd, FCIO_CMD, &fcio) != 0) {
291 291 close(fd);
292 292 if (errno == EBUSY) {
293 293 throw BusyException();
294 294 } else if (errno == EAGAIN) {
295 295 throw TryAgainException();
296 296 } else if (errno == ENOTSUP) {
297 297 throw NotSupportedException();
298 298 } else {
299 299 throw IOError("Unable to fetch adapter attributes");
300 300 }
301 301 }
302 302 close(fd);
303 303
304 304 /* Now copy over the payload */
305 305 attributes.NumberOfPorts = attrs.NumberOfPorts;
306 306 attributes.VendorSpecificID = attrs.VendorSpecificID;
307 307 memcpy(attributes.Manufacturer, attrs.Manufacturer, 64);
308 308 memcpy(attributes.SerialNumber, attrs.SerialNumber, 64);
309 309 memcpy(attributes.Model, attrs.Model, 256);
310 310 memcpy(attributes.ModelDescription, attrs.ModelDescription, 256);
311 311 memcpy(attributes.NodeSymbolicName, attrs.NodeSymbolicName, 256);
312 312 memcpy(attributes.HardwareVersion, attrs.HardwareVersion, 256);
313 313 memcpy(attributes.DriverVersion, attrs.DriverVersion, 256);
314 314 memcpy(attributes.OptionROMVersion, attrs.OptionROMVersion, 256);
315 315 memcpy(attributes.FirmwareVersion, attrs.FirmwareVersion, 256);
316 316 memcpy(attributes.DriverName, attrs.DriverName, 256);
317 317 memcpy(&attributes.NodeWWN, &attrs.NodeWWN, 8);
318 318
319 319 return (attributes);
320 320 }
321 321
322 322 void FCHBA::loadAdapters(vector<HBA*> &list) {
323 323 Trace log("FCHBA::loadAdapters");
324 324 fcio_t fcio;
325 325 fc_hba_list_t *pathList;
326 326 int fd;
327 327 int size = 64; // default first attempt
328 328 bool retry = false;
329 329 struct stat sb;
330 330 int bufSize;
331 331
332 332 /* Before we do anything, let's see if FCSM is on the system */
333 333 errno = 0;
334 334 if (stat(FCSM_DRIVER_PATH.c_str(), &sb) != 0) {
335 335 if (errno == ENOENT) {
336 336 log.genericIOError(
337 337 "The %s driver is not present. Unable to issue "
338 338 "CT commands. Please install the %s package.",
339 339 FCSM_DRIVER_PATH.c_str(), FCSM_DRIVER_PKG.c_str());
340 340 throw NotSupportedException();
341 341 } else {
342 342 log.genericIOError(
343 343 "Can not stat the %s driver for reason \"%s\" "
344 344 "Unable to issue CT commands.",
345 345 FCSM_DRIVER_PATH.c_str(), strerror(errno));
346 346 throw IOError("Unable to stat FCSM driver");
347 347 }
348 348 }
349 349
350 350
351 351 /* construct fcio struct */
352 352 memset(&fcio, 0, sizeof (fcio_t));
353 353 fcio.fcio_cmd = FCSMIO_ADAPTER_LIST;
354 354 fcio.fcio_xfer = FCIO_XFER_RW;
355 355
356 356
357 357 /* open the fcsm node so we can send the ioctl to */
358 358 errno = 0;
359 359 if ((fd = open(FCSM_DRIVER_PATH.c_str(), O_RDONLY)) < 0) {
360 360 if (errno == EBUSY) {
361 361 throw BusyException();
362 362 } else if (errno == EAGAIN) {
363 363 throw TryAgainException();
364 364 } else if (errno == ENOTSUP) {
365 365 throw NotSupportedException();
366 366 } else if (errno == ENOENT) {
367 367 throw UnavailableException();
368 368 } else {
369 369 throw IOError("Unable to open FCSM driver");
370 370 }
371 371 }
372 372
373 373 do {
374 374 retry = false;
375 375 errno = 0;
376 376 bufSize = MAXPATHLEN * size + (int) sizeof (fc_hba_list_t) - 1;
377 377 pathList = (fc_hba_list_t *)new uchar_t[bufSize];
378 378 pathList->numAdapters = size;
379 379 fcio.fcio_olen = bufSize;
380 380 fcio.fcio_obuf = (char *)pathList;
381 381 if (ioctl(fd, FCSMIO_CMD, &fcio) != 0) {
382 382 /* Interpret the fcio error code */
383 383 char fcioErrorString[MAX_FCIO_MSG_LEN] = "";
384 384
385 385 log.genericIOError(
386 386 "ADAPTER_LIST failed: "
387 387 "Errno: \"%s\"",
388 388 strerror(errno));
389 389 delete (pathList);
390 390 close(fd);
391 391 if (errno == EBUSY) {
392 392 throw BusyException();
393 393 } else if (errno == EAGAIN) {
394 394 throw TryAgainException();
395 395 } else if (errno == ENOTSUP) {
396 396 throw NotSupportedException();
397 397 } else if (errno == ENOENT) {
398 398 throw UnavailableException();
399 399 } else {
400 400 throw IOError("Unable to build HBA list");
401 401 }
402 402 }
403 403 if (pathList->numAdapters > size) {
404 404 log.debug(
405 405 "Buffer too small for number of HBAs. Retrying.");
406 406 size = pathList->numAdapters;
407 407 retry = true;
408 408 delete (pathList);
409 409 }
410 410 } while (retry);
411 411
412 412 close(fd);
413 413 log.debug("Detected %d adapters", pathList->numAdapters);
414 414 for (int i = 0, times =0; i < pathList->numAdapters;) {
415 415 try {
416 416 HBA *hba = new FCHBA(pathList->hbaPaths[i]);
417 417 list.insert(list.begin(), hba);
418 418 i++;
419 419 } catch (BusyException &e) {
420 420 sleep(1);
421 421 if (times++ > EXCPT_RETRY_COUNT) {
422 422 i++;
423 423 times = 0;
424 424 }
425 425 continue;
426 426 } catch (TryAgainException &e) {
427 427 sleep(1);
428 428 if (times++ > EXCPT_RETRY_COUNT) {
429 429 i++;
430 430 times = 0;
431 431 }
432 432 continue;
433 433 } catch (UnavailableException &e) {
434 434 sleep(1);
435 435 if (times++ > EXCPT_RETRY_COUNT) {
436 436 i++;
437 437 times = 0;
438 438 }
439 439 continue;
↓ open down ↓ |
439 lines elided |
↑ open up ↑ |
440 440 } catch (HBAException &e) {
441 441 i++;
442 442 times = 0;
443 443 log.debug(
444 444 "Ignoring partial failure while loading an HBA");
445 445 }
446 446 }
447 447 if (pathList->numAdapters > HBAList::HBA_MAX_PER_LIST) {
448 448 delete(pathList);
449 449 throw InternalError(
450 - "Exceeds max number of adatpers that VSL supports.");
450 + "Exceeds max number of adapters that VSL supports.");
451 451 }
452 452 delete (pathList);
453 453 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX