Mercurial > unleashed > prev-conversion
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 |
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 |