1*76ca3cb0SRobert Mustacchi /* 2*76ca3cb0SRobert Mustacchi * This file and its contents are supplied under the terms of the 3*76ca3cb0SRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0. 4*76ca3cb0SRobert Mustacchi * You may only use this file in accordance with the terms of version 5*76ca3cb0SRobert Mustacchi * 1.0 of the CDDL. 6*76ca3cb0SRobert Mustacchi * 7*76ca3cb0SRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this 8*76ca3cb0SRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at 9*76ca3cb0SRobert Mustacchi * http://www.illumos.org/license/CDDL. 10*76ca3cb0SRobert Mustacchi */ 11*76ca3cb0SRobert Mustacchi 12*76ca3cb0SRobert Mustacchi /* 13*76ca3cb0SRobert Mustacchi * Copyright (c) 2015 Joyent, Inc. All rights reserved. 14*76ca3cb0SRobert Mustacchi */ 15*76ca3cb0SRobert Mustacchi 16*76ca3cb0SRobert Mustacchi /* 17*76ca3cb0SRobert Mustacchi * This file takes care of reading the boot time modules and constructing them 18*76ca3cb0SRobert Mustacchi * into the appropriate series of vnodes. 19*76ca3cb0SRobert Mustacchi */ 20*76ca3cb0SRobert Mustacchi 21*76ca3cb0SRobert Mustacchi #include <sys/conf.h> 22*76ca3cb0SRobert Mustacchi #include <sys/ddi.h> 23*76ca3cb0SRobert Mustacchi #include <sys/sunddi.h> 24*76ca3cb0SRobert Mustacchi #include <sys/vfs.h> 25*76ca3cb0SRobert Mustacchi #include <sys/sysmacros.h> 26*76ca3cb0SRobert Mustacchi #include <sys/stat.h> 27*76ca3cb0SRobert Mustacchi 28*76ca3cb0SRobert Mustacchi #include <sys/fs/bootfs_impl.h> 29*76ca3cb0SRobert Mustacchi 30*76ca3cb0SRobert Mustacchi kmem_cache_t *bootfs_node_cache; 31*76ca3cb0SRobert Mustacchi 32*76ca3cb0SRobert Mustacchi static const vattr_t bootfs_vattr_dir = { 33*76ca3cb0SRobert Mustacchi AT_ALL, /* va_mask */ 34*76ca3cb0SRobert Mustacchi VDIR, /* va_type */ 35*76ca3cb0SRobert Mustacchi S_IFDIR | 0555, /* va_mode */ 36*76ca3cb0SRobert Mustacchi 0, /* va_uid */ 37*76ca3cb0SRobert Mustacchi 0, /* va_gid */ 38*76ca3cb0SRobert Mustacchi 0, /* va_fsid */ 39*76ca3cb0SRobert Mustacchi 0, /* va_nodeid */ 40*76ca3cb0SRobert Mustacchi 1, /* va_nlink */ 41*76ca3cb0SRobert Mustacchi 0, /* va_size */ 42*76ca3cb0SRobert Mustacchi 0, /* va_atime */ 43*76ca3cb0SRobert Mustacchi 0, /* va_mtime */ 44*76ca3cb0SRobert Mustacchi 0, /* va_ctime */ 45*76ca3cb0SRobert Mustacchi 0, /* va_rdev */ 46*76ca3cb0SRobert Mustacchi 0, /* va_blksize */ 47*76ca3cb0SRobert Mustacchi 0, /* va_nblocks */ 48*76ca3cb0SRobert Mustacchi 0 /* va_seq */ 49*76ca3cb0SRobert Mustacchi }; 50*76ca3cb0SRobert Mustacchi 51*76ca3cb0SRobert Mustacchi static const vattr_t bootfs_vattr_reg = { 52*76ca3cb0SRobert Mustacchi AT_ALL, /* va_mask */ 53*76ca3cb0SRobert Mustacchi VREG, /* va_type */ 54*76ca3cb0SRobert Mustacchi S_IFREG | 0555, /* va_mode */ 55*76ca3cb0SRobert Mustacchi 0, /* va_uid */ 56*76ca3cb0SRobert Mustacchi 0, /* va_gid */ 57*76ca3cb0SRobert Mustacchi 0, /* va_fsid */ 58*76ca3cb0SRobert Mustacchi 0, /* va_nodeid */ 59*76ca3cb0SRobert Mustacchi 1, /* va_nlink */ 60*76ca3cb0SRobert Mustacchi 0, /* va_size */ 61*76ca3cb0SRobert Mustacchi 0, /* va_atime */ 62*76ca3cb0SRobert Mustacchi 0, /* va_mtime */ 63*76ca3cb0SRobert Mustacchi 0, /* va_ctime */ 64*76ca3cb0SRobert Mustacchi 0, /* va_rdev */ 65*76ca3cb0SRobert Mustacchi 0, /* va_blksize */ 66*76ca3cb0SRobert Mustacchi 0, /* va_nblocks */ 67*76ca3cb0SRobert Mustacchi 0 /* va_seq */ 68*76ca3cb0SRobert Mustacchi }; 69*76ca3cb0SRobert Mustacchi 70*76ca3cb0SRobert Mustacchi /*ARGSUSED*/ 71*76ca3cb0SRobert Mustacchi int 72*76ca3cb0SRobert Mustacchi bootfs_node_constructor(void *buf, void *arg, int kmflags) 73*76ca3cb0SRobert Mustacchi { 74*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp = buf; 75*76ca3cb0SRobert Mustacchi 76*76ca3cb0SRobert Mustacchi bnp->bvn_vnp = vn_alloc(kmflags); 77*76ca3cb0SRobert Mustacchi if (bnp->bvn_vnp == NULL) 78*76ca3cb0SRobert Mustacchi return (-1); 79*76ca3cb0SRobert Mustacchi 80*76ca3cb0SRobert Mustacchi return (0); 81*76ca3cb0SRobert Mustacchi } 82*76ca3cb0SRobert Mustacchi 83*76ca3cb0SRobert Mustacchi /*ARGSUSED*/ 84*76ca3cb0SRobert Mustacchi void 85*76ca3cb0SRobert Mustacchi bootfs_node_destructor(void *buf, void *arg) 86*76ca3cb0SRobert Mustacchi { 87*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp = buf; 88*76ca3cb0SRobert Mustacchi 89*76ca3cb0SRobert Mustacchi vn_free(bnp->bvn_vnp); 90*76ca3cb0SRobert Mustacchi } 91*76ca3cb0SRobert Mustacchi 92*76ca3cb0SRobert Mustacchi static int 93*76ca3cb0SRobert Mustacchi bootfs_comparator(const void *a, const void *b) 94*76ca3cb0SRobert Mustacchi { 95*76ca3cb0SRobert Mustacchi const bootfs_node_t *lfs, *rfs; 96*76ca3cb0SRobert Mustacchi int ret; 97*76ca3cb0SRobert Mustacchi 98*76ca3cb0SRobert Mustacchi lfs = a; 99*76ca3cb0SRobert Mustacchi rfs = b; 100*76ca3cb0SRobert Mustacchi 101*76ca3cb0SRobert Mustacchi ret = strcmp(lfs->bvn_name, rfs->bvn_name); 102*76ca3cb0SRobert Mustacchi if (ret > 0) 103*76ca3cb0SRobert Mustacchi ret = 1; 104*76ca3cb0SRobert Mustacchi if (ret < 0) 105*76ca3cb0SRobert Mustacchi ret = -1; 106*76ca3cb0SRobert Mustacchi return (ret); 107*76ca3cb0SRobert Mustacchi } 108*76ca3cb0SRobert Mustacchi 109*76ca3cb0SRobert Mustacchi static void 110*76ca3cb0SRobert Mustacchi bootfs_node_init(bootfs_t *bfs, bootfs_node_t *bnp, const struct vattr *vap, 111*76ca3cb0SRobert Mustacchi const char *name, size_t namelen) 112*76ca3cb0SRobert Mustacchi { 113*76ca3cb0SRobert Mustacchi timestruc_t now; 114*76ca3cb0SRobert Mustacchi 115*76ca3cb0SRobert Mustacchi vn_reinit(bnp->bvn_vnp); 116*76ca3cb0SRobert Mustacchi 117*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_flag |= VNOSWAP; 118*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_type = vap->va_type; 119*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_vfsp = bfs->bfs_vfsp; 120*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_rdev = 0; 121*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_data = (caddr_t)bnp; 122*76ca3cb0SRobert Mustacchi vn_setops(bnp->bvn_vnp, bootfs_vnodeops); 123*76ca3cb0SRobert Mustacchi 124*76ca3cb0SRobert Mustacchi bnp->bvn_name = kmem_alloc(namelen + 1, KM_SLEEP); 125*76ca3cb0SRobert Mustacchi bcopy(name, bnp->bvn_name, namelen); 126*76ca3cb0SRobert Mustacchi bnp->bvn_name[namelen] = '\0'; 127*76ca3cb0SRobert Mustacchi if (vap->va_type == VDIR) { 128*76ca3cb0SRobert Mustacchi avl_create(&bnp->bvn_dir, bootfs_comparator, 129*76ca3cb0SRobert Mustacchi sizeof (bootfs_node_t), 130*76ca3cb0SRobert Mustacchi offsetof(bootfs_node_t, bvn_link)); 131*76ca3cb0SRobert Mustacchi } 132*76ca3cb0SRobert Mustacchi bzero(&bnp->bvn_link, sizeof (avl_node_t)); 133*76ca3cb0SRobert Mustacchi bcopy(vap, &bnp->bvn_attr, sizeof (vattr_t)); 134*76ca3cb0SRobert Mustacchi 135*76ca3cb0SRobert Mustacchi gethrestime(&now); 136*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_atime = now; 137*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_ctime = now; 138*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_mtime = now; 139*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_fsid = makedevice(bootfs_major, bfs->bfs_minor); 140*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_nodeid = bfs->bfs_ninode; 141*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_blksize = PAGESIZE; 142*76ca3cb0SRobert Mustacchi bfs->bfs_ninode++; 143*76ca3cb0SRobert Mustacchi list_insert_tail(&bfs->bfs_nodes, bnp); 144*76ca3cb0SRobert Mustacchi } 145*76ca3cb0SRobert Mustacchi 146*76ca3cb0SRobert Mustacchi static void 147*76ca3cb0SRobert Mustacchi bootfs_mkroot(bootfs_t *bfs) 148*76ca3cb0SRobert Mustacchi { 149*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp; 150*76ca3cb0SRobert Mustacchi 151*76ca3cb0SRobert Mustacchi bnp = kmem_cache_alloc(bootfs_node_cache, KM_SLEEP); 152*76ca3cb0SRobert Mustacchi bootfs_node_init(bfs, bnp, &bootfs_vattr_dir, "/", 1); 153*76ca3cb0SRobert Mustacchi bnp->bvn_vnp->v_flag |= VROOT; 154*76ca3cb0SRobert Mustacchi bnp->bvn_parent = bnp; 155*76ca3cb0SRobert Mustacchi bfs->bfs_rootvn = bnp; 156*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_ndirs.value.ui32++; 157*76ca3cb0SRobert Mustacchi vn_exists(bnp->bvn_vnp); 158*76ca3cb0SRobert Mustacchi } 159*76ca3cb0SRobert Mustacchi 160*76ca3cb0SRobert Mustacchi static int 161*76ca3cb0SRobert Mustacchi bootfs_mknode(bootfs_t *bfs, bootfs_node_t *parent, bootfs_node_t **outp, 162*76ca3cb0SRobert Mustacchi const char *name, size_t namelen, const vattr_t *vap, uintptr_t addr, 163*76ca3cb0SRobert Mustacchi uint64_t size) 164*76ca3cb0SRobert Mustacchi { 165*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp; 166*76ca3cb0SRobert Mustacchi bootfs_node_t sn; 167*76ca3cb0SRobert Mustacchi avl_index_t where; 168*76ca3cb0SRobert Mustacchi char *buf; 169*76ca3cb0SRobert Mustacchi 170*76ca3cb0SRobert Mustacchi ASSERT(parent->bvn_attr.va_type == VDIR); 171*76ca3cb0SRobert Mustacchi buf = kmem_alloc(namelen + 1, KM_SLEEP); 172*76ca3cb0SRobert Mustacchi bcopy(name, buf, namelen); 173*76ca3cb0SRobert Mustacchi buf[namelen] = '\0'; 174*76ca3cb0SRobert Mustacchi sn.bvn_name = buf; 175*76ca3cb0SRobert Mustacchi if ((bnp = avl_find(&parent->bvn_dir, &sn, &where)) != NULL) { 176*76ca3cb0SRobert Mustacchi kmem_free(buf, namelen + 1); 177*76ca3cb0SRobert Mustacchi /* Directories can collide, files cannot */ 178*76ca3cb0SRobert Mustacchi if (vap->va_type == VDIR) { 179*76ca3cb0SRobert Mustacchi *outp = bnp; 180*76ca3cb0SRobert Mustacchi return (0); 181*76ca3cb0SRobert Mustacchi } 182*76ca3cb0SRobert Mustacchi return (EEXIST); 183*76ca3cb0SRobert Mustacchi } 184*76ca3cb0SRobert Mustacchi kmem_free(buf, namelen + 1); 185*76ca3cb0SRobert Mustacchi 186*76ca3cb0SRobert Mustacchi bnp = kmem_cache_alloc(bootfs_node_cache, KM_SLEEP); 187*76ca3cb0SRobert Mustacchi bootfs_node_init(bfs, bnp, vap, name, namelen); 188*76ca3cb0SRobert Mustacchi bnp->bvn_parent = parent; 189*76ca3cb0SRobert Mustacchi avl_add(&parent->bvn_dir, bnp); 190*76ca3cb0SRobert Mustacchi *outp = bnp; 191*76ca3cb0SRobert Mustacchi 192*76ca3cb0SRobert Mustacchi if (vap->va_type == VDIR) { 193*76ca3cb0SRobert Mustacchi parent->bvn_attr.va_size++; 194*76ca3cb0SRobert Mustacchi parent->bvn_attr.va_nlink++; 195*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_ndirs.value.ui32++; 196*76ca3cb0SRobert Mustacchi } else { 197*76ca3cb0SRobert Mustacchi bnp->bvn_addr = addr; 198*76ca3cb0SRobert Mustacchi bnp->bvn_size = size; 199*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_nfiles.value.ui32++; 200*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_nbytes.value.ui64 += size; 201*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_nblocks = P2ROUNDUP(size, 512) >> 9; 202*76ca3cb0SRobert Mustacchi bnp->bvn_attr.va_size = size; 203*76ca3cb0SRobert Mustacchi } 204*76ca3cb0SRobert Mustacchi 205*76ca3cb0SRobert Mustacchi vn_exists(bnp->bvn_vnp); 206*76ca3cb0SRobert Mustacchi 207*76ca3cb0SRobert Mustacchi return (0); 208*76ca3cb0SRobert Mustacchi } 209*76ca3cb0SRobert Mustacchi 210*76ca3cb0SRobert Mustacchi /* 211*76ca3cb0SRobert Mustacchi * Given the address, size, and path a boot-time module would like, go through 212*76ca3cb0SRobert Mustacchi * and create all of the directory entries that are required and then the file 213*76ca3cb0SRobert Mustacchi * itself. If someone has passed in a module that has the same name as another 214*76ca3cb0SRobert Mustacchi * one, we honor the first one. 215*76ca3cb0SRobert Mustacchi */ 216*76ca3cb0SRobert Mustacchi static int 217*76ca3cb0SRobert Mustacchi bootfs_construct_entry(bootfs_t *bfs, uintptr_t addr, uint64_t size, 218*76ca3cb0SRobert Mustacchi const char *mname) 219*76ca3cb0SRobert Mustacchi { 220*76ca3cb0SRobert Mustacchi char *sp; 221*76ca3cb0SRobert Mustacchi size_t nlen; 222*76ca3cb0SRobert Mustacchi int ret; 223*76ca3cb0SRobert Mustacchi bootfs_node_t *nbnp; 224*76ca3cb0SRobert Mustacchi 225*76ca3cb0SRobert Mustacchi const char *p = mname; 226*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp = bfs->bfs_rootvn; 227*76ca3cb0SRobert Mustacchi 228*76ca3cb0SRobert Mustacchi if (*p == '\0') 229*76ca3cb0SRobert Mustacchi return (EINVAL); 230*76ca3cb0SRobert Mustacchi 231*76ca3cb0SRobert Mustacchi for (;;) { 232*76ca3cb0SRobert Mustacchi /* First eliminate all leading / characters. */ 233*76ca3cb0SRobert Mustacchi while (*p == '/') 234*76ca3cb0SRobert Mustacchi p++; 235*76ca3cb0SRobert Mustacchi 236*76ca3cb0SRobert Mustacchi /* A name with all slashes or ending in a / */ 237*76ca3cb0SRobert Mustacchi if (*p == '\0') 238*76ca3cb0SRobert Mustacchi return (EINVAL); 239*76ca3cb0SRobert Mustacchi 240*76ca3cb0SRobert Mustacchi sp = strchr(p, '/'); 241*76ca3cb0SRobert Mustacchi if (sp == NULL) 242*76ca3cb0SRobert Mustacchi break; 243*76ca3cb0SRobert Mustacchi nlen = (ptrdiff_t)sp - (ptrdiff_t)p; 244*76ca3cb0SRobert Mustacchi if (strncmp(p, ".", nlen) == 0) { 245*76ca3cb0SRobert Mustacchi p = sp + 1; 246*76ca3cb0SRobert Mustacchi continue; 247*76ca3cb0SRobert Mustacchi } 248*76ca3cb0SRobert Mustacchi 249*76ca3cb0SRobert Mustacchi if (strncmp(p, "..", nlen) == 0) { 250*76ca3cb0SRobert Mustacchi bnp = bnp->bvn_parent; 251*76ca3cb0SRobert Mustacchi p = sp + 1; 252*76ca3cb0SRobert Mustacchi continue; 253*76ca3cb0SRobert Mustacchi } 254*76ca3cb0SRobert Mustacchi 255*76ca3cb0SRobert Mustacchi VERIFY(bootfs_mknode(bfs, bnp, &nbnp, p, nlen, 256*76ca3cb0SRobert Mustacchi &bootfs_vattr_dir, addr, size) == 0); 257*76ca3cb0SRobert Mustacchi p = sp + 1; 258*76ca3cb0SRobert Mustacchi bnp = nbnp; 259*76ca3cb0SRobert Mustacchi } 260*76ca3cb0SRobert Mustacchi 261*76ca3cb0SRobert Mustacchi nlen = strlen(p); 262*76ca3cb0SRobert Mustacchi ret = bootfs_mknode(bfs, bnp, &nbnp, p, nlen, &bootfs_vattr_reg, 263*76ca3cb0SRobert Mustacchi addr, size); 264*76ca3cb0SRobert Mustacchi if (ret != 0) 265*76ca3cb0SRobert Mustacchi return (ret); 266*76ca3cb0SRobert Mustacchi 267*76ca3cb0SRobert Mustacchi return (0); 268*76ca3cb0SRobert Mustacchi } 269*76ca3cb0SRobert Mustacchi 270*76ca3cb0SRobert Mustacchi /* 271*76ca3cb0SRobert Mustacchi * We're going to go through every boot time module and construct the 272*76ca3cb0SRobert Mustacchi * appropriate vnodes for them now. Because there are very few of these that 273*76ca3cb0SRobert Mustacchi * exist, generally on the order of a handful, we're going to create them all 274*76ca3cb0SRobert Mustacchi * when the file system is initialized and then tear them all down when the 275*76ca3cb0SRobert Mustacchi * module gets unloaded. 276*76ca3cb0SRobert Mustacchi * 277*76ca3cb0SRobert Mustacchi * The information about the modules is contained in properties on the root of 278*76ca3cb0SRobert Mustacchi * the devinfo tree. Specifically there are three properties per module: 279*76ca3cb0SRobert Mustacchi * 280*76ca3cb0SRobert Mustacchi * - module-size-%d int64_t size, in bytes, of the boot time module. 281*76ca3cb0SRobert Mustacchi * - module-addr-%d The address of the boot time module 282*76ca3cb0SRobert Mustacchi * - module-name-%d The string name of the boot time module 283*76ca3cb0SRobert Mustacchi * 284*76ca3cb0SRobert Mustacchi * Note that the module-size and module-addr fields are always 64-bit values 285*76ca3cb0SRobert Mustacchi * regardless of being on a 32-bit or 64-bit kernel. module-name is a string 286*76ca3cb0SRobert Mustacchi * property. 287*76ca3cb0SRobert Mustacchi * 288*76ca3cb0SRobert Mustacchi * There is no property that indicates the total number of such modules. Modules 289*76ca3cb0SRobert Mustacchi * start at 0 and work their way up incrementally. The first time we can't find 290*76ca3cb0SRobert Mustacchi * a module or a property, then we stop. 291*76ca3cb0SRobert Mustacchi */ 292*76ca3cb0SRobert Mustacchi void 293*76ca3cb0SRobert Mustacchi bootfs_construct(bootfs_t *bfs) 294*76ca3cb0SRobert Mustacchi { 295*76ca3cb0SRobert Mustacchi uint_t id = 0, ndata; 296*76ca3cb0SRobert Mustacchi char paddr[64], psize[64], pname[64], *mname; 297*76ca3cb0SRobert Mustacchi dev_info_t *root; 298*76ca3cb0SRobert Mustacchi uchar_t *datap; 299*76ca3cb0SRobert Mustacchi uint64_t size = 0, addr = 0; 300*76ca3cb0SRobert Mustacchi int ret; 301*76ca3cb0SRobert Mustacchi 302*76ca3cb0SRobert Mustacchi bootfs_mkroot(bfs); 303*76ca3cb0SRobert Mustacchi root = ddi_root_node(); 304*76ca3cb0SRobert Mustacchi 305*76ca3cb0SRobert Mustacchi for (;;) { 306*76ca3cb0SRobert Mustacchi if (id == UINT32_MAX) 307*76ca3cb0SRobert Mustacchi break; 308*76ca3cb0SRobert Mustacchi 309*76ca3cb0SRobert Mustacchi if (snprintf(paddr, sizeof (paddr), "module-addr-%d", id) > 310*76ca3cb0SRobert Mustacchi sizeof (paddr)) 311*76ca3cb0SRobert Mustacchi break; 312*76ca3cb0SRobert Mustacchi 313*76ca3cb0SRobert Mustacchi if (snprintf(psize, sizeof (paddr), "module-size-%d", id) > 314*76ca3cb0SRobert Mustacchi sizeof (paddr)) 315*76ca3cb0SRobert Mustacchi break; 316*76ca3cb0SRobert Mustacchi 317*76ca3cb0SRobert Mustacchi if (snprintf(pname, sizeof (paddr), "module-name-%d", id) > 318*76ca3cb0SRobert Mustacchi sizeof (paddr)) 319*76ca3cb0SRobert Mustacchi break; 320*76ca3cb0SRobert Mustacchi 321*76ca3cb0SRobert Mustacchi if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, root, 322*76ca3cb0SRobert Mustacchi DDI_PROP_DONTPASS, paddr, &datap, &ndata) != 323*76ca3cb0SRobert Mustacchi DDI_PROP_SUCCESS) 324*76ca3cb0SRobert Mustacchi break; 325*76ca3cb0SRobert Mustacchi 326*76ca3cb0SRobert Mustacchi if (ndata == 8) 327*76ca3cb0SRobert Mustacchi bcopy(datap, &addr, sizeof (uint64_t)); 328*76ca3cb0SRobert Mustacchi ddi_prop_free(datap); 329*76ca3cb0SRobert Mustacchi if (ndata != 8) 330*76ca3cb0SRobert Mustacchi break; 331*76ca3cb0SRobert Mustacchi 332*76ca3cb0SRobert Mustacchi if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, root, 333*76ca3cb0SRobert Mustacchi DDI_PROP_DONTPASS, psize, &datap, &ndata) != 334*76ca3cb0SRobert Mustacchi DDI_PROP_SUCCESS) 335*76ca3cb0SRobert Mustacchi break; 336*76ca3cb0SRobert Mustacchi if (ndata == 8) 337*76ca3cb0SRobert Mustacchi bcopy(datap, &size, sizeof (uint64_t)); 338*76ca3cb0SRobert Mustacchi ddi_prop_free(datap); 339*76ca3cb0SRobert Mustacchi if (ndata != 8) 340*76ca3cb0SRobert Mustacchi break; 341*76ca3cb0SRobert Mustacchi 342*76ca3cb0SRobert Mustacchi if (ddi_prop_lookup_string(DDI_DEV_T_ANY, root, 343*76ca3cb0SRobert Mustacchi DDI_PROP_DONTPASS, pname, &mname) != DDI_PROP_SUCCESS) 344*76ca3cb0SRobert Mustacchi break; 345*76ca3cb0SRobert Mustacchi 346*76ca3cb0SRobert Mustacchi ret = bootfs_construct_entry(bfs, addr, size, mname); 347*76ca3cb0SRobert Mustacchi if (ret == EINVAL) 348*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_ndiscards.value.ui32++; 349*76ca3cb0SRobert Mustacchi if (ret == EEXIST) 350*76ca3cb0SRobert Mustacchi bfs->bfs_stat.bfss_ndups.value.ui32++; 351*76ca3cb0SRobert Mustacchi ddi_prop_free(mname); 352*76ca3cb0SRobert Mustacchi 353*76ca3cb0SRobert Mustacchi id++; 354*76ca3cb0SRobert Mustacchi } 355*76ca3cb0SRobert Mustacchi } 356*76ca3cb0SRobert Mustacchi 357*76ca3cb0SRobert Mustacchi void 358*76ca3cb0SRobert Mustacchi bootfs_destruct(bootfs_t *bfs) 359*76ca3cb0SRobert Mustacchi { 360*76ca3cb0SRobert Mustacchi bootfs_node_t *bnp; 361*76ca3cb0SRobert Mustacchi 362*76ca3cb0SRobert Mustacchi while ((bnp = list_remove_head(&bfs->bfs_nodes)) != NULL) { 363*76ca3cb0SRobert Mustacchi ASSERT(bnp->bvn_vnp->v_count == 1); 364*76ca3cb0SRobert Mustacchi VN_RELE(bnp->bvn_vnp); 365*76ca3cb0SRobert Mustacchi kmem_free(bnp->bvn_name, strlen(bnp->bvn_name) + 1); 366*76ca3cb0SRobert Mustacchi kmem_cache_free(bootfs_node_cache, bnp); 367*76ca3cb0SRobert Mustacchi } 368*76ca3cb0SRobert Mustacchi } 369