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