Print this page
NEX-5723 libses fails to enumerate HP D2600 SAS AJ940A
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Jeffry Molanus <jeffry.molanus@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-3705 Need to update libses with LID/USN code from sesctld
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/scsi/libses/common/ses_plugin.c
+++ new/usr/src/lib/scsi/libses/common/ses_plugin.c
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
|
↓ open down ↓ |
15 lines elided |
↑ open up ↑ |
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 /*
23 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25 /*
26 - * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
26 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
27 27 */
28 28
29 29 #include <scsi/libses.h>
30 30 #include "ses_impl.h"
31 31
32 32 static boolean_t ses_plugin_dlclose;
33 33
34 34 /*ARGSUSED*/
35 35 void *
36 36 ses_plugin_ctlpage_lookup(ses_plugin_t *sp, ses_snap_t *snap, int pagenum,
37 37 size_t len, ses_node_t *np, boolean_t unique)
38 38 {
39 39 ses_target_t *tp = snap->ss_target;
40 40 ses_snap_page_t *pp;
41 41 ses_pagedesc_t *dp;
42 42
43 43 if ((pp = ses_snap_ctl_page(snap, pagenum, len, unique)) == NULL)
44 44 return (NULL);
45 45
46 46 if ((dp = ses_get_pagedesc(tp, pagenum, SES_PAGE_CTL)) == NULL)
47 47 return (NULL);
48 48
49 49 if (np != NULL && dp->spd_ctl_fill != NULL) {
50 50 return (dp->spd_ctl_fill(sp, pp->ssp_page,
51 51 pp->ssp_len, np));
52 52 } else {
53 53 return (pp->ssp_page);
54 54 }
55 55 }
56 56
57 57 int
58 58 ses_fill_node(ses_node_t *np)
59 59 {
60 60 ses_target_t *tp = np->sn_snapshot->ss_target;
61 61 ses_plugin_t *sp;
62 62
63 63 for (sp = tp->st_plugin_first; sp != NULL; sp = sp->sp_next) {
64 64 if (sp->sp_node_parse == NULL)
65 65 continue;
66 66
67 67 if (sp->sp_node_parse(sp, np) != 0)
68 68 return (-1);
69 69 }
70 70
71 71 return (0);
72 72 }
73 73
74 74 int
75 75 ses_node_ctl(ses_node_t *np, const char *op, nvlist_t *arg)
76 76 {
77 77 ses_target_t *tp = np->sn_snapshot->ss_target;
78 78 ses_plugin_t *sp;
79 79 nvlist_t *nvl;
80 80 nvpair_t *nvp;
81 81 int ret;
82 82
83 83 if (nvlist_dup(arg, &nvl, 0) != 0)
84 84 return (ses_set_errno(ESES_NOMEM));
85 85
86 86 /*
87 87 * Technically we could get away with a per-snapshot lock while we fill
88 88 * the control page contents, but this doesn't take much time and we
89 89 * want actual control operations to be protected per-target, so we just
90 90 * take the target lock.
91 91 */
92 92 (void) pthread_mutex_lock(&tp->st_lock);
93 93
94 94 /*
95 95 * We walk the list of plugins backwards, so that a product-specific
96 96 * plugin can rewrite the nvlist to control operations in terms of the
97 97 * standard mechanisms, if desired.
98 98 */
99 99 for (sp = tp->st_plugin_first; sp != NULL; sp = sp->sp_next) {
100 100 if (sp->sp_node_ctl == NULL)
101 101 continue;
102 102
103 103 if (sp->sp_node_ctl(sp, np, op, nvl) != 0) {
104 104 nvlist_free(nvl);
105 105 (void) pthread_mutex_unlock(&tp->st_lock);
106 106 return (-1);
107 107 }
108 108 }
109 109
110 110 if ((nvp = nvlist_next_nvpair(nvl, NULL)) != NULL) {
111 111 (void) ses_error(ESES_NOTSUP, "property '%s' invalid for "
112 112 "this node", nvpair_name(nvp));
113 113 nvlist_free(nvl);
114 114 (void) pthread_mutex_unlock(&tp->st_lock);
115 115 return (-1);
116 116 }
117 117
118 118 nvlist_free(nvl);
119 119
120 120 ret = ses_snap_do_ctl(np->sn_snapshot);
121 121 (void) pthread_mutex_unlock(&tp->st_lock);
122 122
123 123 return (ret);
124 124 }
125 125
126 126 /*ARGSUSED*/
127 127 void *
128 128 ses_plugin_page_lookup(ses_plugin_t *sp, ses_snap_t *snap, int pagenum,
129 129 ses_node_t *np, size_t *lenp)
130 130 {
131 131 ses_snap_page_t *pp;
132 132 ses_target_t *tp = sp->sp_target;
133 133 ses_pagedesc_t *dp;
134 134
135 135 if ((dp = ses_get_pagedesc(tp, pagenum, SES_PAGE_DIAG)) == NULL)
136 136 return (NULL);
137 137
138 138 if ((pp = ses_snap_find_page(snap, pagenum, B_FALSE)) == NULL)
139 139 return (NULL);
140 140
141 141 if (np != NULL && dp->spd_index != NULL) {
142 142 return (dp->spd_index(sp, np, pp->ssp_page, pp->ssp_len,
143 143 lenp));
144 144 } else {
145 145 *lenp = pp->ssp_len;
146 146 return (pp->ssp_page);
147 147 }
148 148 }
149 149
150 150 ses_pagedesc_t *
151 151 ses_get_pagedesc(ses_target_t *tp, int pagenum, ses_pagetype_t type)
152 152 {
153 153 ses_plugin_t *sp;
154 154 ses_pagedesc_t *dp;
155 155
156 156 for (sp = tp->st_plugin_first; sp != NULL; sp = sp->sp_next) {
157 157 if (sp->sp_pages == NULL)
158 158 continue;
159 159
160 160 for (dp = &sp->sp_pages[0]; dp->spd_pagenum != -1;
161 161 dp++) {
162 162 if ((type == SES_PAGE_CTL && dp->spd_ctl_len == NULL) ||
163 163 (type == SES_PAGE_DIAG && dp->spd_ctl_len != NULL))
164 164 continue;
165 165
166 166 if (dp->spd_pagenum == pagenum)
167 167 return (dp);
168 168 }
169 169 }
170 170
171 171 (void) ses_error(ESES_BAD_PAGE, "failed to find page 0x%x", pagenum);
172 172 return (NULL);
173 173 }
174 174
175 175 int
176 176 ses_plugin_register(ses_plugin_t *sp, int version, ses_plugin_config_t *scp)
177 177 {
178 178 if (version != LIBSES_PLUGIN_VERSION)
179 179 return (ses_set_errno(ESES_VERSION));
180 180
181 181 sp->sp_pages = scp->spc_pages;
182 182 sp->sp_node_parse = scp->spc_node_parse;
183 183 sp->sp_node_ctl = scp->spc_node_ctl;
184 184
185 185 return (0);
186 186 }
187 187
188 188 void
189 189 ses_plugin_setspecific(ses_plugin_t *sp, void *data)
190 190 {
191 191 sp->sp_data = data;
192 192 }
193 193
194 194 void *
195 195 ses_plugin_getspecific(ses_plugin_t *sp)
196 196 {
197 197 return (sp->sp_data);
198 198 }
199 199
200 200 static void
201 201 ses_plugin_cleanstr(char *s)
202 202 {
203 203 while (*s != '\0') {
204 204 if (*s == ' ' || *s == '/')
205 205 *s = '-';
206 206 s++;
207 207 }
208 208 }
209 209
210 210 static void
211 211 ses_plugin_destroy(ses_plugin_t *sp)
212 212 {
213 213 if (sp->sp_initialized && sp->sp_fini != NULL)
214 214 sp->sp_fini(sp);
215 215
216 216 if (ses_plugin_dlclose)
217 217 (void) dlclose(sp->sp_object);
218 218
219 219 ses_free(sp);
220 220 }
221 221
222 222 static int
223 223 ses_plugin_loadone(ses_target_t *tp, const char *path, uint32_t pass)
224 224 {
225 225 ses_plugin_t *sp, **loc;
226 226 void *obj;
227 227 int (*ses_priority)(void);
228 228
229 229 if ((obj = dlopen(path, RTLD_PARENT | RTLD_LOCAL | RTLD_LAZY)) == NULL)
230 230 return (0);
231 231
232 232 if ((sp = ses_zalloc(sizeof (ses_plugin_t))) == NULL) {
233 233 (void) dlclose(obj);
234 234 return (-1);
235 235 }
236 236
237 237 sp->sp_object = obj;
238 238 sp->sp_init = (int (*)())dlsym(obj, "_ses_init");
239 239 sp->sp_fini = (void (*)())dlsym(obj, "_ses_fini");
240 240 sp->sp_target = tp;
241 241
242 242 if (sp->sp_init == NULL) {
243 243 ses_plugin_destroy(sp);
244 244 return (0);
245 245 }
246 246
247 247 /*
248 248 * Framework modules can establish an explicit prioritying by declaring
249 249 * the '_ses_priority' symbol, which returns an integer used to create
250 250 * an explicit ordering between plugins.
251 251 */
252 252 if ((ses_priority = (int (*)())dlsym(obj, "_ses_priority")) != NULL)
253 253 sp->sp_priority = ses_priority();
254 254
255 255 sp->sp_priority |= (uint64_t)pass << 32;
256 256
257 257 for (loc = &tp->st_plugin_first; *loc != NULL; loc = &(*loc)->sp_next) {
258 258 if ((*loc)->sp_priority > sp->sp_priority)
259 259 break;
260 260 }
261 261
262 262 if (*loc != NULL)
263 263 (*loc)->sp_prev = sp;
264 264 else
265 265 tp->st_plugin_last = sp;
266 266
267 267 sp->sp_next = *loc;
268 268 *loc = sp;
269 269
270 270 if (sp->sp_init(sp) != 0)
271 271 return (-1);
272 272 sp->sp_initialized = B_TRUE;
273 273
274 274 return (0);
275 275 }
276 276
277 277 static int
278 278 ses_plugin_load_dir(ses_target_t *tp, const char *pluginroot)
279 279 {
280 280 char path[PATH_MAX];
281 281 DIR *dirp;
282 282 struct dirent64 *dp;
283 283 char *vendor, *product, *revision;
284 284 char isa[257];
285 285
286 286 (void) snprintf(path, sizeof (path), "%s/%s",
287 287 pluginroot, LIBSES_PLUGIN_FRAMEWORK);
288 288
289 289 #if defined(_LP64)
290 290 if (sysinfo(SI_ARCHITECTURE_64, isa, sizeof (isa)) < 0)
291 291 isa[0] = '\0';
292 292 #else
293 293 isa[0] = '\0';
294 294 #endif
295 295
296 296 if ((dirp = opendir(path)) != NULL) {
297 297 while ((dp = readdir64(dirp)) != NULL) {
298 298 if (strcmp(dp->d_name, ".") == 0 ||
299 299 strcmp(dp->d_name, "..") == 0)
300 300 continue;
301 301
302 302 (void) snprintf(path, sizeof (path), "%s/%s/%s/%s",
303 303 pluginroot, LIBSES_PLUGIN_FRAMEWORK,
304 304 isa, dp->d_name);
305 305
306 306 if (ses_plugin_loadone(tp, path, 0) != 0) {
307 307 (void) closedir(dirp);
308 308 return (-1);
309 309 }
310 310 }
311 311
312 312 (void) closedir(dirp);
313 313 }
314 314
315 315 /*
316 316 * Create a local copy of the vendor/product/revision, strip out any
317 317 * questionable characters, and then attempt to load each plugin.
318 318 */
319 319 vendor = strdupa(libscsi_vendor(tp->st_target));
320 320 product = strdupa(libscsi_product(tp->st_target));
321 321 revision = strdupa(libscsi_revision(tp->st_target));
322 322
323 323 ses_plugin_cleanstr(vendor);
324 324 ses_plugin_cleanstr(product);
325 325 ses_plugin_cleanstr(revision);
326 326
327 327 (void) snprintf(path, sizeof (path), "%s/%s/%s/%s%s", pluginroot,
328 328 LIBSES_PLUGIN_VENDOR, isa, vendor,
329 329 LIBSES_PLUGIN_EXT);
330 330 if (ses_plugin_loadone(tp, path, 1) != 0)
331 331 return (-1);
332 332
333 333 (void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s%s", pluginroot,
334 334 LIBSES_PLUGIN_VENDOR, isa, vendor, product,
335 335 LIBSES_PLUGIN_EXT);
336 336 if (ses_plugin_loadone(tp, path, 2) != 0)
337 337 return (-1);
338 338
339 339 (void) snprintf(path, sizeof (path), "%s/%s/%s/%s-%s-%s%s", pluginroot,
340 340 LIBSES_PLUGIN_VENDOR, isa, vendor, product,
341 341 revision, LIBSES_PLUGIN_EXT);
342 342 if (ses_plugin_loadone(tp, path, 3) != 0)
343 343 return (-1);
344 344
345 345 return (0);
346 346 }
347 347
348 348 int
349 349 ses_plugin_load(ses_target_t *tp)
350 350 {
351 351 char pluginroot[PATH_MAX];
352 352 const char *pluginpath, *p, *q;
353 353
354 354 if ((pluginpath = getenv("SES_PLUGINPATH")) == NULL)
355 355 pluginpath = LIBSES_DEFAULT_PLUGINDIR;
356 356 ses_plugin_dlclose = (getenv("SES_NODLCLOSE") == NULL);
357 357
358 358 for (p = pluginpath; p != NULL; p = q) {
359 359 if ((q = strchr(p, ':')) != NULL) {
360 360 ptrdiff_t len = q - p;
361 361 (void) strncpy(pluginroot, p, len);
362 362 pluginroot[len] = '\0';
363 363 while (*q == ':')
364 364 ++q;
365 365 if (*q == '\0')
366 366 q = NULL;
367 367 if (len == 0)
368 368 continue;
369 369 } else {
370 370 (void) strcpy(pluginroot, p);
371 371 }
372 372
373 373 if (pluginroot[0] != '/')
374 374 continue;
375 375
376 376 if (ses_plugin_load_dir(tp, pluginroot) != 0)
377 377 return (-1);
378 378 }
379 379
380 380 if (tp->st_plugin_first == NULL)
381 381 return (ses_error(ESES_PLUGIN, "no plugins found"));
382 382
383 383 return (0);
384 384 }
385 385
386 386 void
387 387 ses_plugin_unload(ses_target_t *tp)
388 388 {
389 389 ses_plugin_t *sp;
390 390
391 391 while ((sp = tp->st_plugin_first) != NULL) {
392 392 tp->st_plugin_first = sp->sp_next;
393 393 ses_plugin_destroy(sp);
394 394 }
395 395 }
|
↓ open down ↓ |
359 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX