xref: /freebsd-13-stable/stand/libsa/zfs/zfs.c (revision 3d497e17ebd33fe0f58d773e35ab994d750258d6)
1 /*-
2  * Copyright (c) 2007 Doug Rabson
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 /*
29  *	Stand-alone file reading package.
30  */
31 
32 #include <stand.h>
33 #include <sys/disk.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/queue.h>
37 #include <part.h>
38 #include <stddef.h>
39 #include <stdarg.h>
40 #include <string.h>
41 #include <bootstrap.h>
42 
43 #include "libzfs.h"
44 
45 #include "zfsimpl.c"
46 
47 /* Define the range of indexes to be populated with ZFS Boot Environments */
48 #define		ZFS_BE_FIRST	4
49 #define		ZFS_BE_LAST	8
50 
51 static int	zfs_open(const char *path, struct open_file *f);
52 static int	zfs_close(struct open_file *f);
53 static int	zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
54 static off_t	zfs_seek(struct open_file *f, off_t offset, int where);
55 static int	zfs_stat(struct open_file *f, struct stat *sb);
56 static int	zfs_readdir(struct open_file *f, struct dirent *d);
57 static int	zfs_mount(const char *dev, const char *path, void **data);
58 static int	zfs_unmount(const char *dev, void *data);
59 
60 static void	zfs_bootenv_initial(const char *envname, spa_t *spa,
61 		    const char *name, const char *dsname, int checkpoint);
62 static void	zfs_checkpoints_initial(spa_t *spa, const char *name,
63 		    const char *dsname);
64 
65 static int	zfs_parsedev(struct devdesc **idev, const char *devspec,
66 		    const char **path);
67 
68 struct devsw zfs_dev;
69 
70 struct fs_ops zfs_fsops = {
71 	.fs_name = "zfs",
72 	.fo_open = zfs_open,
73 	.fo_close = zfs_close,
74 	.fo_read = zfs_read,
75 	.fo_write = null_write,
76 	.fo_seek = zfs_seek,
77 	.fo_stat = zfs_stat,
78 	.fo_readdir = zfs_readdir,
79 	.fo_mount = zfs_mount,
80 	.fo_unmount = zfs_unmount
81 };
82 
83 /*
84  * In-core open file.
85  */
86 struct file {
87 	off_t		f_seekp;	/* seek pointer */
88 	dnode_phys_t	f_dnode;
89 	uint64_t	f_zap_type;	/* zap type for readdir */
90 	uint64_t	f_num_leafs;	/* number of fzap leaf blocks */
91 	zap_leaf_phys_t	*f_zap_leaf;	/* zap leaf buffer */
92 };
93 
94 static int	zfs_env_index;
95 static int	zfs_env_count;
96 
97 SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
98 struct zfs_be_list *zfs_be_headp;
99 struct zfs_be_entry {
100 	char *name;
101 	SLIST_ENTRY(zfs_be_entry) entries;
102 } *zfs_be, *zfs_be_tmp;
103 
104 /*
105  * Open a file.
106  */
107 static int
zfs_open(const char * upath,struct open_file * f)108 zfs_open(const char *upath, struct open_file *f)
109 {
110 	struct devdesc *dev = f->f_devdata;
111 	struct zfsmount *mount = dev->d_opendata;
112 	struct file *fp;
113 	int rc;
114 
115 	if (f->f_dev != &zfs_dev)
116 		return (EINVAL);
117 
118 	/* allocate file system specific data structure */
119 	fp = calloc(1, sizeof(struct file));
120 	if (fp == NULL)
121 		return (ENOMEM);
122 	f->f_fsdata = fp;
123 
124 	rc = zfs_lookup(mount, upath, &fp->f_dnode);
125 	fp->f_seekp = 0;
126 	if (rc) {
127 		f->f_fsdata = NULL;
128 		free(fp);
129 	}
130 	return (rc);
131 }
132 
133 static int
zfs_close(struct open_file * f)134 zfs_close(struct open_file *f)
135 {
136 	struct file *fp = (struct file *)f->f_fsdata;
137 
138 	dnode_cache_obj = NULL;
139 	f->f_fsdata = NULL;
140 
141 	free(fp);
142 	return (0);
143 }
144 
145 /*
146  * Copy a portion of a file into kernel memory.
147  * Cross block boundaries when necessary.
148  */
149 static int
zfs_read(struct open_file * f,void * start,size_t size,size_t * resid)150 zfs_read(struct open_file *f, void *start, size_t size, size_t *resid	/* out */)
151 {
152 	struct devdesc *dev = f->f_devdata;
153 	const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa;
154 	struct file *fp = (struct file *)f->f_fsdata;
155 	struct stat sb;
156 	size_t n;
157 	int rc;
158 
159 	rc = zfs_stat(f, &sb);
160 	if (rc)
161 		return (rc);
162 	n = size;
163 	if (fp->f_seekp + n > sb.st_size)
164 		n = sb.st_size - fp->f_seekp;
165 
166 	rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n);
167 	if (rc)
168 		return (rc);
169 
170 	if (0) {
171 	    int i;
172 	    for (i = 0; i < n; i++)
173 		putchar(((char*) start)[i]);
174 	}
175 	fp->f_seekp += n;
176 	if (resid)
177 		*resid = size - n;
178 
179 	return (0);
180 }
181 
182 static off_t
zfs_seek(struct open_file * f,off_t offset,int where)183 zfs_seek(struct open_file *f, off_t offset, int where)
184 {
185 	struct file *fp = (struct file *)f->f_fsdata;
186 
187 	switch (where) {
188 	case SEEK_SET:
189 		fp->f_seekp = offset;
190 		break;
191 	case SEEK_CUR:
192 		fp->f_seekp += offset;
193 		break;
194 	case SEEK_END:
195 	    {
196 		struct stat sb;
197 		int error;
198 
199 		error = zfs_stat(f, &sb);
200 		if (error != 0) {
201 			errno = error;
202 			return (-1);
203 		}
204 		fp->f_seekp = sb.st_size - offset;
205 		break;
206 	    }
207 	default:
208 		errno = EINVAL;
209 		return (-1);
210 	}
211 	return (fp->f_seekp);
212 }
213 
214 static int
zfs_stat(struct open_file * f,struct stat * sb)215 zfs_stat(struct open_file *f, struct stat *sb)
216 {
217 	struct devdesc *dev = f->f_devdata;
218 	const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa;
219 	struct file *fp = (struct file *)f->f_fsdata;
220 
221 	return (zfs_dnode_stat(spa, &fp->f_dnode, sb));
222 }
223 
224 static int
zfs_readdir(struct open_file * f,struct dirent * d)225 zfs_readdir(struct open_file *f, struct dirent *d)
226 {
227 	struct devdesc *dev = f->f_devdata;
228 	const spa_t *spa = ((struct zfsmount *)dev->d_opendata)->spa;
229 	struct file *fp = (struct file *)f->f_fsdata;
230 	mzap_ent_phys_t mze;
231 	struct stat sb;
232 	size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT;
233 	int rc;
234 
235 	rc = zfs_stat(f, &sb);
236 	if (rc)
237 		return (rc);
238 	if (!S_ISDIR(sb.st_mode))
239 		return (ENOTDIR);
240 
241 	/*
242 	 * If this is the first read, get the zap type.
243 	 */
244 	if (fp->f_seekp == 0) {
245 		rc = dnode_read(spa, &fp->f_dnode,
246 				0, &fp->f_zap_type, sizeof(fp->f_zap_type));
247 		if (rc)
248 			return (rc);
249 
250 		if (fp->f_zap_type == ZBT_MICRO) {
251 			fp->f_seekp = offsetof(mzap_phys_t, mz_chunk);
252 		} else {
253 			rc = dnode_read(spa, &fp->f_dnode,
254 					offsetof(zap_phys_t, zap_num_leafs),
255 					&fp->f_num_leafs,
256 					sizeof(fp->f_num_leafs));
257 			if (rc)
258 				return (rc);
259 
260 			fp->f_seekp = bsize;
261 			fp->f_zap_leaf = malloc(bsize);
262 			if (fp->f_zap_leaf == NULL)
263 				return (ENOMEM);
264 			rc = dnode_read(spa, &fp->f_dnode,
265 					fp->f_seekp,
266 					fp->f_zap_leaf,
267 					bsize);
268 			if (rc)
269 				return (rc);
270 		}
271 	}
272 
273 	if (fp->f_zap_type == ZBT_MICRO) {
274 	mzap_next:
275 		if (fp->f_seekp >= bsize)
276 			return (ENOENT);
277 
278 		rc = dnode_read(spa, &fp->f_dnode,
279 				fp->f_seekp, &mze, sizeof(mze));
280 		if (rc)
281 			return (rc);
282 		fp->f_seekp += sizeof(mze);
283 
284 		if (!mze.mze_name[0])
285 			goto mzap_next;
286 
287 		d->d_fileno = ZFS_DIRENT_OBJ(mze.mze_value);
288 		d->d_type = ZFS_DIRENT_TYPE(mze.mze_value);
289 		strcpy(d->d_name, mze.mze_name);
290 		d->d_namlen = strlen(d->d_name);
291 		return (0);
292 	} else {
293 		zap_leaf_t zl;
294 		zap_leaf_chunk_t *zc, *nc;
295 		int chunk;
296 		size_t namelen;
297 		char *p;
298 		uint64_t value;
299 
300 		/*
301 		 * Initialise this so we can use the ZAP size
302 		 * calculating macros.
303 		 */
304 		zl.l_bs = ilog2(bsize);
305 		zl.l_phys = fp->f_zap_leaf;
306 
307 		/*
308 		 * Figure out which chunk we are currently looking at
309 		 * and consider seeking to the next leaf. We use the
310 		 * low bits of f_seekp as a simple chunk index.
311 		 */
312 	fzap_next:
313 		chunk = fp->f_seekp & (bsize - 1);
314 		if (chunk == ZAP_LEAF_NUMCHUNKS(&zl)) {
315 			fp->f_seekp = rounddown2(fp->f_seekp, bsize) + bsize;
316 			chunk = 0;
317 
318 			/*
319 			 * Check for EOF and read the new leaf.
320 			 */
321 			if (fp->f_seekp >= bsize * fp->f_num_leafs)
322 				return (ENOENT);
323 
324 			rc = dnode_read(spa, &fp->f_dnode,
325 					fp->f_seekp,
326 					fp->f_zap_leaf,
327 					bsize);
328 			if (rc)
329 				return (rc);
330 		}
331 
332 		zc = &ZAP_LEAF_CHUNK(&zl, chunk);
333 		fp->f_seekp++;
334 		if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
335 			goto fzap_next;
336 
337 		namelen = zc->l_entry.le_name_numints;
338 		if (namelen > sizeof(d->d_name))
339 			namelen = sizeof(d->d_name);
340 
341 		/*
342 		 * Paste the name back together.
343 		 */
344 		nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk);
345 		p = d->d_name;
346 		while (namelen > 0) {
347 			int len;
348 			len = namelen;
349 			if (len > ZAP_LEAF_ARRAY_BYTES)
350 				len = ZAP_LEAF_ARRAY_BYTES;
351 			memcpy(p, nc->l_array.la_array, len);
352 			p += len;
353 			namelen -= len;
354 			nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next);
355 		}
356 		d->d_name[sizeof(d->d_name) - 1] = 0;
357 
358 		/*
359 		 * Assume the first eight bytes of the value are
360 		 * a uint64_t.
361 		 */
362 		value = fzap_leaf_value(&zl, zc);
363 
364 		d->d_fileno = ZFS_DIRENT_OBJ(value);
365 		d->d_type = ZFS_DIRENT_TYPE(value);
366 		d->d_namlen = strlen(d->d_name);
367 
368 		return (0);
369 	}
370 }
371 
372 /*
373  * if path is NULL, create mount structure, but do not add it to list.
374  */
375 static int
zfs_mount(const char * dev,const char * path,void ** data)376 zfs_mount(const char *dev, const char *path, void **data)
377 {
378 	struct zfs_devdesc *zfsdev = NULL;
379 	spa_t *spa;
380 	struct zfsmount *mnt = NULL;
381 	int rv;
382 
383 	errno = 0;
384 	rv = zfs_parsedev((struct devdesc **)&zfsdev, dev, NULL);
385 	if (rv != 0) {
386 		return (rv);
387 	}
388 
389 	spa = spa_find_by_dev(zfsdev);
390 	if (spa == NULL) {
391 		rv = ENXIO;
392 		goto err;
393 	}
394 
395 	mnt = calloc(1, sizeof(*mnt));
396 	if (mnt == NULL) {
397 		rv = ENOMEM;
398 		goto err;
399 	}
400 
401 	if (mnt->path != NULL) {
402 		mnt->path = strdup(path);
403 		if (mnt->path == NULL) {
404 			rv = ENOMEM;
405 			goto err;
406 		}
407 	}
408 
409 	rv = zfs_mount_impl(spa, zfsdev->root_guid, mnt);
410 
411 	if (rv == 0 && mnt->objset.os_type != DMU_OST_ZFS) {
412 		printf("Unexpected object set type %ju\n",
413 		    (uintmax_t)mnt->objset.os_type);
414 		rv = EIO;
415 	}
416 err:
417 	if (rv != 0) {
418 		if (mnt != NULL)
419 			free(mnt->path);
420 		free(mnt);
421 		free(zfsdev);
422 		return (rv);
423 	}
424 
425 	*data = mnt;
426 	if (path != NULL)
427 		STAILQ_INSERT_TAIL(&zfsmount, mnt, next);
428 
429 	free(zfsdev);
430 
431 	return (rv);
432 }
433 
434 static int
zfs_unmount(const char * dev,void * data)435 zfs_unmount(const char *dev, void *data)
436 {
437 	struct zfsmount *mnt = data;
438 
439 	STAILQ_REMOVE(&zfsmount, mnt, zfsmount, next);
440 	free(mnt->path);
441 	free(mnt);
442 	return (0);
443 }
444 
445 static int
vdev_read(vdev_t * vdev,void * priv,off_t offset,void * buf,size_t bytes)446 vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes)
447 {
448 	int fd, ret;
449 	size_t res, head, tail, total_size, full_sec_size;
450 	unsigned secsz, do_tail_read;
451 	off_t start_sec;
452 	char *outbuf, *bouncebuf;
453 
454 	fd = (uintptr_t) priv;
455 	outbuf = (char *) buf;
456 	bouncebuf = NULL;
457 
458 	ret = ioctl(fd, DIOCGSECTORSIZE, &secsz);
459 	if (ret != 0)
460 		return (ret);
461 
462 	/*
463 	 * Handling reads of arbitrary offset and size - multi-sector case
464 	 * and single-sector case.
465 	 *
466 	 *                        Multi-sector Case
467 	 *                (do_tail_read = true if tail > 0)
468 	 *
469 	 *   |<----------------------total_size--------------------->|
470 	 *   |                                                       |
471 	 *   |<--head-->|<--------------bytes------------>|<--tail-->|
472 	 *   |          |                                 |          |
473 	 *   |          |       |<~full_sec_size~>|       |          |
474 	 *   +------------------+                 +------------------+
475 	 *   |          |0101010|     .  .  .     |0101011|          |
476 	 *   +------------------+                 +------------------+
477 	 *         start_sec                         start_sec + n
478 	 *
479 	 *
480 	 *                      Single-sector Case
481 	 *                    (do_tail_read = false)
482 	 *
483 	 *              |<------total_size = secsz----->|
484 	 *              |                               |
485 	 *              |<-head->|<---bytes--->|<-tail->|
486 	 *              +-------------------------------+
487 	 *              |        |0101010101010|        |
488 	 *              +-------------------------------+
489 	 *                          start_sec
490 	 */
491 	start_sec = offset / secsz;
492 	head = offset % secsz;
493 	total_size = roundup2(head + bytes, secsz);
494 	tail = total_size - (head + bytes);
495 	do_tail_read = ((tail > 0) && (head + bytes > secsz));
496 	full_sec_size = total_size;
497 	if (head > 0)
498 		full_sec_size -= secsz;
499 	if (do_tail_read)
500 		full_sec_size -= secsz;
501 
502 	/* Return of partial sector data requires a bounce buffer. */
503 	if ((head > 0) || do_tail_read || bytes < secsz) {
504 		bouncebuf = malloc(secsz);
505 		if (bouncebuf == NULL) {
506 			printf("vdev_read: out of memory\n");
507 			return (ENOMEM);
508 		}
509 	}
510 
511 	if (lseek(fd, start_sec * secsz, SEEK_SET) == -1) {
512 		ret = errno;
513 		goto error;
514 	}
515 
516 	/* Partial data return from first sector */
517 	if (head > 0) {
518 		res = read(fd, bouncebuf, secsz);
519 		if (res != secsz) {
520 			ret = EIO;
521 			goto error;
522 		}
523 		memcpy(outbuf, bouncebuf + head, min(secsz - head, bytes));
524 		outbuf += min(secsz - head, bytes);
525 	}
526 
527 	/*
528 	 * Full data return from read sectors.
529 	 * Note, there is still corner case where we read
530 	 * from sector boundary, but less than sector size, e.g. reading 512B
531 	 * from 4k sector.
532 	 */
533 	if (full_sec_size > 0) {
534 		if (bytes < full_sec_size) {
535 			res = read(fd, bouncebuf, secsz);
536 			if (res != secsz) {
537 				ret = EIO;
538 				goto error;
539 			}
540 			memcpy(outbuf, bouncebuf, bytes);
541 		} else {
542 			res = read(fd, outbuf, full_sec_size);
543 			if (res != full_sec_size) {
544 				ret = EIO;
545 				goto error;
546 			}
547 			outbuf += full_sec_size;
548 		}
549 	}
550 
551 	/* Partial data return from last sector */
552 	if (do_tail_read) {
553 		res = read(fd, bouncebuf, secsz);
554 		if (res != secsz) {
555 			ret = EIO;
556 			goto error;
557 		}
558 		memcpy(outbuf, bouncebuf, secsz - tail);
559 	}
560 
561 	ret = 0;
562 error:
563 	free(bouncebuf);
564 	return (ret);
565 }
566 
567 static int
vdev_write(vdev_t * vdev,off_t offset,void * buf,size_t bytes)568 vdev_write(vdev_t *vdev, off_t offset, void *buf, size_t bytes)
569 {
570 	int fd, ret;
571 	size_t head, tail, total_size, full_sec_size;
572 	unsigned secsz, do_tail_write;
573 	off_t start_sec;
574 	ssize_t res;
575 	char *outbuf, *bouncebuf;
576 
577 	fd = (uintptr_t)vdev->v_priv;
578 	outbuf = (char *)buf;
579 	bouncebuf = NULL;
580 
581 	ret = ioctl(fd, DIOCGSECTORSIZE, &secsz);
582 	if (ret != 0)
583 		return (ret);
584 
585 	start_sec = offset / secsz;
586 	head = offset % secsz;
587 	total_size = roundup2(head + bytes, secsz);
588 	tail = total_size - (head + bytes);
589 	do_tail_write = ((tail > 0) && (head + bytes > secsz));
590 	full_sec_size = total_size;
591 	if (head > 0)
592 		full_sec_size -= secsz;
593 	if (do_tail_write)
594 		full_sec_size -= secsz;
595 
596 	/* Partial sector write requires a bounce buffer. */
597 	if ((head > 0) || do_tail_write || bytes < secsz) {
598 		bouncebuf = malloc(secsz);
599 		if (bouncebuf == NULL) {
600 			printf("vdev_write: out of memory\n");
601 			return (ENOMEM);
602 		}
603 	}
604 
605 	if (lseek(fd, start_sec * secsz, SEEK_SET) == -1) {
606 		ret = errno;
607 		goto error;
608 	}
609 
610 	/* Partial data for first sector */
611 	if (head > 0) {
612 		res = read(fd, bouncebuf, secsz);
613 		if ((unsigned)res != secsz) {
614 			ret = EIO;
615 			goto error;
616 		}
617 		memcpy(bouncebuf + head, outbuf, min(secsz - head, bytes));
618 		(void) lseek(fd, -secsz, SEEK_CUR);
619 		res = write(fd, bouncebuf, secsz);
620 		if ((unsigned)res != secsz) {
621 			ret = EIO;
622 			goto error;
623 		}
624 		outbuf += min(secsz - head, bytes);
625 	}
626 
627 	/*
628 	 * Full data write to sectors.
629 	 * Note, there is still corner case where we write
630 	 * to sector boundary, but less than sector size, e.g. write 512B
631 	 * to 4k sector.
632 	 */
633 	if (full_sec_size > 0) {
634 		if (bytes < full_sec_size) {
635 			res = read(fd, bouncebuf, secsz);
636 			if ((unsigned)res != secsz) {
637 				ret = EIO;
638 				goto error;
639 			}
640 			memcpy(bouncebuf, outbuf, bytes);
641 			(void) lseek(fd, -secsz, SEEK_CUR);
642 			res = write(fd, bouncebuf, secsz);
643 			if ((unsigned)res != secsz) {
644 				ret = EIO;
645 				goto error;
646 			}
647 		} else {
648 			res = write(fd, outbuf, full_sec_size);
649 			if ((unsigned)res != full_sec_size) {
650 				ret = EIO;
651 				goto error;
652 			}
653 			outbuf += full_sec_size;
654 		}
655 	}
656 
657 	/* Partial data write to last sector */
658 	if (do_tail_write) {
659 		res = read(fd, bouncebuf, secsz);
660 		if ((unsigned)res != secsz) {
661 			ret = EIO;
662 			goto error;
663 		}
664 		memcpy(bouncebuf, outbuf, secsz - tail);
665 		(void) lseek(fd, -secsz, SEEK_CUR);
666 		res = write(fd, bouncebuf, secsz);
667 		if ((unsigned)res != secsz) {
668 			ret = EIO;
669 			goto error;
670 		}
671 	}
672 
673 	ret = 0;
674 error:
675 	free(bouncebuf);
676 	return (ret);
677 }
678 
679 static int
zfs_dev_init(void)680 zfs_dev_init(void)
681 {
682 	spa_t *spa;
683 	spa_t *next;
684 	spa_t *prev;
685 
686 	zfs_init();
687 	if (archsw.arch_zfs_probe == NULL)
688 		return (ENXIO);
689 	archsw.arch_zfs_probe();
690 
691 	prev = NULL;
692 	spa = STAILQ_FIRST(&zfs_pools);
693 	while (spa != NULL) {
694 		next = STAILQ_NEXT(spa, spa_link);
695 		if (zfs_spa_init(spa)) {
696 			if (prev == NULL)
697 				STAILQ_REMOVE_HEAD(&zfs_pools, spa_link);
698 			else
699 				STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link);
700 		} else
701 			prev = spa;
702 		spa = next;
703 	}
704 	return (0);
705 }
706 
707 struct zfs_probe_args {
708 	int		fd;
709 	const char	*devname;
710 	uint64_t	*pool_guid;
711 	u_int		secsz;
712 };
713 
714 static int
zfs_diskread(void * arg,void * buf,size_t blocks,uint64_t offset)715 zfs_diskread(void *arg, void *buf, size_t blocks, uint64_t offset)
716 {
717 	struct zfs_probe_args *ppa;
718 
719 	ppa = (struct zfs_probe_args *)arg;
720 	return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd,
721 	    offset * ppa->secsz, buf, blocks * ppa->secsz));
722 }
723 
724 static int
zfs_probe(int fd,uint64_t * pool_guid)725 zfs_probe(int fd, uint64_t *pool_guid)
726 {
727 	spa_t *spa;
728 	int ret;
729 
730 	spa = NULL;
731 	ret = vdev_probe(vdev_read, vdev_write, (void *)(uintptr_t)fd, &spa);
732 	if (ret == 0 && pool_guid != NULL)
733 		if (*pool_guid == 0)
734 			*pool_guid = spa->spa_guid;
735 	return (ret);
736 }
737 
738 static int
zfs_probe_partition(void * arg,const char * partname,const struct ptable_entry * part)739 zfs_probe_partition(void *arg, const char *partname,
740     const struct ptable_entry *part)
741 {
742 	struct zfs_probe_args *ppa, pa;
743 	struct ptable *table;
744 	char devname[32];
745 	int ret;
746 
747 	/* Probe only freebsd-zfs and freebsd partitions */
748 	if (part->type != PART_FREEBSD &&
749 	    part->type != PART_FREEBSD_ZFS)
750 		return (0);
751 
752 	ppa = (struct zfs_probe_args *)arg;
753 	strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
754 	devname[strlen(ppa->devname) - 1] = '\0';
755 	snprintf(devname, sizeof(devname), "%s%s:", devname, partname);
756 	pa.fd = open(devname, O_RDWR);
757 	if (pa.fd == -1)
758 		return (0);
759 	ret = zfs_probe(pa.fd, ppa->pool_guid);
760 	if (ret == 0)
761 		return (0);
762 	/* Do we have BSD label here? */
763 	if (part->type == PART_FREEBSD) {
764 		pa.devname = devname;
765 		pa.pool_guid = ppa->pool_guid;
766 		pa.secsz = ppa->secsz;
767 		table = ptable_open(&pa, part->end - part->start + 1,
768 		    ppa->secsz, zfs_diskread);
769 		if (table != NULL) {
770 			ptable_iterate(table, &pa, zfs_probe_partition);
771 			ptable_close(table);
772 		}
773 	}
774 	close(pa.fd);
775 	return (0);
776 }
777 
778 /*
779  * Return bootenv nvlist from pool label.
780  */
781 int
zfs_get_bootenv(void * vdev,nvlist_t ** benvp)782 zfs_get_bootenv(void *vdev, nvlist_t **benvp)
783 {
784 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
785 	nvlist_t *benv = NULL;
786 	vdev_t *vd;
787 	spa_t *spa;
788 
789 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
790 		return (ENOTSUP);
791 
792 	if ((spa = spa_find_by_dev(dev)) == NULL)
793 		return (ENXIO);
794 
795 	if (spa->spa_bootenv == NULL) {
796 		STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children,
797 		    v_childlink) {
798 			benv = vdev_read_bootenv(vd);
799 
800 			if (benv != NULL)
801 				break;
802 		}
803 		spa->spa_bootenv = benv;
804 	} else {
805 		benv = spa->spa_bootenv;
806 	}
807 
808 	if (benv == NULL)
809 		return (ENOENT);
810 
811 	*benvp = benv;
812 	return (0);
813 }
814 
815 /*
816  * Store nvlist to pool label bootenv area. Also updates cached pointer in spa.
817  */
818 int
zfs_set_bootenv(void * vdev,nvlist_t * benv)819 zfs_set_bootenv(void *vdev, nvlist_t *benv)
820 {
821 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
822 	spa_t *spa;
823 	vdev_t *vd;
824 
825 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
826 		return (ENOTSUP);
827 
828 	if ((spa = spa_find_by_dev(dev)) == NULL)
829 		return (ENXIO);
830 
831 	STAILQ_FOREACH(vd, &spa->spa_root_vdev->v_children, v_childlink) {
832 		vdev_write_bootenv(vd, benv);
833 	}
834 
835 	spa->spa_bootenv = benv;
836 	return (0);
837 }
838 
839 /*
840  * Get bootonce value by key. The bootonce <key, value> pair is removed
841  * from the bootenv nvlist and the remaining nvlist is committed back to disk.
842  */
843 int
zfs_get_bootonce(void * vdev,const char * key,char * buf,size_t size)844 zfs_get_bootonce(void *vdev, const char *key, char *buf, size_t size)
845 {
846 	nvlist_t *benv;
847 	char *result = NULL;
848 	int result_size, rv;
849 
850 	if ((rv = zfs_get_bootenv(vdev, &benv)) != 0)
851 		return (rv);
852 
853 	if ((rv = nvlist_find(benv, key, DATA_TYPE_STRING, NULL,
854 	    &result, &result_size)) == 0) {
855 		if (result_size == 0) {
856 			/* ignore empty string */
857 			rv = ENOENT;
858 		} else {
859 			size = MIN((size_t)result_size + 1, size);
860 			strlcpy(buf, result, size);
861 		}
862 		(void) nvlist_remove(benv, key, DATA_TYPE_STRING);
863 		(void) zfs_set_bootenv(vdev, benv);
864 	}
865 
866 	return (rv);
867 }
868 
869 /*
870  * nvstore backend.
871  */
872 
873 static int zfs_nvstore_setter(void *, int, const char *,
874     const void *, size_t);
875 static int zfs_nvstore_setter_str(void *, const char *, const char *,
876     const char *);
877 static int zfs_nvstore_unset_impl(void *, const char *, bool);
878 static int zfs_nvstore_setenv(void *, void *);
879 
880 /*
881  * nvstore is only present for current rootfs pool.
882  */
883 static int
zfs_nvstore_sethook(struct env_var * ev,int flags __unused,const void * value)884 zfs_nvstore_sethook(struct env_var *ev, int flags __unused, const void *value)
885 {
886 	struct zfs_devdesc *dev;
887 	int rv;
888 
889 	archsw.arch_getdev((void **)&dev, NULL, NULL);
890 	if (dev == NULL)
891 		return (ENXIO);
892 
893 	rv = zfs_nvstore_setter_str(dev, NULL, ev->ev_name, value);
894 
895 	free(dev);
896 	return (rv);
897 }
898 
899 /*
900  * nvstore is only present for current rootfs pool.
901  */
902 static int
zfs_nvstore_unsethook(struct env_var * ev)903 zfs_nvstore_unsethook(struct env_var *ev)
904 {
905 	struct zfs_devdesc *dev;
906 	int rv;
907 
908 	archsw.arch_getdev((void **)&dev, NULL, NULL);
909 	if (dev == NULL)
910 		return (ENXIO);
911 
912 	rv = zfs_nvstore_unset_impl(dev, ev->ev_name, false);
913 
914 	free(dev);
915 	return (rv);
916 }
917 
918 static int
zfs_nvstore_getter(void * vdev,const char * name,void ** data)919 zfs_nvstore_getter(void *vdev, const char *name, void **data)
920 {
921 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
922 	spa_t *spa;
923 	nvlist_t *nv;
924 	char *str, **ptr;
925 	int size;
926 	int rv;
927 
928 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
929 		return (ENOTSUP);
930 
931 	if ((spa = spa_find_by_dev(dev)) == NULL)
932 		return (ENXIO);
933 
934 	if (spa->spa_bootenv == NULL)
935 		return (ENXIO);
936 
937 	if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST,
938 	    NULL, &nv, NULL) != 0)
939 		return (ENOENT);
940 
941 	rv = nvlist_find(nv, name, DATA_TYPE_STRING, NULL, &str, &size);
942 	if (rv == 0) {
943 		ptr = (char **)data;
944 		asprintf(ptr, "%.*s", size, str);
945 		if (*data == NULL)
946 			rv = ENOMEM;
947 	}
948 	nvlist_destroy(nv);
949 	return (rv);
950 }
951 
952 static int
zfs_nvstore_setter(void * vdev,int type,const char * name,const void * data,size_t size)953 zfs_nvstore_setter(void *vdev, int type, const char *name,
954     const void *data, size_t size)
955 {
956 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
957 	spa_t *spa;
958 	nvlist_t *nv;
959 	int rv;
960 	bool env_set = true;
961 
962 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
963 		return (ENOTSUP);
964 
965 	if ((spa = spa_find_by_dev(dev)) == NULL)
966 		return (ENXIO);
967 
968 	if (spa->spa_bootenv == NULL)
969 		return (ENXIO);
970 
971 	if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST,
972 	    NULL, &nv, NULL) != 0) {
973 		nv = nvlist_create(NV_UNIQUE_NAME);
974 		if (nv == NULL)
975 			return (ENOMEM);
976 	}
977 
978 	rv = 0;
979 	switch (type) {
980         case DATA_TYPE_INT8:
981 		if (size != sizeof (int8_t)) {
982 			rv = EINVAL;
983 			break;
984 		}
985 		rv = nvlist_add_int8(nv, name, *(int8_t *)data);
986 		break;
987 
988         case DATA_TYPE_INT16:
989 		if (size != sizeof (int16_t)) {
990 			rv = EINVAL;
991 			break;
992 		}
993 		rv = nvlist_add_int16(nv, name, *(int16_t *)data);
994 		break;
995 
996         case DATA_TYPE_INT32:
997 		if (size != sizeof (int32_t)) {
998 			rv = EINVAL;
999 			break;
1000 		}
1001 		rv = nvlist_add_int32(nv, name, *(int32_t *)data);
1002 		break;
1003 
1004         case DATA_TYPE_INT64:
1005 		if (size != sizeof (int64_t)) {
1006 			rv = EINVAL;
1007 			break;
1008 		}
1009 		rv = nvlist_add_int64(nv, name, *(int64_t *)data);
1010 		break;
1011 
1012         case DATA_TYPE_BYTE:
1013 		if (size != sizeof (uint8_t)) {
1014 			rv = EINVAL;
1015 			break;
1016 		}
1017 		rv = nvlist_add_byte(nv, name, *(int8_t *)data);
1018 		break;
1019 
1020         case DATA_TYPE_UINT8:
1021 		if (size != sizeof (uint8_t)) {
1022 			rv = EINVAL;
1023 			break;
1024 		}
1025 		rv = nvlist_add_uint8(nv, name, *(int8_t *)data);
1026 		break;
1027 
1028         case DATA_TYPE_UINT16:
1029 		if (size != sizeof (uint16_t)) {
1030 			rv = EINVAL;
1031 			break;
1032 		}
1033 		rv = nvlist_add_uint16(nv, name, *(uint16_t *)data);
1034 		break;
1035 
1036         case DATA_TYPE_UINT32:
1037 		if (size != sizeof (uint32_t)) {
1038 			rv = EINVAL;
1039 			break;
1040 		}
1041 		rv = nvlist_add_uint32(nv, name, *(uint32_t *)data);
1042 		break;
1043 
1044         case DATA_TYPE_UINT64:
1045 		if (size != sizeof (uint64_t)) {
1046 			rv = EINVAL;
1047 			break;
1048 		}
1049 		rv = nvlist_add_uint64(nv, name, *(uint64_t *)data);
1050 		break;
1051 
1052         case DATA_TYPE_STRING:
1053 		rv = nvlist_add_string(nv, name, data);
1054 		break;
1055 
1056 	case DATA_TYPE_BOOLEAN_VALUE:
1057 		if (size != sizeof (boolean_t)) {
1058 			rv = EINVAL;
1059 			break;
1060 		}
1061 		rv = nvlist_add_boolean_value(nv, name, *(boolean_t *)data);
1062 		break;
1063 
1064 	default:
1065 		rv = EINVAL;
1066 		break;
1067 	}
1068 
1069 	if (rv == 0) {
1070 		rv = nvlist_add_nvlist(spa->spa_bootenv, OS_NVSTORE, nv);
1071 		if (rv == 0) {
1072 			rv = zfs_set_bootenv(vdev, spa->spa_bootenv);
1073 		}
1074 		if (rv == 0) {
1075 			if (env_set) {
1076 				rv = zfs_nvstore_setenv(vdev,
1077 				    nvpair_find(nv, name));
1078 			} else {
1079 				env_discard(env_getenv(name));
1080 				rv = 0;
1081 			}
1082 		}
1083 	}
1084 
1085 	nvlist_destroy(nv);
1086 	return (rv);
1087 }
1088 
1089 static int
get_int64(const char * data,int64_t * ip)1090 get_int64(const char *data, int64_t *ip)
1091 {
1092 	char *end;
1093 	int64_t val;
1094 
1095 	errno = 0;
1096 	val = strtoll(data, &end, 0);
1097 	if (errno != 0 || *data == '\0' || *end != '\0')
1098 		return (EINVAL);
1099 
1100 	*ip = val;
1101 	return (0);
1102 }
1103 
1104 static int
get_uint64(const char * data,uint64_t * ip)1105 get_uint64(const char *data, uint64_t *ip)
1106 {
1107 	char *end;
1108 	uint64_t val;
1109 
1110 	errno = 0;
1111 	val = strtoull(data, &end, 0);
1112 	if (errno != 0 || *data == '\0' || *end != '\0')
1113 		return (EINVAL);
1114 
1115 	*ip = val;
1116 	return (0);
1117 }
1118 
1119 /*
1120  * Translate textual data to data type. If type is not set, and we are
1121  * creating new pair, use DATA_TYPE_STRING.
1122  */
1123 static int
zfs_nvstore_setter_str(void * vdev,const char * type,const char * name,const char * data)1124 zfs_nvstore_setter_str(void *vdev, const char *type, const char *name,
1125     const char *data)
1126 {
1127 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
1128 	spa_t *spa;
1129 	nvlist_t *nv;
1130 	int rv;
1131 	data_type_t dt;
1132 	int64_t val;
1133 	uint64_t uval;
1134 
1135 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
1136 		return (ENOTSUP);
1137 
1138 	if ((spa = spa_find_by_dev(dev)) == NULL)
1139 		return (ENXIO);
1140 
1141 	if (spa->spa_bootenv == NULL)
1142 		return (ENXIO);
1143 
1144 	if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST,
1145 	    NULL, &nv, NULL) != 0) {
1146 		nv = NULL;
1147 	}
1148 
1149 	if (type == NULL) {
1150 		nvp_header_t *nvh;
1151 
1152 		/*
1153 		 * if there is no existing pair, default to string.
1154 		 * Otherwise, use type from existing pair.
1155 		 */
1156 		nvh = nvpair_find(nv, name);
1157 		if (nvh == NULL) {
1158 			dt = DATA_TYPE_STRING;
1159 		} else {
1160 			nv_string_t *nvp_name;
1161 			nv_pair_data_t *nvp_data;
1162 
1163 			nvp_name = (nv_string_t *)(nvh + 1);
1164 			nvp_data = (nv_pair_data_t *)(&nvp_name->nv_data[0] +
1165 			    NV_ALIGN4(nvp_name->nv_size));
1166 			dt = nvp_data->nv_type;
1167 		}
1168 	} else {
1169 		dt = nvpair_type_from_name(type);
1170 	}
1171 	nvlist_destroy(nv);
1172 
1173 	rv = 0;
1174 	switch (dt) {
1175         case DATA_TYPE_INT8:
1176 		rv = get_int64(data, &val);
1177 		if (rv == 0) {
1178 			int8_t v = val;
1179 
1180 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1181 		}
1182 		break;
1183         case DATA_TYPE_INT16:
1184 		rv = get_int64(data, &val);
1185 		if (rv == 0) {
1186 			int16_t v = val;
1187 
1188 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1189 		}
1190 		break;
1191         case DATA_TYPE_INT32:
1192 		rv = get_int64(data, &val);
1193 		if (rv == 0) {
1194 			int32_t v = val;
1195 
1196 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1197 		}
1198 		break;
1199         case DATA_TYPE_INT64:
1200 		rv = get_int64(data, &val);
1201 		if (rv == 0) {
1202 			rv = zfs_nvstore_setter(vdev, dt, name, &val,
1203 			    sizeof (val));
1204 		}
1205 		break;
1206 
1207         case DATA_TYPE_BYTE:
1208 		rv = get_uint64(data, &uval);
1209 		if (rv == 0) {
1210 			uint8_t v = uval;
1211 
1212 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1213 		}
1214 		break;
1215 
1216         case DATA_TYPE_UINT8:
1217 		rv = get_uint64(data, &uval);
1218 		if (rv == 0) {
1219 			uint8_t v = uval;
1220 
1221 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1222 		}
1223 		break;
1224 
1225         case DATA_TYPE_UINT16:
1226 		rv = get_uint64(data, &uval);
1227 		if (rv == 0) {
1228 			uint16_t v = uval;
1229 
1230 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1231 		}
1232 		break;
1233 
1234         case DATA_TYPE_UINT32:
1235 		rv = get_uint64(data, &uval);
1236 		if (rv == 0) {
1237 			uint32_t v = uval;
1238 
1239 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1240 		}
1241 		break;
1242 
1243         case DATA_TYPE_UINT64:
1244 		rv = get_uint64(data, &uval);
1245 		if (rv == 0) {
1246 			rv = zfs_nvstore_setter(vdev, dt, name, &uval,
1247 			    sizeof (uval));
1248 		}
1249 		break;
1250 
1251         case DATA_TYPE_STRING:
1252 		rv = zfs_nvstore_setter(vdev, dt, name, data, strlen(data) + 1);
1253 		break;
1254 
1255 	case DATA_TYPE_BOOLEAN_VALUE:
1256 		rv = get_int64(data, &val);
1257 		if (rv == 0) {
1258 			boolean_t v = val;
1259 
1260 			rv = zfs_nvstore_setter(vdev, dt, name, &v, sizeof (v));
1261 		}
1262 
1263 	default:
1264 		rv = EINVAL;
1265 	}
1266 	return (rv);
1267 }
1268 
1269 static int
zfs_nvstore_unset_impl(void * vdev,const char * name,bool unset_env)1270 zfs_nvstore_unset_impl(void *vdev, const char *name, bool unset_env)
1271 {
1272 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
1273 	spa_t *spa;
1274 	nvlist_t *nv;
1275 	int rv;
1276 
1277 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
1278 		return (ENOTSUP);
1279 
1280 	if ((spa = spa_find_by_dev(dev)) == NULL)
1281 		return (ENXIO);
1282 
1283 	if (spa->spa_bootenv == NULL)
1284 		return (ENXIO);
1285 
1286 	if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST,
1287 	    NULL, &nv, NULL) != 0)
1288 		return (ENOENT);
1289 
1290 	rv = nvlist_remove(nv, name, DATA_TYPE_UNKNOWN);
1291 	if (rv == 0) {
1292 		if (nvlist_next_nvpair(nv, NULL) == NULL) {
1293 			rv = nvlist_remove(spa->spa_bootenv, OS_NVSTORE,
1294 			    DATA_TYPE_NVLIST);
1295 		} else {
1296 			rv = nvlist_add_nvlist(spa->spa_bootenv,
1297 			    OS_NVSTORE, nv);
1298 		}
1299 		if (rv == 0)
1300 			rv = zfs_set_bootenv(vdev, spa->spa_bootenv);
1301 	}
1302 
1303 	if (unset_env)
1304 		env_discard(env_getenv(name));
1305 	return (rv);
1306 }
1307 
1308 static int
zfs_nvstore_unset(void * vdev,const char * name)1309 zfs_nvstore_unset(void *vdev, const char *name)
1310 {
1311 	return (zfs_nvstore_unset_impl(vdev, name, true));
1312 }
1313 
1314 static int
zfs_nvstore_print(void * vdev __unused,void * ptr)1315 zfs_nvstore_print(void *vdev __unused, void *ptr)
1316 {
1317 
1318 	nvpair_print(ptr, 0);
1319 	return (0);
1320 }
1321 
1322 /*
1323  * Create environment variable from nvpair.
1324  * set hook will update nvstore with new value, unset hook will remove
1325  * variable from nvstore.
1326  */
1327 static int
zfs_nvstore_setenv(void * vdev __unused,void * ptr)1328 zfs_nvstore_setenv(void *vdev __unused, void *ptr)
1329 {
1330 	nvp_header_t *nvh = ptr;
1331 	nv_string_t *nvp_name, *nvp_value;
1332 	nv_pair_data_t *nvp_data;
1333 	char *name, *value;
1334 	int rv = 0;
1335 
1336 	if (nvh == NULL)
1337 		return (ENOENT);
1338 
1339 	nvp_name = (nv_string_t *)(nvh + 1);
1340 	nvp_data = (nv_pair_data_t *)(&nvp_name->nv_data[0] +
1341 	    NV_ALIGN4(nvp_name->nv_size));
1342 
1343 	if ((name = nvstring_get(nvp_name)) == NULL)
1344 		return (ENOMEM);
1345 
1346 	value = NULL;
1347 	switch (nvp_data->nv_type) {
1348 	case DATA_TYPE_BYTE:
1349 	case DATA_TYPE_UINT8:
1350 		(void) asprintf(&value, "%uc",
1351 		    *(unsigned *)&nvp_data->nv_data[0]);
1352 		if (value == NULL)
1353 			rv = ENOMEM;
1354 		break;
1355 
1356 	case DATA_TYPE_INT8:
1357 		(void) asprintf(&value, "%c", *(int *)&nvp_data->nv_data[0]);
1358 		if (value == NULL)
1359 			rv = ENOMEM;
1360 		break;
1361 
1362 	case DATA_TYPE_INT16:
1363 		(void) asprintf(&value, "%hd", *(short *)&nvp_data->nv_data[0]);
1364 		if (value == NULL)
1365 			rv = ENOMEM;
1366 		break;
1367 
1368 	case DATA_TYPE_UINT16:
1369 		(void) asprintf(&value, "%hu",
1370 		    *(unsigned short *)&nvp_data->nv_data[0]);
1371 		if (value == NULL)
1372 			rv = ENOMEM;
1373 		break;
1374 
1375 	case DATA_TYPE_BOOLEAN_VALUE:
1376 	case DATA_TYPE_INT32:
1377 		(void) asprintf(&value, "%d", *(int *)&nvp_data->nv_data[0]);
1378 		if (value == NULL)
1379 			rv = ENOMEM;
1380 		break;
1381 
1382 	case DATA_TYPE_UINT32:
1383 		(void) asprintf(&value, "%u",
1384 		    *(unsigned *)&nvp_data->nv_data[0]);
1385 		if (value == NULL)
1386 			rv = ENOMEM;
1387 		break;
1388 
1389 	case DATA_TYPE_INT64:
1390 		(void) asprintf(&value, "%jd",
1391 		    (intmax_t)*(int64_t *)&nvp_data->nv_data[0]);
1392 		if (value == NULL)
1393 			rv = ENOMEM;
1394 		break;
1395 
1396 	case DATA_TYPE_UINT64:
1397 		(void) asprintf(&value, "%ju",
1398 		    (uintmax_t)*(uint64_t *)&nvp_data->nv_data[0]);
1399 		if (value == NULL)
1400 			rv = ENOMEM;
1401 		break;
1402 
1403 	case DATA_TYPE_STRING:
1404 		nvp_value = (nv_string_t *)&nvp_data->nv_data[0];
1405 		if ((value = nvstring_get(nvp_value)) == NULL) {
1406 			rv = ENOMEM;
1407 			break;
1408 		}
1409 		break;
1410 
1411 	default:
1412 		rv = EINVAL;
1413 		break;
1414 	}
1415 
1416 	if (value != NULL) {
1417 		rv = env_setenv(name, EV_VOLATILE | EV_NOHOOK, value,
1418 		    zfs_nvstore_sethook, zfs_nvstore_unsethook);
1419 		free(value);
1420 	}
1421 	free(name);
1422 	return (rv);
1423 }
1424 
1425 static int
zfs_nvstore_iterate(void * vdev,int (* cb)(void *,void *))1426 zfs_nvstore_iterate(void *vdev, int (*cb)(void *, void *))
1427 {
1428 	struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
1429 	spa_t *spa;
1430 	nvlist_t *nv;
1431 	nvp_header_t *nvh;
1432 	int rv;
1433 
1434 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
1435 		return (ENOTSUP);
1436 
1437 	if ((spa = spa_find_by_dev(dev)) == NULL)
1438 		return (ENXIO);
1439 
1440 	if (spa->spa_bootenv == NULL)
1441 		return (ENXIO);
1442 
1443 	if (nvlist_find(spa->spa_bootenv, OS_NVSTORE, DATA_TYPE_NVLIST,
1444 	    NULL, &nv, NULL) != 0)
1445 		return (ENOENT);
1446 
1447 	rv = 0;
1448 	nvh = NULL;
1449 	while ((nvh = nvlist_next_nvpair(nv, nvh)) != NULL) {
1450 		rv = cb(vdev, nvh);
1451 		if (rv != 0)
1452 			break;
1453 	}
1454 	return (rv);
1455 }
1456 
1457 nvs_callbacks_t nvstore_zfs_cb = {
1458 	.nvs_getter = zfs_nvstore_getter,
1459 	.nvs_setter = zfs_nvstore_setter,
1460 	.nvs_setter_str = zfs_nvstore_setter_str,
1461 	.nvs_unset = zfs_nvstore_unset,
1462 	.nvs_print = zfs_nvstore_print,
1463 	.nvs_iterate = zfs_nvstore_iterate
1464 };
1465 
1466 int
zfs_attach_nvstore(void * vdev)1467 zfs_attach_nvstore(void *vdev)
1468 {
1469 	struct zfs_devdesc *dev = vdev;
1470 	spa_t *spa;
1471 	uint64_t version;
1472 	int rv;
1473 
1474 	if (dev->dd.d_dev->dv_type != DEVT_ZFS)
1475 		return (ENOTSUP);
1476 
1477 	if ((spa = spa_find_by_dev(dev)) == NULL)
1478 		return (ENXIO);
1479 
1480 	rv = nvlist_find(spa->spa_bootenv, BOOTENV_VERSION, DATA_TYPE_UINT64,
1481 	    NULL, &version, NULL);
1482 
1483 	if (rv != 0 || version != VB_NVLIST) {
1484 		return (ENXIO);
1485 	}
1486 
1487 	dev = malloc(sizeof (*dev));
1488 	if (dev == NULL)
1489 		return (ENOMEM);
1490 	memcpy(dev, vdev, sizeof (*dev));
1491 
1492 	rv = nvstore_init(spa->spa_name, &nvstore_zfs_cb, dev);
1493 	if (rv != 0)
1494 		free(dev);
1495 	else
1496 		rv = zfs_nvstore_iterate(dev, zfs_nvstore_setenv);
1497 	return (rv);
1498 }
1499 
1500 int
zfs_probe_dev(const char * devname,uint64_t * pool_guid,bool parts_too)1501 zfs_probe_dev(const char *devname, uint64_t *pool_guid, bool parts_too)
1502 {
1503 	struct ptable *table;
1504 	struct zfs_probe_args pa;
1505 	uint64_t mediasz;
1506 	int ret;
1507 
1508 	if (pool_guid)
1509 		*pool_guid = 0;
1510 	pa.fd = open(devname, O_RDWR);
1511 	if (pa.fd == -1)
1512 		return (ENXIO);
1513 	/* Probe the whole disk */
1514 	ret = zfs_probe(pa.fd, pool_guid);
1515 	if (ret == 0)
1516 		return (0);
1517 	if (!parts_too)
1518 		return (ENXIO);
1519 
1520 	/* Probe each partition */
1521 	ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
1522 	if (ret == 0)
1523 		ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
1524 	if (ret == 0) {
1525 		pa.devname = devname;
1526 		pa.pool_guid = pool_guid;
1527 		table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
1528 		    zfs_diskread);
1529 		if (table != NULL) {
1530 			ptable_iterate(table, &pa, zfs_probe_partition);
1531 			ptable_close(table);
1532 		}
1533 	}
1534 	close(pa.fd);
1535 	if (pool_guid && *pool_guid == 0)
1536 		ret = ENXIO;
1537 	return (ret);
1538 }
1539 
1540 /*
1541  * Print information about ZFS pools
1542  */
1543 static int
zfs_dev_print(int verbose)1544 zfs_dev_print(int verbose)
1545 {
1546 	spa_t *spa;
1547 	char line[80];
1548 	int ret = 0;
1549 
1550 	if (STAILQ_EMPTY(&zfs_pools))
1551 		return (0);
1552 
1553 	printf("%s devices:", zfs_dev.dv_name);
1554 	if ((ret = pager_output("\n")) != 0)
1555 		return (ret);
1556 
1557 	if (verbose) {
1558 		return (spa_all_status());
1559 	}
1560 	STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
1561 		snprintf(line, sizeof(line), "    zfs:%s\n", spa->spa_name);
1562 		ret = pager_output(line);
1563 		if (ret != 0)
1564 			break;
1565 	}
1566 	return (ret);
1567 }
1568 
1569 /*
1570  * Attempt to open the pool described by (dev) for use by (f).
1571  */
1572 static int
zfs_dev_open(struct open_file * f,...)1573 zfs_dev_open(struct open_file *f, ...)
1574 {
1575 	va_list		args;
1576 	struct zfs_devdesc	*dev;
1577 	struct zfsmount	*mount;
1578 	spa_t		*spa;
1579 	int		rv;
1580 
1581 	va_start(args, f);
1582 	dev = va_arg(args, struct zfs_devdesc *);
1583 	va_end(args);
1584 
1585 	if ((spa = spa_find_by_dev(dev)) == NULL)
1586 		return (ENXIO);
1587 
1588 	STAILQ_FOREACH(mount, &zfsmount, next) {
1589 		if (spa->spa_guid == mount->spa->spa_guid)
1590 			break;
1591 	}
1592 
1593 	rv = 0;
1594 	/* This device is not set as currdev, mount us private copy. */
1595 	if (mount == NULL)
1596 		rv = zfs_mount(devformat(&dev->dd), NULL, (void **)&mount);
1597 
1598 	if (rv == 0) {
1599 		dev->dd.d_opendata = mount;
1600 	}
1601 	return (rv);
1602 }
1603 
1604 static int
zfs_dev_close(struct open_file * f)1605 zfs_dev_close(struct open_file *f)
1606 {
1607 	struct devdesc *dev;
1608 	struct zfsmount	*mnt, *mount;
1609 
1610 	dev = f->f_devdata;
1611 	mnt = dev->d_opendata;
1612 
1613 	STAILQ_FOREACH(mount, &zfsmount, next) {
1614 		if (mnt->spa->spa_guid == mount->spa->spa_guid)
1615 			break;
1616 	}
1617 
1618 	/* XXX */
1619 	return (0);
1620 }
1621 
1622 static int
zfs_dev_strategy(void * devdata,int rw,daddr_t dblk,size_t size,char * buf,size_t * rsize)1623 zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size, char *buf, size_t *rsize)
1624 {
1625 
1626 	return (ENOSYS);
1627 }
1628 
1629 struct devsw zfs_dev = {
1630 	.dv_name = "zfs",
1631 	.dv_type = DEVT_ZFS,
1632 	.dv_init = zfs_dev_init,
1633 	.dv_strategy = zfs_dev_strategy,
1634 	.dv_open = zfs_dev_open,
1635 	.dv_close = zfs_dev_close,
1636 	.dv_ioctl = noioctl,
1637 	.dv_print = zfs_dev_print,
1638 	.dv_cleanup = nullsys,
1639 	.dv_fmtdev = zfs_fmtdev,
1640 	.dv_parsedev = zfs_parsedev,
1641 };
1642 
1643 static int
zfs_parsedev(struct devdesc ** idev,const char * devspec,const char ** path)1644 zfs_parsedev(struct devdesc **idev, const char *devspec, const char **path)
1645 {
1646 	static char	rootname[ZFS_MAXNAMELEN];
1647 	static char	poolname[ZFS_MAXNAMELEN];
1648 	spa_t		*spa;
1649 	const char	*end;
1650 	const char	*np;
1651 	const char	*sep;
1652 	int		rv;
1653 	struct zfs_devdesc *dev;
1654 
1655 	np = devspec + 3;			/* Skip the leading 'zfs' */
1656 	if (*np != ':')
1657 		return (EINVAL);
1658 	np++;
1659 	end = strrchr(np, ':');
1660 	if (end == NULL)
1661 		return (EINVAL);
1662 	sep = strchr(np, '/');
1663 	if (sep == NULL || sep >= end)
1664 		sep = end;
1665 	memcpy(poolname, np, sep - np);
1666 	poolname[sep - np] = '\0';
1667 	if (sep < end) {
1668 		sep++;
1669 		memcpy(rootname, sep, end - sep);
1670 		rootname[end - sep] = '\0';
1671 	}
1672 	else
1673 		rootname[0] = '\0';
1674 
1675 	spa = spa_find_by_name(poolname);
1676 	if (!spa)
1677 		return (ENXIO);
1678 	dev = malloc(sizeof(*dev));
1679 	if (dev == NULL)
1680 		return (ENOMEM);
1681 	dev->pool_guid = spa->spa_guid;
1682 	rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
1683 	if (rv != 0) {
1684 		free(dev);
1685 		return (rv);
1686 	}
1687 	if (path != NULL)
1688 		*path = (*end == '\0') ? end : end + 1;
1689 	dev->dd.d_dev = &zfs_dev;
1690 	*idev = &dev->dd;
1691 	return (0);
1692 }
1693 
1694 char *
zfs_fmtdev(struct devdesc * vdev)1695 zfs_fmtdev(struct devdesc *vdev)
1696 {
1697 	static char		rootname[ZFS_MAXNAMELEN];
1698 	static char		buf[2 * ZFS_MAXNAMELEN + 8];
1699 	struct zfs_devdesc	*dev = (struct zfs_devdesc *)vdev;
1700 	spa_t			*spa;
1701 
1702 	buf[0] = '\0';
1703 	if (vdev->d_dev->dv_type != DEVT_ZFS)
1704 		return (buf);
1705 
1706 	/* Do we have any pools? */
1707 	spa = STAILQ_FIRST(&zfs_pools);
1708 	if (spa == NULL)
1709 		return (buf);
1710 
1711 	if (dev->pool_guid == 0)
1712 		dev->pool_guid = spa->spa_guid;
1713 	else
1714 		spa = spa_find_by_guid(dev->pool_guid);
1715 
1716 	if (spa == NULL) {
1717 		printf("ZFS: can't find pool by guid\n");
1718 		return (buf);
1719 	}
1720 	if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
1721 		printf("ZFS: can't find root filesystem\n");
1722 		return (buf);
1723 	}
1724 	if (zfs_rlookup(spa, dev->root_guid, rootname)) {
1725 		printf("ZFS: can't find filesystem by guid\n");
1726 		return (buf);
1727 	}
1728 
1729 	if (rootname[0] == '\0')
1730 		snprintf(buf, sizeof(buf), "%s:%s:", dev->dd.d_dev->dv_name,
1731 		    spa->spa_name);
1732 	else
1733 		snprintf(buf, sizeof(buf), "%s:%s/%s:", dev->dd.d_dev->dv_name,
1734 		    spa->spa_name, rootname);
1735 	return (buf);
1736 }
1737 
1738 static int
split_devname(const char * name,char * poolname,size_t size,const char ** dsnamep)1739 split_devname(const char *name, char *poolname, size_t size,
1740     const char **dsnamep)
1741 {
1742 	const char *dsname;
1743 	size_t len;
1744 
1745 	ASSERT(name != NULL);
1746 	ASSERT(poolname != NULL);
1747 
1748 	len = strlen(name);
1749 	dsname = strchr(name, '/');
1750 	if (dsname != NULL) {
1751 		len = dsname - name;
1752 		dsname++;
1753 	} else
1754 		dsname = "";
1755 
1756 	if (len + 1 > size)
1757 		return (EINVAL);
1758 
1759 	strlcpy(poolname, name, len + 1);
1760 
1761 	if (dsnamep != NULL)
1762 		*dsnamep = dsname;
1763 
1764 	return (0);
1765 }
1766 
1767 int
zfs_list(const char * name)1768 zfs_list(const char *name)
1769 {
1770 	static char	poolname[ZFS_MAXNAMELEN];
1771 	uint64_t	objid;
1772 	spa_t		*spa;
1773 	const char	*dsname;
1774 	int		rv;
1775 
1776 	if (split_devname(name, poolname, sizeof(poolname), &dsname) != 0)
1777 		return (EINVAL);
1778 
1779 	spa = spa_find_by_name(poolname);
1780 	if (!spa)
1781 		return (ENXIO);
1782 	rv = zfs_lookup_dataset(spa, dsname, &objid);
1783 	if (rv != 0)
1784 		return (rv);
1785 
1786 	return (zfs_list_dataset(spa, objid));
1787 }
1788 
1789 void
init_zfs_boot_options(const char * currdev_in)1790 init_zfs_boot_options(const char *currdev_in)
1791 {
1792 	char poolname[ZFS_MAXNAMELEN];
1793 	char *beroot, *currdev;
1794 	spa_t *spa;
1795 	int currdev_len;
1796 	const char *dsname;
1797 
1798 	currdev = NULL;
1799 	currdev_len = strlen(currdev_in);
1800 	if (currdev_len == 0)
1801 		return;
1802 	if (strncmp(currdev_in, "zfs:", 4) != 0)
1803 		return;
1804 	currdev = strdup(currdev_in);
1805 	if (currdev == NULL)
1806 		return;
1807 	/* Remove the trailing : */
1808 	currdev[currdev_len - 1] = '\0';
1809 
1810 	setenv("zfs_be_active", currdev, 1);
1811 	setenv("zfs_be_currpage", "1", 1);
1812 	/* Remove the last element (current bootenv) */
1813 	beroot = strrchr(currdev, '/');
1814 	if (beroot != NULL)
1815 		beroot[0] = '\0';
1816 	beroot = strchr(currdev, ':') + 1;
1817 	setenv("zfs_be_root", beroot, 1);
1818 
1819 	if (split_devname(beroot, poolname, sizeof(poolname), &dsname) != 0)
1820 		return;
1821 
1822 	spa = spa_find_by_name(poolname);
1823 	if (spa == NULL)
1824 		return;
1825 
1826 	zfs_bootenv_initial("bootenvs", spa, beroot, dsname, 0);
1827 	zfs_checkpoints_initial(spa, beroot, dsname);
1828 
1829 	free(currdev);
1830 }
1831 
1832 static void
zfs_checkpoints_initial(spa_t * spa,const char * name,const char * dsname)1833 zfs_checkpoints_initial(spa_t *spa, const char *name, const char *dsname)
1834 {
1835 	char envname[32];
1836 
1837 	if (spa->spa_uberblock_checkpoint.ub_checkpoint_txg != 0) {
1838 		snprintf(envname, sizeof(envname), "zpool_checkpoint");
1839 		setenv(envname, name, 1);
1840 
1841 		spa->spa_uberblock = &spa->spa_uberblock_checkpoint;
1842 		spa->spa_mos = &spa->spa_mos_checkpoint;
1843 
1844 		zfs_bootenv_initial("bootenvs_check", spa, name, dsname, 1);
1845 
1846 		spa->spa_uberblock = &spa->spa_uberblock_master;
1847 		spa->spa_mos = &spa->spa_mos_master;
1848 	}
1849 }
1850 
1851 static void
zfs_bootenv_initial(const char * envprefix,spa_t * spa,const char * rootname,const char * dsname,int checkpoint)1852 zfs_bootenv_initial(const char *envprefix, spa_t *spa, const char *rootname,
1853    const char *dsname, int checkpoint)
1854 {
1855 	char		envname[32], envval[256];
1856 	uint64_t	objid;
1857 	int		bootenvs_idx, rv;
1858 
1859 	SLIST_INIT(&zfs_be_head);
1860 	zfs_env_count = 0;
1861 
1862 	rv = zfs_lookup_dataset(spa, dsname, &objid);
1863 	if (rv != 0)
1864 		return;
1865 
1866 	rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
1867 	bootenvs_idx = 0;
1868 	/* Populate the initial environment variables */
1869 	SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
1870 		/* Enumerate all bootenvs for general usage */
1871 		snprintf(envname, sizeof(envname), "%s[%d]",
1872 		    envprefix, bootenvs_idx);
1873 		snprintf(envval, sizeof(envval), "zfs:%s%s/%s",
1874 		    checkpoint ? "!" : "", rootname, zfs_be->name);
1875 		rv = setenv(envname, envval, 1);
1876 		if (rv != 0)
1877 			break;
1878 		bootenvs_idx++;
1879 	}
1880 	snprintf(envname, sizeof(envname), "%s_count", envprefix);
1881 	snprintf(envval, sizeof(envval), "%d", bootenvs_idx);
1882 	setenv(envname, envval, 1);
1883 
1884 	/* Clean up the SLIST of ZFS BEs */
1885 	while (!SLIST_EMPTY(&zfs_be_head)) {
1886 		zfs_be = SLIST_FIRST(&zfs_be_head);
1887 		SLIST_REMOVE_HEAD(&zfs_be_head, entries);
1888 		free(zfs_be->name);
1889 		free(zfs_be);
1890 	}
1891 }
1892 
1893 int
zfs_bootenv(const char * name)1894 zfs_bootenv(const char *name)
1895 {
1896 	char		poolname[ZFS_MAXNAMELEN], *root;
1897 	const char	*dsname;
1898 	char		becount[4];
1899 	uint64_t	objid;
1900 	spa_t		*spa;
1901 	int		rv, pages, perpage, currpage;
1902 
1903 	if (name == NULL)
1904 		return (EINVAL);
1905 	if ((root = getenv("zfs_be_root")) == NULL)
1906 		return (EINVAL);
1907 
1908 	if (strcmp(name, root) != 0) {
1909 		if (setenv("zfs_be_root", name, 1) != 0)
1910 			return (ENOMEM);
1911 	}
1912 
1913 	SLIST_INIT(&zfs_be_head);
1914 	zfs_env_count = 0;
1915 
1916 	if (split_devname(name, poolname, sizeof(poolname), &dsname) != 0)
1917 		return (EINVAL);
1918 
1919 	spa = spa_find_by_name(poolname);
1920 	if (!spa)
1921 		return (ENXIO);
1922 	rv = zfs_lookup_dataset(spa, dsname, &objid);
1923 	if (rv != 0)
1924 		return (rv);
1925 	rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
1926 
1927 	/* Calculate and store the number of pages of BEs */
1928 	perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
1929 	pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
1930 	snprintf(becount, 4, "%d", pages);
1931 	if (setenv("zfs_be_pages", becount, 1) != 0)
1932 		return (ENOMEM);
1933 
1934 	/* Roll over the page counter if it has exceeded the maximum */
1935 	currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
1936 	if (currpage > pages) {
1937 		if (setenv("zfs_be_currpage", "1", 1) != 0)
1938 			return (ENOMEM);
1939 	}
1940 
1941 	/* Populate the menu environment variables */
1942 	zfs_set_env();
1943 
1944 	/* Clean up the SLIST of ZFS BEs */
1945 	while (!SLIST_EMPTY(&zfs_be_head)) {
1946 		zfs_be = SLIST_FIRST(&zfs_be_head);
1947 		SLIST_REMOVE_HEAD(&zfs_be_head, entries);
1948 		free(zfs_be->name);
1949 		free(zfs_be);
1950 	}
1951 
1952 	return (rv);
1953 }
1954 
1955 int
zfs_belist_add(const char * name,uint64_t value __unused)1956 zfs_belist_add(const char *name, uint64_t value __unused)
1957 {
1958 
1959 	/* Skip special datasets that start with a $ character */
1960 	if (strncmp(name, "$", 1) == 0) {
1961 		return (0);
1962 	}
1963 	/* Add the boot environment to the head of the SLIST */
1964 	zfs_be = malloc(sizeof(struct zfs_be_entry));
1965 	if (zfs_be == NULL) {
1966 		return (ENOMEM);
1967 	}
1968 	zfs_be->name = strdup(name);
1969 	if (zfs_be->name == NULL) {
1970 		free(zfs_be);
1971 		return (ENOMEM);
1972 	}
1973 	SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
1974 	zfs_env_count++;
1975 
1976 	return (0);
1977 }
1978 
1979 int
zfs_set_env(void)1980 zfs_set_env(void)
1981 {
1982 	char envname[32], envval[256];
1983 	char *beroot, *pagenum;
1984 	int rv, page, ctr;
1985 
1986 	beroot = getenv("zfs_be_root");
1987 	if (beroot == NULL) {
1988 		return (1);
1989 	}
1990 
1991 	pagenum = getenv("zfs_be_currpage");
1992 	if (pagenum != NULL) {
1993 		page = strtol(pagenum, NULL, 10);
1994 	} else {
1995 		page = 1;
1996 	}
1997 
1998 	ctr = 1;
1999 	rv = 0;
2000 	zfs_env_index = ZFS_BE_FIRST;
2001 	SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
2002 		/* Skip to the requested page number */
2003 		if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
2004 			ctr++;
2005 			continue;
2006 		}
2007 
2008 		snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
2009 		snprintf(envval, sizeof(envval), "%s", zfs_be->name);
2010 		rv = setenv(envname, envval, 1);
2011 		if (rv != 0) {
2012 			break;
2013 		}
2014 
2015 		snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
2016 		rv = setenv(envname, envval, 1);
2017 		if (rv != 0){
2018 			break;
2019 		}
2020 
2021 		snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
2022 		rv = setenv(envname, "set_bootenv", 1);
2023 		if (rv != 0){
2024 			break;
2025 		}
2026 
2027 		snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
2028 		snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
2029 		rv = setenv(envname, envval, 1);
2030 		if (rv != 0){
2031 			break;
2032 		}
2033 
2034 		zfs_env_index++;
2035 		if (zfs_env_index > ZFS_BE_LAST) {
2036 			break;
2037 		}
2038 
2039 	}
2040 
2041 	for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
2042 		snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
2043 		(void)unsetenv(envname);
2044 		snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
2045 		(void)unsetenv(envname);
2046 		snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
2047 		(void)unsetenv(envname);
2048 		snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
2049 		(void)unsetenv(envname);
2050 	}
2051 
2052 	return (rv);
2053 }
2054