Print this page
8954 libtopo cannot handle any array type other than string_array.
Reviewed by: Andy Stormont astormont@racktopsystems.com
Reviewed by: David Höppner 0xffea@gmail.com
Reviewed by: Rob Johnston rob.johnston@joyent.com


   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)