annotate usr/src/boot/sys/boot/zfs/zfs.c @ 18825:2ed7ea649fe9

loader: zfs_bootfs() needs to use config pool txg for boot device illumos issue #9423
author Toomas Soome <tsoome@me.com>
date Thu, 29 Mar 2018 16:11:54 +0300
parents d5ab76c227a2
children f69311ba75b3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
18803
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
1 /*
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
2 * Copyright (c) 2007 Doug Rabson
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
3 * All rights reserved.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
4 *
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
5 * Redistribution and use in source and binary forms, with or without
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
6 * modification, are permitted provided that the following conditions
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
7 * are met:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
8 * 1. Redistributions of source code must retain the above copyright
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
9 * notice, this list of conditions and the following disclaimer.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
10 * 2. Redistributions in binary form must reproduce the above copyright
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
11 * notice, this list of conditions and the following disclaimer in the
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
12 * documentation and/or other materials provided with the distribution.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
13 *
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
24 * SUCH DAMAGE.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
25 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
26
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
27 #include <sys/cdefs.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
28
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
29 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
30 * Stand-alone file reading package.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
31 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
32
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
33 #include <sys/disk.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
34 #include <sys/param.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
35 #include <sys/time.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
36 #include <sys/queue.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
37 #include <part.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
38 #include <stddef.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
39 #include <stdarg.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
40 #include <string.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
41 #include <stand.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
42 #include <bootstrap.h>
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
43
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
44 #include "libzfs.h"
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
45
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
46 #include "zfsimpl.c"
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
47
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
48 /* Define the range of indexes to be populated with ZFS Boot Environments */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
49 #define ZFS_BE_FIRST 4
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
50 #define ZFS_BE_LAST 8
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
51
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
52 static int zfs_open(const char *path, struct open_file *f);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
53 static int zfs_close(struct open_file *f);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
54 static int zfs_read(struct open_file *f, void *buf, size_t size, size_t *resid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
55 static off_t zfs_seek(struct open_file *f, off_t offset, int where);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
56 static int zfs_stat(struct open_file *f, struct stat *sb);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
57 static int zfs_readdir(struct open_file *f, struct dirent *d);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
58
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
59 struct devsw zfs_dev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
60
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
61 struct fs_ops zfs_fsops = {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
62 "zfs",
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
63 zfs_open,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
64 zfs_close,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
65 zfs_read,
18820
d5ab76c227a2 libstand: Const-ify buffer argument of write(2) analog
Toomas Soome <tsoome@me.com>
parents: 18817
diff changeset
66 null_write,
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
67 zfs_seek,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
68 zfs_stat,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
69 zfs_readdir
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
70 };
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
71
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
72 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
73 * In-core open file.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
74 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
75 struct file {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
76 off_t f_seekp; /* seek pointer */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
77 dnode_phys_t f_dnode;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
78 uint64_t f_zap_type; /* zap type for readdir */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
79 uint64_t f_num_leafs; /* number of fzap leaf blocks */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
80 zap_leaf_phys_t *f_zap_leaf; /* zap leaf buffer */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
81 };
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
82
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
83 #ifdef __FreeBSD__
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
84 static int zfs_env_index;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
85 static int zfs_env_count;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
86 #endif
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
87
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
88 SLIST_HEAD(zfs_be_list, zfs_be_entry) zfs_be_head = SLIST_HEAD_INITIALIZER(zfs_be_head);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
89 struct zfs_be_list *zfs_be_headp;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
90 struct zfs_be_entry {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
91 const char *name;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
92 SLIST_ENTRY(zfs_be_entry) entries;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
93 } *zfs_be, *zfs_be_tmp;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
94
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
95 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
96 * Open a file.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
97 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
98 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
99 zfs_open(const char *upath, struct open_file *f)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
100 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
101 struct zfsmount *mount = (struct zfsmount *)f->f_devdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
102 struct file *fp;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
103 int rc;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
104
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
105 if (f->f_dev != &zfs_dev)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
106 return (EINVAL);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
107
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
108 /* allocate file system specific data structure */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
109 fp = malloc(sizeof(struct file));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
110 bzero(fp, sizeof(struct file));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
111 f->f_fsdata = (void *)fp;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
112
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
113 rc = zfs_lookup(mount, upath, &fp->f_dnode);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
114 fp->f_seekp = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
115 if (rc) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
116 f->f_fsdata = NULL;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
117 free(fp);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
118 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
119 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
120 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
121
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
122 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
123 zfs_close(struct open_file *f)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
124 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
125 struct file *fp = (struct file *)f->f_fsdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
126
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
127 dnode_cache_obj = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
128 f->f_fsdata = (void *)0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
129 if (fp == (struct file *)0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
130 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
131
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
132 free(fp);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
133 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
134 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
135
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
136 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
137 * Copy a portion of a file into kernel memory.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
138 * Cross block boundaries when necessary.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
139 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
140 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
141 zfs_read(struct open_file *f, void *start, size_t size, size_t *resid /* out */)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
142 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
143 const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
144 struct file *fp = (struct file *)f->f_fsdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
145 struct stat sb;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
146 size_t n;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
147 int rc;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
148
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
149 rc = zfs_stat(f, &sb);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
150 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
151 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
152 n = size;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
153 if (fp->f_seekp + n > sb.st_size)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
154 n = sb.st_size - fp->f_seekp;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
155
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
156 rc = dnode_read(spa, &fp->f_dnode, fp->f_seekp, start, n);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
157 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
158 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
159
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
160 if (0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
161 int i;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
162 for (i = 0; i < n; i++)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
163 putchar(((char*) start)[i]);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
164 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
165 fp->f_seekp += n;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
166 if (resid)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
167 *resid = size - n;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
168
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
169 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
170 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
171
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
172 static off_t
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
173 zfs_seek(struct open_file *f, off_t offset, int where)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
174 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
175 struct file *fp = (struct file *)f->f_fsdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
176
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
177 switch (where) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
178 case SEEK_SET:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
179 fp->f_seekp = offset;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
180 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
181 case SEEK_CUR:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
182 fp->f_seekp += offset;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
183 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
184 case SEEK_END:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
185 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
186 struct stat sb;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
187 int error;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
188
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
189 error = zfs_stat(f, &sb);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
190 if (error != 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
191 errno = error;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
192 return (-1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
193 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
194 fp->f_seekp = sb.st_size - offset;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
195 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
196 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
197 default:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
198 errno = EINVAL;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
199 return (-1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
200 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
201 return (fp->f_seekp);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
202 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
203
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
204 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
205 zfs_stat(struct open_file *f, struct stat *sb)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
206 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
207 const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
208 struct file *fp = (struct file *)f->f_fsdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
209
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
210 return (zfs_dnode_stat(spa, &fp->f_dnode, sb));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
211 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
212
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
213 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
214 zfs_readdir(struct open_file *f, struct dirent *d)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
215 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
216 const spa_t *spa = ((struct zfsmount *)f->f_devdata)->spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
217 struct file *fp = (struct file *)f->f_fsdata;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
218 mzap_ent_phys_t mze;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
219 struct stat sb;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
220 size_t bsize = fp->f_dnode.dn_datablkszsec << SPA_MINBLOCKSHIFT;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
221 int rc;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
222
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
223 rc = zfs_stat(f, &sb);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
224 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
225 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
226 if (!S_ISDIR(sb.st_mode))
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
227 return (ENOTDIR);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
228
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
229 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
230 * If this is the first read, get the zap type.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
231 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
232 if (fp->f_seekp == 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
233 rc = dnode_read(spa, &fp->f_dnode,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
234 0, &fp->f_zap_type, sizeof(fp->f_zap_type));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
235 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
236 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
237
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
238 if (fp->f_zap_type == ZBT_MICRO) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
239 fp->f_seekp = offsetof(mzap_phys_t, mz_chunk);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
240 } else {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
241 rc = dnode_read(spa, &fp->f_dnode,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
242 offsetof(zap_phys_t, zap_num_leafs),
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
243 &fp->f_num_leafs,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
244 sizeof(fp->f_num_leafs));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
245 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
246 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
247
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
248 fp->f_seekp = bsize;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
249 fp->f_zap_leaf = (zap_leaf_phys_t *)malloc(bsize);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
250 rc = dnode_read(spa, &fp->f_dnode,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
251 fp->f_seekp,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
252 fp->f_zap_leaf,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
253 bsize);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
254 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
255 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
256 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
257 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
258
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
259 if (fp->f_zap_type == ZBT_MICRO) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
260 mzap_next:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
261 if (fp->f_seekp >= bsize)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
262 return (ENOENT);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
263
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
264 rc = dnode_read(spa, &fp->f_dnode,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
265 fp->f_seekp, &mze, sizeof(mze));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
266 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
267 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
268 fp->f_seekp += sizeof(mze);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
269
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
270 if (!mze.mze_name[0])
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
271 goto mzap_next;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
272
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
273 d->d_fileno = ZFS_DIRENT_OBJ(mze.mze_value);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
274 d->d_type = ZFS_DIRENT_TYPE(mze.mze_value);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
275 strcpy(d->d_name, mze.mze_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
276 d->d_namlen = strlen(d->d_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
277 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
278 } else {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
279 zap_leaf_t zl;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
280 zap_leaf_chunk_t *zc, *nc;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
281 int chunk;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
282 size_t namelen;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
283 char *p;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
284 uint64_t value;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
285
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
286 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
287 * Initialise this so we can use the ZAP size
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
288 * calculating macros.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
289 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
290 zl.l_bs = ilog2(bsize);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
291 zl.l_phys = fp->f_zap_leaf;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
292
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
293 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
294 * Figure out which chunk we are currently looking at
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
295 * and consider seeking to the next leaf. We use the
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
296 * low bits of f_seekp as a simple chunk index.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
297 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
298 fzap_next:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
299 chunk = fp->f_seekp & (bsize - 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
300 if (chunk == ZAP_LEAF_NUMCHUNKS(&zl)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
301 fp->f_seekp = (fp->f_seekp & ~(bsize - 1)) + bsize;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
302 chunk = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
303
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
304 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
305 * Check for EOF and read the new leaf.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
306 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
307 if (fp->f_seekp >= bsize * fp->f_num_leafs)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
308 return (ENOENT);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
309
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
310 rc = dnode_read(spa, &fp->f_dnode,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
311 fp->f_seekp,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
312 fp->f_zap_leaf,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
313 bsize);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
314 if (rc)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
315 return (rc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
316 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
317
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
318 zc = &ZAP_LEAF_CHUNK(&zl, chunk);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
319 fp->f_seekp++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
320 if (zc->l_entry.le_type != ZAP_CHUNK_ENTRY)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
321 goto fzap_next;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
322
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
323 namelen = zc->l_entry.le_name_numints;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
324 if (namelen > sizeof(d->d_name))
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
325 namelen = sizeof(d->d_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
326
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
327 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
328 * Paste the name back together.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
329 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
330 nc = &ZAP_LEAF_CHUNK(&zl, zc->l_entry.le_name_chunk);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
331 p = d->d_name;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
332 while (namelen > 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
333 int len;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
334 len = namelen;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
335 if (len > ZAP_LEAF_ARRAY_BYTES)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
336 len = ZAP_LEAF_ARRAY_BYTES;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
337 memcpy(p, nc->l_array.la_array, len);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
338 p += len;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
339 namelen -= len;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
340 nc = &ZAP_LEAF_CHUNK(&zl, nc->l_array.la_next);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
341 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
342 d->d_name[sizeof(d->d_name) - 1] = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
343
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
344 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
345 * Assume the first eight bytes of the value are
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
346 * a uint64_t.
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
347 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
348 value = fzap_leaf_value(&zl, zc);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
349
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
350 d->d_fileno = ZFS_DIRENT_OBJ(value);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
351 d->d_type = ZFS_DIRENT_TYPE(value);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
352 d->d_namlen = strlen(d->d_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
353
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
354 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
355 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
356 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
357
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
358 static int
18803
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
359 vdev_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t bytes)
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
360 {
18803
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
361 int fd, ret;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
362 size_t res, size, remainder, rb_size, blksz;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
363 unsigned secsz;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
364 off_t off;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
365 char *bouncebuf, *rb_buf;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
366
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
367 fd = (uintptr_t) priv;
18803
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
368 bouncebuf = NULL;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
369
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
370 ret = ioctl(fd, DIOCGSECTORSIZE, &secsz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
371 if (ret != 0)
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
372 return (ret);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
373
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
374 off = offset / secsz;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
375 remainder = offset % secsz;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
376 if (lseek(fd, off * secsz, SEEK_SET) == -1)
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
377 return (errno);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
378
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
379 rb_buf = buf;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
380 rb_size = bytes;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
381 size = roundup2(bytes + remainder, secsz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
382 blksz = size;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
383 if (remainder != 0 || size != bytes) {
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
384 bouncebuf = zfs_alloc(secsz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
385 if (bouncebuf == NULL) {
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
386 printf("vdev_read: out of memory\n");
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
387 return (ENOMEM);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
388 }
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
389 rb_buf = bouncebuf;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
390 blksz = rb_size - remainder;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
391 }
18803
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
392
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
393 while (bytes > 0) {
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
394 res = read(fd, rb_buf, rb_size);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
395 if (res != rb_size) {
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
396 ret = EIO;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
397 goto error;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
398 }
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
399 if (bytes < blksz)
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
400 blksz = bytes;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
401 if (bouncebuf != NULL)
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
402 memcpy(buf, rb_buf + remainder, blksz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
403 buf = (void *)((uintptr_t)buf + blksz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
404 bytes -= blksz;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
405 remainder = 0;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
406 blksz = rb_size;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
407 }
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
408
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
409 ret = 0;
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
410 error:
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
411 if (bouncebuf != NULL)
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
412 zfs_free(bouncebuf, secsz);
4cce1091b47b 8750 loader: vdev_read() needs to be careful about large sectors
Toomas Soome <tsoome@me.com>
parents: 18757
diff changeset
413 return (ret);
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
414 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
415
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
416 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
417 zfs_dev_init(void)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
418 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
419 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
420 spa_t *next;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
421 spa_t *prev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
422
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
423 zfs_init();
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
424 if (archsw.arch_zfs_probe == NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
425 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
426 archsw.arch_zfs_probe();
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
427
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
428 prev = NULL;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
429 spa = STAILQ_FIRST(&zfs_pools);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
430 while (spa != NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
431 next = STAILQ_NEXT(spa, spa_link);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
432 if (zfs_spa_init(spa)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
433 if (prev == NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
434 STAILQ_REMOVE_HEAD(&zfs_pools, spa_link);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
435 else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
436 STAILQ_REMOVE_AFTER(&zfs_pools, prev, spa_link);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
437 } else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
438 prev = spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
439 spa = next;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
440 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
441 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
442 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
443
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
444 struct zfs_probe_args {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
445 int fd;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
446 const char *devname;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
447 uint64_t *pool_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
448 u_int secsz;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
449 };
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
450
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
451 static int
17019
55ca9ddc9ca8 7641 loader: disk/part api needs to use uint64_t offsets
Toomas Soome <tsoome@me.com>
parents: 16956
diff changeset
452 zfs_diskread(void *arg, void *buf, size_t blocks, uint64_t offset)
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
453 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
454 struct zfs_probe_args *ppa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
455
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
456 ppa = (struct zfs_probe_args *)arg;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
457 return (vdev_read(NULL, (void *)(uintptr_t)ppa->fd,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
458 offset * ppa->secsz, buf, blocks * ppa->secsz));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
459 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
460
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
461 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
462 zfs_probe(int fd, uint64_t *pool_guid)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
463 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
464 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
465 int ret;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
466
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
467 ret = vdev_probe(vdev_read, (void *)(uintptr_t)fd, &spa);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
468 if (ret == 0 && pool_guid != NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
469 *pool_guid = spa->spa_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
470 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
471 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
472
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
473 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
474 zfs_probe_partition(void *arg, const char *partname,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
475 const struct ptable_entry *part)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
476 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
477 struct zfs_probe_args *ppa, pa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
478 struct ptable *table;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
479 char devname[32];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
480 int ret = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
481
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
482 /* filter out partitions *not* used by zfs */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
483 switch (part->type) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
484 case PART_RESERVED: /* efi reserverd */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
485 case PART_VTOC_BOOT: /* vtoc boot area */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
486 case PART_VTOC_SWAP:
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
487 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
488 default:
18814
9c034bba7722 loader: Solaris 2 partition may have no VTOC
Toomas Soome <tsoome@me.com>
parents: 18803
diff changeset
489 break;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
490 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
491 ppa = (struct zfs_probe_args *)arg;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
492 strncpy(devname, ppa->devname, strlen(ppa->devname) - 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
493 devname[strlen(ppa->devname) - 1] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
494 sprintf(devname, "%s%s:", devname, partname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
495 pa.fd = open(devname, O_RDONLY);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
496 if (pa.fd == -1)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
497 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
498 ret = zfs_probe(pa.fd, ppa->pool_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
499 if (ret == 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
500 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
501 if (part->type == PART_SOLARIS2) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
502 pa.devname = devname;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
503 pa.pool_guid = ppa->pool_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
504 pa.secsz = ppa->secsz;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
505 table = ptable_open(&pa, part->end - part->start + 1,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
506 ppa->secsz, zfs_diskread);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
507 if (table != NULL) {
18817
b74d8d540aba gptzfsboot and zfsloader can't find slices inside PTABLE_VTOC label after 9099
Toomas Soome <tsoome@me.com>
parents: 18814
diff changeset
508 enum ptable_type pt = ptable_gettype(table);
b74d8d540aba gptzfsboot and zfsloader can't find slices inside PTABLE_VTOC label after 9099
Toomas Soome <tsoome@me.com>
parents: 18814
diff changeset
509
b74d8d540aba gptzfsboot and zfsloader can't find slices inside PTABLE_VTOC label after 9099
Toomas Soome <tsoome@me.com>
parents: 18814
diff changeset
510 if (pt == PTABLE_VTOC8 || pt == PTABLE_VTOC)
18814
9c034bba7722 loader: Solaris 2 partition may have no VTOC
Toomas Soome <tsoome@me.com>
parents: 18803
diff changeset
511 ptable_iterate(table, &pa, zfs_probe_partition);
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
512 ptable_close(table);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
513 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
514 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
515 close(pa.fd);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
516 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
517 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
518
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
519 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
520 zfs_probe_dev(const char *devname, uint64_t *pool_guid)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
521 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
522 struct ptable *table;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
523 struct zfs_probe_args pa;
17694
7b8f0425acf1 7540 loader zfs should check all labels
Toomas Soome <tsoome@me.com>
parents: 17285
diff changeset
524 uint64_t mediasz;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
525 int ret;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
526
18757
a7d9e0e99825 8646 loader: replace EFI part devices.
Toomas Soome <tsoome@me.com>
parents: 17694
diff changeset
527 if (pool_guid)
a7d9e0e99825 8646 loader: replace EFI part devices.
Toomas Soome <tsoome@me.com>
parents: 17694
diff changeset
528 *pool_guid = 0;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
529 pa.fd = open(devname, O_RDONLY);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
530 if (pa.fd == -1)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
531 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
532 /* Probe the whole disk */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
533 ret = zfs_probe(pa.fd, pool_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
534 if (ret == 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
535 return (0);
18757
a7d9e0e99825 8646 loader: replace EFI part devices.
Toomas Soome <tsoome@me.com>
parents: 17694
diff changeset
536
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
537 /* Probe each partition */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
538 ret = ioctl(pa.fd, DIOCGMEDIASIZE, &mediasz);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
539 if (ret == 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
540 ret = ioctl(pa.fd, DIOCGSECTORSIZE, &pa.secsz);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
541 if (ret == 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
542 pa.devname = devname;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
543 pa.pool_guid = pool_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
544 table = ptable_open(&pa, mediasz / pa.secsz, pa.secsz,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
545 zfs_diskread);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
546 if (table != NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
547 ptable_iterate(table, &pa, zfs_probe_partition);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
548 ptable_close(table);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
549 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
550 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
551 close(pa.fd);
18757
a7d9e0e99825 8646 loader: replace EFI part devices.
Toomas Soome <tsoome@me.com>
parents: 17694
diff changeset
552 if (pool_guid && *pool_guid == 0)
a7d9e0e99825 8646 loader: replace EFI part devices.
Toomas Soome <tsoome@me.com>
parents: 17694
diff changeset
553 ret = ENXIO;
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
554 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
555 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
556
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
557 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
558 * Print information about ZFS pools
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
559 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
560 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
561 zfs_dev_print(int verbose)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
562 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
563 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
564 char line[80];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
565 int ret = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
566
16956
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
567 if (STAILQ_EMPTY(&zfs_pools))
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
568 return (0);
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
569
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
570 printf("%s devices:", zfs_dev.dv_name);
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
571 if ((ret = pager_output("\n")) != 0)
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
572 return (ret);
f222ff501f0a 7593 lsdev device name section headers should be printed by dv_print callback.
Toomas Soome <tsoome@me.com>
parents: 16020
diff changeset
573
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
574 if (verbose) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
575 return (spa_all_status());
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
576 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
577 STAILQ_FOREACH(spa, &zfs_pools, spa_link) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
578 sprintf(line, " zfs:%s\n", spa->spa_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
579 ret = pager_output(line);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
580 if (ret != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
581 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
582 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
583 return (ret);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
584 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
585
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
586 /*
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
587 * Attempt to open the pool described by (dev) for use by (f).
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
588 */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
589 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
590 zfs_dev_open(struct open_file *f, ...)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
591 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
592 va_list args;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
593 struct zfs_devdesc *dev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
594 struct zfsmount *mount;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
595 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
596 int rv;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
597
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
598 va_start(args, f);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
599 dev = va_arg(args, struct zfs_devdesc *);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
600 va_end(args);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
601
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
602 if (dev->pool_guid == 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
603 spa = STAILQ_FIRST(&zfs_pools);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
604 else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
605 spa = spa_find_by_guid(dev->pool_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
606 if (!spa)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
607 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
608 mount = malloc(sizeof(*mount));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
609 rv = zfs_mount(spa, dev->root_guid, mount);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
610 if (rv != 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
611 free(mount);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
612 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
613 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
614 if (mount->objset.os_type != DMU_OST_ZFS) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
615 printf("Unexpected object set type %ju\n",
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
616 (uintmax_t)mount->objset.os_type);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
617 free(mount);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
618 return (EIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
619 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
620 f->f_devdata = mount;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
621 free(dev);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
622 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
623 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
624
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
625 static int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
626 zfs_dev_close(struct open_file *f)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
627 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
628
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
629 free(f->f_devdata);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
630 f->f_devdata = NULL;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
631 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
632 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
633
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
634 static int
17057
ec0d87693f50 7618 loader: dosfs can corrupt memory
Toomas Soome <tsoome@me.com>
parents: 17019
diff changeset
635 zfs_dev_strategy(void *devdata, int rw, daddr_t dblk, size_t size,
ec0d87693f50 7618 loader: dosfs can corrupt memory
Toomas Soome <tsoome@me.com>
parents: 17019
diff changeset
636 char *buf, size_t *rsize)
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
637 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
638
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
639 return (ENOSYS);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
640 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
641
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
642 struct devsw zfs_dev = {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
643 .dv_name = "zfs",
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
644 .dv_type = DEVT_ZFS,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
645 .dv_init = zfs_dev_init,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
646 .dv_strategy = zfs_dev_strategy,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
647 .dv_open = zfs_dev_open,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
648 .dv_close = zfs_dev_close,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
649 .dv_ioctl = noioctl,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
650 .dv_print = zfs_dev_print,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
651 .dv_cleanup = NULL
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
652 };
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
653
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
654 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
655 zfs_parsedev(struct zfs_devdesc *dev, const char *devspec, const char **path)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
656 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
657 static char rootname[ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
658 static char poolname[ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
659 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
660 const char *end;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
661 const char *np;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
662 const char *sep;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
663 int rv;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
664
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
665 np = devspec;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
666 if (*np != ':')
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
667 return (EINVAL);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
668 np++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
669 end = strchr(np, ':');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
670 if (end == NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
671 return (EINVAL);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
672 sep = strchr(np, '/');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
673 if (sep == NULL || sep >= end)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
674 sep = end;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
675 memcpy(poolname, np, sep - np);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
676 poolname[sep - np] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
677 if (sep < end) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
678 sep++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
679 memcpy(rootname, sep, end - sep);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
680 rootname[end - sep] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
681 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
682 else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
683 rootname[0] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
684
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
685 spa = spa_find_by_name(poolname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
686 if (!spa)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
687 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
688 dev->pool_guid = spa->spa_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
689 rv = zfs_lookup_dataset(spa, rootname, &dev->root_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
690 if (rv != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
691 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
692 if (path != NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
693 *path = (*end == '\0') ? end : end + 1;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
694 dev->d_dev = &zfs_dev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
695 dev->d_type = zfs_dev.dv_type;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
696 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
697 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
698
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
699 char *
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
700 zfs_bootfs(void *zdev)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
701 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
702 static char rootname[ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
703 static char buf[2 * ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
704 struct zfs_devdesc *dev = (struct zfs_devdesc *)zdev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
705 uint64_t objnum;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
706 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
707 int n;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
708
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
709 buf[0] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
710 if (dev->d_type != DEVT_ZFS)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
711 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
712
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
713 spa = spa_find_by_guid(dev->pool_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
714 if (spa == NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
715 printf("ZFS: can't find pool by guid\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
716 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
717 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
718 if (zfs_rlookup(spa, dev->root_guid, rootname)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
719 printf("ZFS: can't find filesystem by guid\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
720 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
721 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
722 if (zfs_lookup_dataset(spa, rootname, &objnum)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
723 printf("ZFS: can't find filesystem by name\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
724 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
725 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
726
17285
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
727 /* Set the environment. */
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
728 snprintf(buf, sizeof (buf), "%s/%llu", spa->spa_name,
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
729 (unsigned long long)objnum);
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
730 setenv("zfs-bootfs", buf, 1);
18825
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
731 if (spa->spa_boot_vdev->v_phys_path != NULL)
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
732 setenv("bootpath", spa->spa_boot_vdev->v_phys_path, 1);
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
733 if (spa->spa_boot_vdev->v_devid != NULL)
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
734 setenv("diskdevid", spa->spa_boot_vdev->v_devid, 1);
17285
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
735
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
736 /*
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
737 * Build the command line string. Once our kernel will read
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
738 * the environment and we can stop caring about old kernels,
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
739 * we can remove this part.
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
740 */
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
741 snprintf(buf, sizeof(buf), "zfs-bootfs=%s/%llu", spa->spa_name,
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
742 (unsigned long long)objnum);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
743 n = strlen(buf);
18825
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
744 if (spa->spa_boot_vdev->v_phys_path != NULL) {
17285
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
745 snprintf(buf+n, sizeof (buf) - n, ",bootpath=\"%s\"",
18825
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
746 spa->spa_boot_vdev->v_phys_path);
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
747 n = strlen(buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
748 }
18825
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
749 if (spa->spa_boot_vdev->v_devid != NULL) {
17285
c73d5fa3958a 7792 loader: export zfs-bootfs related data into the environment
Toomas Soome <tsoome@me.com>
parents: 17243
diff changeset
750 snprintf(buf+n, sizeof (buf) - n, ",diskdevid=\"%s\"",
18825
2ed7ea649fe9 loader: zfs_bootfs() needs to use config pool txg for boot device
Toomas Soome <tsoome@me.com>
parents: 18820
diff changeset
751 spa->spa_boot_vdev->v_devid);
16020
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
752 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
753 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
754 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
755
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
756 char *
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
757 zfs_fmtdev(void *vdev)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
758 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
759 static char rootname[ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
760 static char buf[2 * ZFS_MAXNAMELEN + 8];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
761 struct zfs_devdesc *dev = (struct zfs_devdesc *)vdev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
762 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
763
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
764 buf[0] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
765 if (dev->d_type != DEVT_ZFS)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
766 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
767
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
768 if (dev->pool_guid == 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
769 spa = STAILQ_FIRST(&zfs_pools);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
770 dev->pool_guid = spa->spa_guid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
771 } else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
772 spa = spa_find_by_guid(dev->pool_guid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
773 if (spa == NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
774 printf("ZFS: can't find pool by guid\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
775 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
776 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
777 if (dev->root_guid == 0 && zfs_get_root(spa, &dev->root_guid)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
778 printf("ZFS: can't find root filesystem\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
779 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
780 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
781 if (zfs_rlookup(spa, dev->root_guid, rootname)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
782 printf("ZFS: can't find filesystem by guid\n");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
783 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
784 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
785
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
786 if (rootname[0] == '\0')
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
787 sprintf(buf, "%s:%s:", dev->d_dev->dv_name, spa->spa_name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
788 else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
789 sprintf(buf, "%s:%s/%s:", dev->d_dev->dv_name, spa->spa_name,
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
790 rootname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
791 return (buf);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
792 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
793
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
794 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
795 zfs_list(const char *name)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
796 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
797 static char poolname[ZFS_MAXNAMELEN];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
798 uint64_t objid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
799 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
800 const char *dsname;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
801 int len;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
802 int rv;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
803
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
804 len = strlen(name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
805 dsname = strchr(name, '/');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
806 if (dsname != NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
807 len = dsname - name;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
808 dsname++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
809 } else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
810 dsname = "";
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
811 memcpy(poolname, name, len);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
812 poolname[len] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
813
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
814 spa = spa_find_by_name(poolname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
815 if (!spa)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
816 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
817 rv = zfs_lookup_dataset(spa, dsname, &objid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
818 if (rv != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
819 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
820
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
821 return (zfs_list_dataset(spa, objid));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
822 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
823
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
824 #ifdef __FreeBSD__
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
825 void
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
826 init_zfs_bootenv(char *currdev)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
827 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
828 char *beroot;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
829
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
830 if (strlen(currdev) == 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
831 return;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
832 if(strncmp(currdev, "zfs:", 4) != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
833 return;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
834 /* Remove the trailing : */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
835 currdev[strlen(currdev) - 1] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
836 setenv("zfs_be_active", currdev, 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
837 setenv("zfs_be_currpage", "1", 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
838 /* Forward past zfs: */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
839 currdev = strchr(currdev, ':');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
840 currdev++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
841 /* Remove the last element (current bootenv) */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
842 beroot = strrchr(currdev, '/');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
843 if (beroot != NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
844 beroot[0] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
845 beroot = currdev;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
846 setenv("zfs_be_root", beroot, 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
847 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
848
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
849 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
850 zfs_bootenv(const char *name)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
851 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
852 static char poolname[ZFS_MAXNAMELEN], *dsname, *root;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
853 char becount[4];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
854 uint64_t objid;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
855 spa_t *spa;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
856 int len, rv, pages, perpage, currpage;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
857
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
858 if (name == NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
859 return (EINVAL);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
860 if ((root = getenv("zfs_be_root")) == NULL)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
861 return (EINVAL);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
862
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
863 if (strcmp(name, root) != 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
864 if (setenv("zfs_be_root", name, 1) != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
865 return (ENOMEM);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
866 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
867
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
868 SLIST_INIT(&zfs_be_head);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
869 zfs_env_count = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
870 len = strlen(name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
871 dsname = strchr(name, '/');
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
872 if (dsname != NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
873 len = dsname - name;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
874 dsname++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
875 } else
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
876 dsname = "";
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
877 memcpy(poolname, name, len);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
878 poolname[len] = '\0';
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
879
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
880 spa = spa_find_by_name(poolname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
881 if (!spa)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
882 return (ENXIO);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
883 rv = zfs_lookup_dataset(spa, dsname, &objid);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
884 if (rv != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
885 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
886 rv = zfs_callback_dataset(spa, objid, zfs_belist_add);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
887
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
888 /* Calculate and store the number of pages of BEs */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
889 perpage = (ZFS_BE_LAST - ZFS_BE_FIRST + 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
890 pages = (zfs_env_count / perpage) + ((zfs_env_count % perpage) > 0 ? 1 : 0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
891 snprintf(becount, 4, "%d", pages);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
892 if (setenv("zfs_be_pages", becount, 1) != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
893 return (ENOMEM);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
894
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
895 /* Roll over the page counter if it has exceeded the maximum */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
896 currpage = strtol(getenv("zfs_be_currpage"), NULL, 10);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
897 if (currpage > pages) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
898 if (setenv("zfs_be_currpage", "1", 1) != 0)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
899 return (ENOMEM);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
900 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
901
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
902 /* Populate the menu environment variables */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
903 zfs_set_env();
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
904
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
905 /* Clean up the SLIST of ZFS BEs */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
906 while (!SLIST_EMPTY(&zfs_be_head)) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
907 zfs_be = SLIST_FIRST(&zfs_be_head);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
908 SLIST_REMOVE_HEAD(&zfs_be_head, entries);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
909 free(zfs_be);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
910 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
911
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
912 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
913 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
914
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
915 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
916 zfs_belist_add(const char *name, uint64_t value __unused)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
917 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
918
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
919 /* Skip special datasets that start with a $ character */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
920 if (strncmp(name, "$", 1) == 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
921 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
922 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
923 /* Add the boot environment to the head of the SLIST */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
924 zfs_be = malloc(sizeof(struct zfs_be_entry));
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
925 if (zfs_be == NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
926 return (ENOMEM);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
927 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
928 zfs_be->name = name;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
929 SLIST_INSERT_HEAD(&zfs_be_head, zfs_be, entries);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
930 zfs_env_count++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
931
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
932 return (0);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
933 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
934
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
935 int
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
936 zfs_set_env(void)
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
937 {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
938 char envname[32], envval[256];
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
939 char *beroot, *pagenum;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
940 int rv, page, ctr;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
941
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
942 beroot = getenv("zfs_be_root");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
943 if (beroot == NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
944 return (1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
945 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
946
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
947 pagenum = getenv("zfs_be_currpage");
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
948 if (pagenum != NULL) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
949 page = strtol(pagenum, NULL, 10);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
950 } else {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
951 page = 1;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
952 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
953
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
954 ctr = 1;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
955 rv = 0;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
956 zfs_env_index = ZFS_BE_FIRST;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
957 SLIST_FOREACH_SAFE(zfs_be, &zfs_be_head, entries, zfs_be_tmp) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
958 /* Skip to the requested page number */
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
959 if (ctr <= ((ZFS_BE_LAST - ZFS_BE_FIRST + 1) * (page - 1))) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
960 ctr++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
961 continue;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
962 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
963
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
964 snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
965 snprintf(envval, sizeof(envval), "%s", zfs_be->name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
966 rv = setenv(envname, envval, 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
967 if (rv != 0) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
968 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
969 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
970
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
971 snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
972 rv = setenv(envname, envval, 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
973 if (rv != 0){
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
974 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
975 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
976
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
977 snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
978 rv = setenv(envname, "set_bootenv", 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
979 if (rv != 0){
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
980 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
981 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
982
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
983 snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
984 snprintf(envval, sizeof(envval), "zfs:%s/%s", beroot, zfs_be->name);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
985 rv = setenv(envname, envval, 1);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
986 if (rv != 0){
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
987 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
988 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
989
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
990 zfs_env_index++;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
991 if (zfs_env_index > ZFS_BE_LAST) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
992 break;
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
993 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
994
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
995 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
996
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
997 for (; zfs_env_index <= ZFS_BE_LAST; zfs_env_index++) {
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
998 snprintf(envname, sizeof(envname), "bootenvmenu_caption[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
999 (void)unsetenv(envname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1000 snprintf(envname, sizeof(envname), "bootenvansi_caption[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1001 (void)unsetenv(envname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1002 snprintf(envname, sizeof(envname), "bootenvmenu_command[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1003 (void)unsetenv(envname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1004 snprintf(envname, sizeof(envname), "bootenv_root[%d]", zfs_env_index);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1005 (void)unsetenv(envname);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1006 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1007
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1008 return (rv);
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1009 }
eb24e6b255db loader: import and port freebsd loader
Toomas Soome <tsoome@me.com>
parents:
diff changeset
1010 #endif