xref: /titanic_52/usr/src/uts/common/fs/bootfs/bootfs_construct.c (revision 76ca3cb000306bc4052fe820a7e4a6998dbcf932)
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