5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25 */
26
27 #include <libxml/parser.h>
28 #include <libxml/xinclude.h>
29 #include <sys/fm/protocol.h>
30 #include <assert.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <ctype.h>
34 #include <errno.h>
35 #include <limits.h>
36 #include <fm/libtopo.h>
37 #include <unistd.h>
38 #include <sys/stat.h>
39 #include <fcntl.h>
40 #include <topo_file.h>
41 #include <topo_mod.h>
42 #include <topo_subr.h>
43 #include <topo_alloc.h>
44 #include <topo_parse.h>
177 rv = TOPO_TYPE_INT64_ARRAY;
178 } else if (xmlStrcmp(str, (xmlChar *)UInt64_Arr) == 0) {
179 rv = TOPO_TYPE_UINT64_ARRAY;
180 } else if (xmlStrcmp(str, (xmlChar *)String_Arr) == 0) {
181 rv = TOPO_TYPE_STRING_ARRAY;
182 } else if (xmlStrcmp(str, (xmlChar *)FMRI_Arr) == 0) {
183 rv = TOPO_TYPE_FMRI_ARRAY;
184 } else {
185 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
186 "Unrecognized type attribute value '%s'.\n", str);
187 (void) topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE);
188 xmlFree(str);
189 return (TOPO_TYPE_INVALID);
190 }
191 xmlFree(str);
192 return (rv);
193 }
194
195 static int
196 xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl,
197 const char *name)
198 {
199 int rv;
200 uint64_t ui;
201 uint_t i = 0, nelems = 0;
202 nvlist_t *fmri;
203 xmlChar *str;
204 char **strarrbuf;
205 void *arrbuf;
206 nvlist_t **nvlarrbuf;
207 xmlNodePtr cn;
208
209 topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xlate_common(name=%s)\n", name);
210 switch (ptype) {
211 case TOPO_TYPE_INT32:
212 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
213 return (-1);
214 rv = nvlist_add_int32(nvl, name, (int32_t)ui);
215 break;
216 case TOPO_TYPE_UINT32:
217 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
227 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
228 return (-1);
229 rv = nvlist_add_uint64(nvl, name, ui);
230 break;
231 case TOPO_TYPE_FMRI:
232 if (xmlattr_to_fmri(mp, xn, Value, &fmri) < 0)
233 return (-1);
234 rv = nvlist_add_nvlist(nvl, name, fmri);
235 nvlist_free(fmri);
236 break;
237 case TOPO_TYPE_STRING:
238 if ((str = xmlGetProp(xn, (xmlChar *)Value)) == NULL)
239 return (-1);
240 rv = nvlist_add_string(nvl, name, (char *)str);
241 xmlFree(str);
242 break;
243 case TOPO_TYPE_INT32_ARRAY:
244 case TOPO_TYPE_UINT32_ARRAY:
245 case TOPO_TYPE_INT64_ARRAY:
246 case TOPO_TYPE_UINT64_ARRAY:
247 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
248 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
249 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
250 nelems++;
251
252 if (nelems < 1) {
253 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
254 "or <argitem> elements found for array val");
255 return (-1);
256 }
257 if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint64_t))))
258 == NULL)
259 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
260 break;
261 case TOPO_TYPE_STRING_ARRAY:
262 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
263 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
264 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
265 nelems++;
266
267 if (nelems < 1) {
268 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
269 "or <argitem> elements found for array val");
270 return (-1);
271 }
272 if ((strarrbuf = topo_mod_alloc(mp, (nelems * sizeof (char *))))
273 == NULL)
274 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
275 break;
276 case TOPO_TYPE_FMRI_ARRAY:
277 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
278 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
279 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
280 nelems++;
281
282 if (nelems < 1) {
283 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
284 "elements found for array prop");
285 return (-1);
286 }
287 if ((nvlarrbuf = topo_mod_alloc(mp, (nelems *
288 sizeof (nvlist_t *)))) == NULL)
289 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
290 break;
291 default:
292 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
293 "Unrecognized type attribute (ptype = %d)\n", ptype);
294 return (topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE));
295 }
296
297 switch (ptype) {
298 case TOPO_TYPE_INT32_ARRAY:
299 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
300 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
301 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
302
303 if ((str = xmlGetProp(xn, (xmlChar *)Value))
304 == NULL)
305 return (-1);
306
307 ((int32_t *)arrbuf)[i++]
308 = atoi((const char *)str);
309 xmlFree(str);
310 }
311 }
312
313 rv = nvlist_add_int32_array(nvl, name, (int32_t *)arrbuf,
314 nelems);
315 free(arrbuf);
316 break;
317 case TOPO_TYPE_UINT32_ARRAY:
318 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
319 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
320 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
321
322 if ((str = xmlGetProp(xn, (xmlChar *)Value))
323 == NULL)
324 return (-1);
325
326 ((uint32_t *)arrbuf)[i++]
327 = atoi((const char *)str);
328 xmlFree(str);
329 }
330 }
331
332 rv = nvlist_add_uint32_array(nvl, name, (uint32_t *)arrbuf,
333 nelems);
334 free(arrbuf);
335 break;
336 case TOPO_TYPE_INT64_ARRAY:
337 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
338 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
339 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
340
341 if ((str = xmlGetProp(xn, (xmlChar *)Value))
342 == NULL)
343 return (-1);
344
345 ((int64_t *)arrbuf)[i++]
346 = atol((const char *)str);
347 xmlFree(str);
348 }
349 }
350
351 rv = nvlist_add_int64_array(nvl, name, (int64_t *)arrbuf,
352 nelems);
353 free(arrbuf);
354 break;
355 case TOPO_TYPE_UINT64_ARRAY:
356 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
357 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
358 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
359
360 if ((str = xmlGetProp(xn, (xmlChar *)Value))
361 == NULL)
362 return (-1);
363
364 ((uint64_t *)arrbuf)[i++]
365 = atol((const char *)str);
366 xmlFree(str);
367 }
368 }
369
370 rv = nvlist_add_uint64_array(nvl, name, arrbuf,
371 nelems);
372 free(arrbuf);
373 break;
374 case TOPO_TYPE_STRING_ARRAY:
375 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
376 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
377 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
378
379 if ((str = xmlGetProp(cn, (xmlChar *)Value))
380 == NULL)
381 return (-1);
382
383 strarrbuf[i++] =
384 topo_mod_strdup(mp, (const char *)str);
385 xmlFree(str);
386 }
387 }
388
389 rv = nvlist_add_string_array(nvl, name, strarrbuf, nelems);
390 strarr_free(mp, strarrbuf, nelems);
391 break;
392 case TOPO_TYPE_FMRI_ARRAY:
393 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
394 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
395 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
396
397 if ((str = xmlGetProp(xn, (xmlChar *)Value))
398 == NULL)
399 return (-1);
400
401 if (topo_mod_str2nvl(mp, (const char *)str,
402 &(nvlarrbuf[i++])) < 0) {
403 xmlFree(str);
404 return (-1);
405 }
406 xmlFree(str);
407 }
408 }
409
410 rv = nvlist_add_nvlist_array(nvl, name, nvlarrbuf,
411 nelems);
412 free(nvlarrbuf);
413 break;
414 }
415
416 if (rv != 0) {
417 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
418 "Nvlist construction failed.\n");
419 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
420 } else
421 return (0);
422 }
423
424 static int
425 xmlprop_xlate(topo_mod_t *mp, xmlNodePtr xn, nvlist_t *nvl)
426 {
427 topo_type_t ptype;
428 xmlChar *str;
429
430 topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xmlprop_xlate\n");
431 if ((str = xmlGetProp(xn, (xmlChar *)Immutable)) != NULL) {
432 if (xmlStrcmp(str, (xmlChar *)False) == 0)
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25 * Copyright (c) 2018, Western Digital Technologies, Inc. All rights reserved.
26 */
27
28 #include <libxml/parser.h>
29 #include <libxml/xinclude.h>
30 #include <sys/fm/protocol.h>
31 #include <assert.h>
32 #include <string.h>
33 #include <strings.h>
34 #include <ctype.h>
35 #include <errno.h>
36 #include <limits.h>
37 #include <fm/libtopo.h>
38 #include <unistd.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #include <topo_file.h>
42 #include <topo_mod.h>
43 #include <topo_subr.h>
44 #include <topo_alloc.h>
45 #include <topo_parse.h>
178 rv = TOPO_TYPE_INT64_ARRAY;
179 } else if (xmlStrcmp(str, (xmlChar *)UInt64_Arr) == 0) {
180 rv = TOPO_TYPE_UINT64_ARRAY;
181 } else if (xmlStrcmp(str, (xmlChar *)String_Arr) == 0) {
182 rv = TOPO_TYPE_STRING_ARRAY;
183 } else if (xmlStrcmp(str, (xmlChar *)FMRI_Arr) == 0) {
184 rv = TOPO_TYPE_FMRI_ARRAY;
185 } else {
186 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
187 "Unrecognized type attribute value '%s'.\n", str);
188 (void) topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE);
189 xmlFree(str);
190 return (TOPO_TYPE_INVALID);
191 }
192 xmlFree(str);
193 return (rv);
194 }
195
196 static int
197 xlate_common(topo_mod_t *mp, xmlNodePtr xn, topo_type_t ptype, nvlist_t *nvl,
198 const char *name)
199 {
200 int rv;
201 uint64_t ui;
202 uint_t i = 0, nelems = 0;
203 nvlist_t *fmri;
204 xmlChar *str;
205 char **strarrbuf;
206 void *arrbuf;
207 nvlist_t **nvlarrbuf;
208 xmlNodePtr cn;
209
210 topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xlate_common(name=%s)\n", name);
211 switch (ptype) {
212 case TOPO_TYPE_INT32:
213 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
214 return (-1);
215 rv = nvlist_add_int32(nvl, name, (int32_t)ui);
216 break;
217 case TOPO_TYPE_UINT32:
218 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
228 if (xmlattr_to_int(mp, xn, Value, &ui) < 0)
229 return (-1);
230 rv = nvlist_add_uint64(nvl, name, ui);
231 break;
232 case TOPO_TYPE_FMRI:
233 if (xmlattr_to_fmri(mp, xn, Value, &fmri) < 0)
234 return (-1);
235 rv = nvlist_add_nvlist(nvl, name, fmri);
236 nvlist_free(fmri);
237 break;
238 case TOPO_TYPE_STRING:
239 if ((str = xmlGetProp(xn, (xmlChar *)Value)) == NULL)
240 return (-1);
241 rv = nvlist_add_string(nvl, name, (char *)str);
242 xmlFree(str);
243 break;
244 case TOPO_TYPE_INT32_ARRAY:
245 case TOPO_TYPE_UINT32_ARRAY:
246 case TOPO_TYPE_INT64_ARRAY:
247 case TOPO_TYPE_UINT64_ARRAY:
248 case TOPO_TYPE_STRING_ARRAY:
249 case TOPO_TYPE_FMRI_ARRAY:
250 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next)
251 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
252 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0))
253 nelems++;
254
255 if (nelems < 1) {
256 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR, "No <propitem> "
257 "or <argitem> elements found for array val");
258 return (-1);
259 }
260 break;
261 default:
262 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
263 "Unrecognized type attribute (ptype = %d)\n", ptype);
264 return (topo_mod_seterrno(mp, ETOPO_PRSR_BADTYPE));
265 }
266
267 switch (ptype) {
268 case TOPO_TYPE_INT32_ARRAY:
269 if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (int32_t))))
270 == NULL)
271 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
272 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
273 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
274 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
275
276 if ((str = xmlGetProp(cn, (xmlChar *)Value))
277 == NULL)
278 return (-1);
279
280 ((int32_t *)arrbuf)[i++]
281 = atoi((const char *)str);
282 xmlFree(str);
283 }
284 }
285
286 rv = nvlist_add_int32_array(nvl, name, (int32_t *)arrbuf,
287 nelems);
288 topo_mod_free(mp, arrbuf, (nelems * sizeof (int32_t)));
289 break;
290 case TOPO_TYPE_UINT32_ARRAY:
291 if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint32_t))))
292 == NULL)
293 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
294 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
295 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
296 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
297
298 if ((str = xmlGetProp(cn, (xmlChar *)Value))
299 == NULL)
300 return (-1);
301
302 ((uint32_t *)arrbuf)[i++]
303 = atoi((const char *)str);
304 xmlFree(str);
305 }
306 }
307
308 rv = nvlist_add_uint32_array(nvl, name, (uint32_t *)arrbuf,
309 nelems);
310 topo_mod_free(mp, arrbuf, (nelems * sizeof (uint32_t)));
311 break;
312 case TOPO_TYPE_INT64_ARRAY:
313 if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (int64_t))))
314 == NULL)
315 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
316 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
317 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
318 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
319
320 if ((str = xmlGetProp(cn, (xmlChar *)Value))
321 == NULL)
322 return (-1);
323
324 ((int64_t *)arrbuf)[i++]
325 = atol((const char *)str);
326 xmlFree(str);
327 }
328 }
329
330 rv = nvlist_add_int64_array(nvl, name, (int64_t *)arrbuf,
331 nelems);
332 topo_mod_free(mp, arrbuf, (nelems * sizeof (int64_t)));
333 break;
334 case TOPO_TYPE_UINT64_ARRAY:
335 if ((arrbuf = topo_mod_alloc(mp, (nelems * sizeof (uint64_t))))
336 == NULL)
337 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
338 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
339 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
340 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
341
342 if ((str = xmlGetProp(cn, (xmlChar *)Value))
343 == NULL)
344 return (-1);
345
346 ((uint64_t *)arrbuf)[i++]
347 = atol((const char *)str);
348 xmlFree(str);
349 }
350 }
351
352 rv = nvlist_add_uint64_array(nvl, name, arrbuf,
353 nelems);
354 topo_mod_free(mp, arrbuf, (nelems * sizeof (uint64_t)));
355 break;
356 case TOPO_TYPE_STRING_ARRAY:
357 if ((strarrbuf = topo_mod_alloc(mp, (nelems * sizeof (char *))))
358 == NULL)
359 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
360 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
361 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
362 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
363
364 if ((str = xmlGetProp(cn, (xmlChar *)Value))
365 == NULL)
366 return (-1);
367
368 strarrbuf[i++] =
369 topo_mod_strdup(mp, (const char *)str);
370 xmlFree(str);
371 }
372 }
373
374 rv = nvlist_add_string_array(nvl, name, strarrbuf, nelems);
375 strarr_free(mp, strarrbuf, nelems);
376 break;
377 case TOPO_TYPE_FMRI_ARRAY:
378 if ((nvlarrbuf = topo_mod_alloc(mp, (nelems *
379 sizeof (nvlist_t *)))) == NULL)
380 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
381 for (cn = xn->xmlChildrenNode; cn != NULL; cn = cn->next) {
382 if ((xmlStrcmp(cn->name, (xmlChar *)Propitem) == 0) ||
383 (xmlStrcmp(cn->name, (xmlChar *)Argitem) == 0)) {
384
385 if ((str = xmlGetProp(cn, (xmlChar *)Value))
386 == NULL)
387 return (-1);
388
389 if (topo_mod_str2nvl(mp, (const char *)str,
390 &(nvlarrbuf[i++])) < 0) {
391 xmlFree(str);
392 return (-1);
393 }
394 xmlFree(str);
395 }
396 }
397
398 rv = nvlist_add_nvlist_array(nvl, name, nvlarrbuf,
399 nelems);
400 topo_mod_free(mp, nvlarrbuf, (nelems * sizeof (nvlist_t *)));
401 break;
402 }
403
404 if (rv != 0) {
405 topo_dprintf(mp->tm_hdl, TOPO_DBG_ERR,
406 "Nvlist construction failed.\n");
407 return (topo_mod_seterrno(mp, ETOPO_NOMEM));
408 } else
409 return (0);
410 }
411
412 static int
413 xmlprop_xlate(topo_mod_t *mp, xmlNodePtr xn, nvlist_t *nvl)
414 {
415 topo_type_t ptype;
416 xmlChar *str;
417
418 topo_dprintf(mp->tm_hdl, TOPO_DBG_XML, "xmlprop_xlate\n");
419 if ((str = xmlGetProp(xn, (xmlChar *)Immutable)) != NULL) {
420 if (xmlStrcmp(str, (xmlChar *)False) == 0)
|