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