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