Mercurial > illumos > illumos-gate
annotate usr/src/uts/common/fs/zfs/zfs_ioctl.c @ 7046:361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
6343693 'zpool status' gives delayed start for 'zpool scrub'
6670746 scrub on degraded pool return the status of 'resilver completed'?
6675685 DTL entries are lost resulting in checksum errors
6706404 get_history_one() can dereference off end of hist_event_table[]
6715414 assertion failed: ds->ds_owner != tag in dsl_dataset_rele()
6716437 ztest gets SEGV in arc_released()
6722838 bfu does not update grub
author | ahrens |
---|---|
date | Mon, 07 Jul 2008 13:39:21 -0700 |
parents | 46fc4b6db23e |
children | 9508660f9c27 |
rev | line source |
---|---|
789 | 1 /* |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
1485 | 5 * Common Development and Distribution License (the "License"). |
6 * You may not use this file except in compliance with the License. | |
789 | 7 * |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
10 * See the License for the specific language governing permissions | |
11 * and limitations under the License. | |
12 * | |
13 * When distributing Covered Code, include this CDDL HEADER in each | |
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 * If applicable, add the following below this CDDL HEADER, with the | |
16 * fields enclosed by brackets "[]" replaced with your own identifying | |
17 * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
21 /* | |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
789 | 23 * Use is subject to license terms. |
24 */ | |
25 | |
26 #pragma ident "%Z%%M% %I% %E% SMI" | |
27 | |
28 #include <sys/types.h> | |
29 #include <sys/param.h> | |
30 #include <sys/errno.h> | |
31 #include <sys/uio.h> | |
32 #include <sys/buf.h> | |
33 #include <sys/modctl.h> | |
34 #include <sys/open.h> | |
35 #include <sys/file.h> | |
36 #include <sys/kmem.h> | |
37 #include <sys/conf.h> | |
38 #include <sys/cmn_err.h> | |
39 #include <sys/stat.h> | |
40 #include <sys/zfs_ioctl.h> | |
5331 | 41 #include <sys/zfs_znode.h> |
789 | 42 #include <sys/zap.h> |
43 #include <sys/spa.h> | |
3912 | 44 #include <sys/spa_impl.h> |
789 | 45 #include <sys/vdev.h> |
3912 | 46 #include <sys/vdev_impl.h> |
789 | 47 #include <sys/dmu.h> |
48 #include <sys/dsl_dir.h> | |
49 #include <sys/dsl_dataset.h> | |
50 #include <sys/dsl_prop.h> | |
4543 | 51 #include <sys/dsl_deleg.h> |
52 #include <sys/dmu_objset.h> | |
789 | 53 #include <sys/ddi.h> |
54 #include <sys/sunddi.h> | |
55 #include <sys/sunldi.h> | |
56 #include <sys/policy.h> | |
57 #include <sys/zone.h> | |
58 #include <sys/nvpair.h> | |
59 #include <sys/pathname.h> | |
60 #include <sys/mount.h> | |
61 #include <sys/sdt.h> | |
62 #include <sys/fs/zfs.h> | |
63 #include <sys/zfs_ctldir.h> | |
5331 | 64 #include <sys/zfs_dir.h> |
2885 | 65 #include <sys/zvol.h> |
4543 | 66 #include <sharefs/share.h> |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
67 #include <sys/dmu_objset.h> |
789 | 68 |
69 #include "zfs_namecheck.h" | |
2676 | 70 #include "zfs_prop.h" |
4543 | 71 #include "zfs_deleg.h" |
789 | 72 |
73 extern struct modlfs zfs_modlfs; | |
74 | |
75 extern void zfs_init(void); | |
76 extern void zfs_fini(void); | |
77 | |
78 ldi_ident_t zfs_li = NULL; | |
79 dev_info_t *zfs_dip; | |
80 | |
81 typedef int zfs_ioc_func_t(zfs_cmd_t *); | |
4543 | 82 typedef int zfs_secpolicy_func_t(zfs_cmd_t *, cred_t *); |
789 | 83 |
84 typedef struct zfs_ioc_vec { | |
85 zfs_ioc_func_t *zvec_func; | |
86 zfs_secpolicy_func_t *zvec_secpolicy; | |
87 enum { | |
4577 | 88 NO_NAME, |
89 POOL_NAME, | |
90 DATASET_NAME | |
4543 | 91 } zvec_namecheck; |
92 boolean_t zvec_his_log; | |
789 | 93 } zfs_ioc_vec_t; |
94 | |
95 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */ | |
96 void | |
97 __dprintf(const char *file, const char *func, int line, const char *fmt, ...) | |
98 { | |
99 const char *newfile; | |
100 char buf[256]; | |
101 va_list adx; | |
102 | |
103 /* | |
104 * Get rid of annoying "../common/" prefix to filename. | |
105 */ | |
106 newfile = strrchr(file, '/'); | |
107 if (newfile != NULL) { | |
108 newfile = newfile + 1; /* Get rid of leading / */ | |
109 } else { | |
110 newfile = file; | |
111 } | |
112 | |
113 va_start(adx, fmt); | |
114 (void) vsnprintf(buf, sizeof (buf), fmt, adx); | |
115 va_end(adx); | |
116 | |
117 /* | |
118 * To get this data, use the zfs-dprintf probe as so: | |
119 * dtrace -q -n 'zfs-dprintf \ | |
120 * /stringof(arg0) == "dbuf.c"/ \ | |
121 * {printf("%s: %s", stringof(arg1), stringof(arg3))}' | |
122 * arg0 = file name | |
123 * arg1 = function name | |
124 * arg2 = line number | |
125 * arg3 = message | |
126 */ | |
127 DTRACE_PROBE4(zfs__dprintf, | |
128 char *, newfile, char *, func, int, line, char *, buf); | |
129 } | |
130 | |
4543 | 131 static void |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
132 history_str_free(char *buf) |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
133 { |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
134 kmem_free(buf, HIS_MAX_RECORD_LEN); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
135 } |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
136 |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
137 static char * |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
138 history_str_get(zfs_cmd_t *zc) |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
139 { |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
140 char *buf; |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
141 |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
142 if (zc->zc_history == NULL) |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
143 return (NULL); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
144 |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
145 buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
146 if (copyinstr((void *)(uintptr_t)zc->zc_history, |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
147 buf, HIS_MAX_RECORD_LEN, NULL) != 0) { |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
148 history_str_free(buf); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
149 return (NULL); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
150 } |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
151 |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
152 buf[HIS_MAX_RECORD_LEN -1] = '\0'; |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
153 |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
154 return (buf); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
155 } |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
156 |
5375 | 157 /* |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
158 * Check to see if the named dataset is currently defined as bootable |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
159 */ |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
160 static boolean_t |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
161 zfs_is_bootfs(const char *name) |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
162 { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
163 spa_t *spa; |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
164 boolean_t ret = B_FALSE; |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
165 |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
166 if (spa_open(name, &spa, FTAG) == 0) { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
167 if (spa->spa_bootfs) { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
168 objset_t *os; |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
169 |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
170 if (dmu_objset_open(name, DMU_OST_ZFS, |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
171 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
172 ret = (dmu_objset_id(os) == spa->spa_bootfs); |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
173 dmu_objset_close(os); |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
174 } |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
175 } |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
176 spa_close(spa, FTAG); |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
177 } |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
178 return (ret); |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
179 } |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
180 |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
181 /* |
5375 | 182 * zfs_check_version |
183 * | |
184 * Return non-zero if the spa version is less than requested version. | |
185 */ | |
5331 | 186 static int |
187 zfs_check_version(const char *name, int version) | |
188 { | |
189 | |
190 spa_t *spa; | |
191 | |
192 if (spa_open(name, &spa, FTAG) == 0) { | |
193 if (spa_version(spa) < version) { | |
194 spa_close(spa, FTAG); | |
195 return (1); | |
196 } | |
197 spa_close(spa, FTAG); | |
198 } | |
199 return (0); | |
200 } | |
201 | |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
202 /* |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
203 * zpl_earlier_version |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
204 * |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
205 * Return TRUE if the ZPL version is less than requested version. |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
206 */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
207 static boolean_t |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
208 zpl_earlier_version(const char *name, int version) |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
209 { |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
210 objset_t *os; |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
211 boolean_t rc = B_TRUE; |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
212 |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
213 if (dmu_objset_open(name, DMU_OST_ANY, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
214 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
215 uint64_t zplversion; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
216 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
217 if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
218 rc = zplversion < version; |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
219 dmu_objset_close(os); |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
220 } |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
221 return (rc); |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
222 } |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
223 |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
224 static void |
4543 | 225 zfs_log_history(zfs_cmd_t *zc) |
226 { | |
227 spa_t *spa; | |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
228 char *buf; |
4543 | 229 |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
230 if ((buf = history_str_get(zc)) == NULL) |
4577 | 231 return; |
232 | |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
233 if (spa_open(zc->zc_name, &spa, FTAG) == 0) { |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
234 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY) |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
235 (void) spa_history_log(spa, buf, LOG_CMD_NORMAL); |
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
236 spa_close(spa, FTAG); |
4543 | 237 } |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
238 history_str_free(buf); |
4543 | 239 } |
240 | |
789 | 241 /* |
242 * Policy for top-level read operations (list pools). Requires no privileges, | |
243 * and can be used in the local zone, as there is no associated dataset. | |
244 */ | |
245 /* ARGSUSED */ | |
246 static int | |
4543 | 247 zfs_secpolicy_none(zfs_cmd_t *zc, cred_t *cr) |
789 | 248 { |
249 return (0); | |
250 } | |
251 | |
252 /* | |
253 * Policy for dataset read operations (list children, get statistics). Requires | |
254 * no privileges, but must be visible in the local zone. | |
255 */ | |
256 /* ARGSUSED */ | |
257 static int | |
4543 | 258 zfs_secpolicy_read(zfs_cmd_t *zc, cred_t *cr) |
789 | 259 { |
260 if (INGLOBALZONE(curproc) || | |
4543 | 261 zone_dataset_visible(zc->zc_name, NULL)) |
789 | 262 return (0); |
263 | |
264 return (ENOENT); | |
265 } | |
266 | |
267 static int | |
268 zfs_dozonecheck(const char *dataset, cred_t *cr) | |
269 { | |
270 uint64_t zoned; | |
271 int writable = 1; | |
272 | |
273 /* | |
274 * The dataset must be visible by this zone -- check this first | |
275 * so they don't see EPERM on something they shouldn't know about. | |
276 */ | |
277 if (!INGLOBALZONE(curproc) && | |
278 !zone_dataset_visible(dataset, &writable)) | |
279 return (ENOENT); | |
280 | |
281 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL)) | |
282 return (ENOENT); | |
283 | |
284 if (INGLOBALZONE(curproc)) { | |
285 /* | |
286 * If the fs is zoned, only root can access it from the | |
287 * global zone. | |
288 */ | |
289 if (secpolicy_zfs(cr) && zoned) | |
290 return (EPERM); | |
291 } else { | |
292 /* | |
293 * If we are in a local zone, the 'zoned' property must be set. | |
294 */ | |
295 if (!zoned) | |
296 return (EPERM); | |
297 | |
298 /* must be writable by this zone */ | |
299 if (!writable) | |
300 return (EPERM); | |
301 } | |
302 return (0); | |
303 } | |
304 | |
305 int | |
4543 | 306 zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr) |
789 | 307 { |
308 int error; | |
309 | |
4543 | 310 error = zfs_dozonecheck(name, cr); |
311 if (error == 0) { | |
312 error = secpolicy_zfs(cr); | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
313 if (error) |
4543 | 314 error = dsl_deleg_access(name, perm, cr); |
315 } | |
316 return (error); | |
317 } | |
318 | |
319 static int | |
320 zfs_secpolicy_setprop(const char *name, zfs_prop_t prop, cred_t *cr) | |
321 { | |
322 /* | |
323 * Check permissions for special properties. | |
324 */ | |
325 switch (prop) { | |
326 case ZFS_PROP_ZONED: | |
327 /* | |
328 * Disallow setting of 'zoned' from within a local zone. | |
329 */ | |
330 if (!INGLOBALZONE(curproc)) | |
331 return (EPERM); | |
332 break; | |
789 | 333 |
4543 | 334 case ZFS_PROP_QUOTA: |
335 if (!INGLOBALZONE(curproc)) { | |
336 uint64_t zoned; | |
337 char setpoint[MAXNAMELEN]; | |
338 /* | |
339 * Unprivileged users are allowed to modify the | |
340 * quota on things *under* (ie. contained by) | |
341 * the thing they own. | |
342 */ | |
343 if (dsl_prop_get_integer(name, "zoned", &zoned, | |
344 setpoint)) | |
345 return (EPERM); | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
346 if (!zoned || strlen(name) <= strlen(setpoint)) |
4543 | 347 return (EPERM); |
348 } | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
349 break; |
4543 | 350 } |
351 | |
4787 | 352 return (zfs_secpolicy_write_perms(name, zfs_prop_to_name(prop), cr)); |
789 | 353 } |
354 | |
4543 | 355 int |
356 zfs_secpolicy_fsacl(zfs_cmd_t *zc, cred_t *cr) | |
357 { | |
358 int error; | |
359 | |
360 error = zfs_dozonecheck(zc->zc_name, cr); | |
361 if (error) | |
362 return (error); | |
363 | |
364 /* | |
365 * permission to set permissions will be evaluated later in | |
366 * dsl_deleg_can_allow() | |
367 */ | |
368 return (0); | |
369 } | |
370 | |
371 int | |
372 zfs_secpolicy_rollback(zfs_cmd_t *zc, cred_t *cr) | |
373 { | |
374 int error; | |
375 error = zfs_secpolicy_write_perms(zc->zc_name, | |
376 ZFS_DELEG_PERM_ROLLBACK, cr); | |
377 if (error == 0) | |
378 error = zfs_secpolicy_write_perms(zc->zc_name, | |
379 ZFS_DELEG_PERM_MOUNT, cr); | |
380 return (error); | |
381 } | |
382 | |
383 int | |
384 zfs_secpolicy_send(zfs_cmd_t *zc, cred_t *cr) | |
385 { | |
386 return (zfs_secpolicy_write_perms(zc->zc_name, | |
387 ZFS_DELEG_PERM_SEND, cr)); | |
388 } | |
389 | |
390 int | |
391 zfs_secpolicy_share(zfs_cmd_t *zc, cred_t *cr) | |
392 { | |
393 if (!INGLOBALZONE(curproc)) | |
394 return (EPERM); | |
395 | |
5367 | 396 if (secpolicy_nfs(cr) == 0) { |
4543 | 397 return (0); |
398 } else { | |
399 vnode_t *vp; | |
400 int error; | |
401 | |
402 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE, | |
403 NO_FOLLOW, NULL, &vp)) != 0) | |
404 return (error); | |
405 | |
406 /* Now make sure mntpnt and dataset are ZFS */ | |
407 | |
408 if (vp->v_vfsp->vfs_fstype != zfsfstype || | |
409 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource), | |
410 zc->zc_name) != 0)) { | |
411 VN_RELE(vp); | |
412 return (EPERM); | |
413 } | |
414 | |
415 VN_RELE(vp); | |
416 return (dsl_deleg_access(zc->zc_name, | |
417 ZFS_DELEG_PERM_SHARE, cr)); | |
418 } | |
419 } | |
420 | |
789 | 421 static int |
4543 | 422 zfs_get_parent(const char *datasetname, char *parent, int parentsize) |
789 | 423 { |
424 char *cp; | |
425 | |
426 /* | |
427 * Remove the @bla or /bla from the end of the name to get the parent. | |
428 */ | |
4543 | 429 (void) strncpy(parent, datasetname, parentsize); |
430 cp = strrchr(parent, '@'); | |
789 | 431 if (cp != NULL) { |
432 cp[0] = '\0'; | |
433 } else { | |
4543 | 434 cp = strrchr(parent, '/'); |
789 | 435 if (cp == NULL) |
436 return (ENOENT); | |
437 cp[0] = '\0'; | |
438 } | |
439 | |
4543 | 440 return (0); |
441 } | |
442 | |
443 int | |
444 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr) | |
445 { | |
446 int error; | |
447 | |
448 if ((error = zfs_secpolicy_write_perms(name, | |
449 ZFS_DELEG_PERM_MOUNT, cr)) != 0) | |
450 return (error); | |
451 | |
452 return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr)); | |
453 } | |
454 | |
455 static int | |
456 zfs_secpolicy_destroy(zfs_cmd_t *zc, cred_t *cr) | |
457 { | |
458 return (zfs_secpolicy_destroy_perms(zc->zc_name, cr)); | |
459 } | |
460 | |
461 /* | |
462 * Must have sys_config privilege to check the iscsi permission | |
463 */ | |
464 /* ARGSUSED */ | |
465 static int | |
466 zfs_secpolicy_iscsi(zfs_cmd_t *zc, cred_t *cr) | |
467 { | |
468 return (secpolicy_zfs(cr)); | |
469 } | |
470 | |
471 int | |
472 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr) | |
473 { | |
474 char parentname[MAXNAMELEN]; | |
475 int error; | |
476 | |
477 if ((error = zfs_secpolicy_write_perms(from, | |
478 ZFS_DELEG_PERM_RENAME, cr)) != 0) | |
479 return (error); | |
480 | |
481 if ((error = zfs_secpolicy_write_perms(from, | |
482 ZFS_DELEG_PERM_MOUNT, cr)) != 0) | |
483 return (error); | |
484 | |
485 if ((error = zfs_get_parent(to, parentname, | |
486 sizeof (parentname))) != 0) | |
487 return (error); | |
488 | |
489 if ((error = zfs_secpolicy_write_perms(parentname, | |
490 ZFS_DELEG_PERM_CREATE, cr)) != 0) | |
491 return (error); | |
492 | |
493 if ((error = zfs_secpolicy_write_perms(parentname, | |
494 ZFS_DELEG_PERM_MOUNT, cr)) != 0) | |
495 return (error); | |
496 | |
497 return (error); | |
498 } | |
499 | |
500 static int | |
501 zfs_secpolicy_rename(zfs_cmd_t *zc, cred_t *cr) | |
502 { | |
503 return (zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr)); | |
504 } | |
505 | |
506 static int | |
507 zfs_secpolicy_promote(zfs_cmd_t *zc, cred_t *cr) | |
508 { | |
509 char parentname[MAXNAMELEN]; | |
510 objset_t *clone; | |
511 int error; | |
512 | |
513 error = zfs_secpolicy_write_perms(zc->zc_name, | |
514 ZFS_DELEG_PERM_PROMOTE, cr); | |
515 if (error) | |
516 return (error); | |
517 | |
518 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
519 DS_MODE_USER | DS_MODE_READONLY, &clone); |
4543 | 520 |
521 if (error == 0) { | |
522 dsl_dataset_t *pclone = NULL; | |
523 dsl_dir_t *dd; | |
524 dd = clone->os->os_dsl_dataset->ds_dir; | |
525 | |
526 rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
527 error = dsl_dataset_hold_obj(dd->dd_pool, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
528 dd->dd_phys->dd_origin_obj, FTAG, &pclone); |
4543 | 529 rw_exit(&dd->dd_pool->dp_config_rwlock); |
530 if (error) { | |
531 dmu_objset_close(clone); | |
532 return (error); | |
533 } | |
534 | |
535 error = zfs_secpolicy_write_perms(zc->zc_name, | |
536 ZFS_DELEG_PERM_MOUNT, cr); | |
537 | |
538 dsl_dataset_name(pclone, parentname); | |
539 dmu_objset_close(clone); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
540 dsl_dataset_rele(pclone, FTAG); |
4543 | 541 if (error == 0) |
542 error = zfs_secpolicy_write_perms(parentname, | |
543 ZFS_DELEG_PERM_PROMOTE, cr); | |
544 } | |
545 return (error); | |
546 } | |
547 | |
548 static int | |
549 zfs_secpolicy_receive(zfs_cmd_t *zc, cred_t *cr) | |
550 { | |
551 int error; | |
552 | |
553 if ((error = zfs_secpolicy_write_perms(zc->zc_name, | |
554 ZFS_DELEG_PERM_RECEIVE, cr)) != 0) | |
555 return (error); | |
556 | |
557 if ((error = zfs_secpolicy_write_perms(zc->zc_name, | |
558 ZFS_DELEG_PERM_MOUNT, cr)) != 0) | |
559 return (error); | |
560 | |
561 return (zfs_secpolicy_write_perms(zc->zc_name, | |
562 ZFS_DELEG_PERM_CREATE, cr)); | |
563 } | |
564 | |
565 int | |
566 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr) | |
567 { | |
568 int error; | |
569 | |
570 if ((error = zfs_secpolicy_write_perms(name, | |
571 ZFS_DELEG_PERM_SNAPSHOT, cr)) != 0) | |
572 return (error); | |
573 | |
574 error = zfs_secpolicy_write_perms(name, | |
575 ZFS_DELEG_PERM_MOUNT, cr); | |
576 | |
577 return (error); | |
578 } | |
579 | |
580 static int | |
581 zfs_secpolicy_snapshot(zfs_cmd_t *zc, cred_t *cr) | |
582 { | |
583 | |
584 return (zfs_secpolicy_snapshot_perms(zc->zc_name, cr)); | |
585 } | |
586 | |
587 static int | |
588 zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr) | |
589 { | |
590 char parentname[MAXNAMELEN]; | |
591 int error; | |
592 | |
593 if ((error = zfs_get_parent(zc->zc_name, parentname, | |
594 sizeof (parentname))) != 0) | |
595 return (error); | |
596 | |
597 if (zc->zc_value[0] != '\0') { | |
598 if ((error = zfs_secpolicy_write_perms(zc->zc_value, | |
599 ZFS_DELEG_PERM_CLONE, cr)) != 0) | |
600 return (error); | |
601 } | |
602 | |
603 if ((error = zfs_secpolicy_write_perms(parentname, | |
604 ZFS_DELEG_PERM_CREATE, cr)) != 0) | |
605 return (error); | |
606 | |
607 error = zfs_secpolicy_write_perms(parentname, | |
608 ZFS_DELEG_PERM_MOUNT, cr); | |
609 | |
610 return (error); | |
611 } | |
612 | |
613 static int | |
614 zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr) | |
615 { | |
616 int error; | |
617 | |
618 error = secpolicy_fs_unmount(cr, NULL); | |
619 if (error) { | |
620 error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr); | |
621 } | |
622 return (error); | |
789 | 623 } |
624 | |
625 /* | |
626 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires | |
627 * SYS_CONFIG privilege, which is not available in a local zone. | |
628 */ | |
629 /* ARGSUSED */ | |
630 static int | |
4543 | 631 zfs_secpolicy_config(zfs_cmd_t *zc, cred_t *cr) |
789 | 632 { |
633 if (secpolicy_sys_config(cr, B_FALSE) != 0) | |
634 return (EPERM); | |
635 | |
636 return (0); | |
637 } | |
638 | |
639 /* | |
4543 | 640 * Just like zfs_secpolicy_config, except that we will check for |
641 * mount permission on the dataset for permission to create/remove | |
642 * the minor nodes. | |
643 */ | |
644 static int | |
645 zfs_secpolicy_minor(zfs_cmd_t *zc, cred_t *cr) | |
646 { | |
647 if (secpolicy_sys_config(cr, B_FALSE) != 0) { | |
648 return (dsl_deleg_access(zc->zc_name, | |
649 ZFS_DELEG_PERM_MOUNT, cr)); | |
650 } | |
651 | |
652 return (0); | |
653 } | |
654 | |
655 /* | |
1544 | 656 * Policy for fault injection. Requires all privileges. |
657 */ | |
658 /* ARGSUSED */ | |
659 static int | |
4543 | 660 zfs_secpolicy_inject(zfs_cmd_t *zc, cred_t *cr) |
1544 | 661 { |
662 return (secpolicy_zinject(cr)); | |
663 } | |
664 | |
4849
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
665 static int |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
666 zfs_secpolicy_inherit(zfs_cmd_t *zc, cred_t *cr) |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
667 { |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
668 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
669 |
5094 | 670 if (prop == ZPROP_INVAL) { |
4849
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
671 if (!zfs_prop_user(zc->zc_value)) |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
672 return (EINVAL); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
673 return (zfs_secpolicy_write_perms(zc->zc_name, |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
674 ZFS_DELEG_PERM_USERPROP, cr)); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
675 } else { |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
676 if (!zfs_prop_inheritable(prop)) |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
677 return (EINVAL); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
678 return (zfs_secpolicy_setprop(zc->zc_name, prop, cr)); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
679 } |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
680 } |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
681 |
1544 | 682 /* |
789 | 683 * Returns the nvlist as specified by the user in the zfs_cmd_t. |
684 */ | |
685 static int | |
5094 | 686 get_nvlist(uint64_t nvl, uint64_t size, nvlist_t **nvp) |
789 | 687 { |
688 char *packed; | |
689 int error; | |
5094 | 690 nvlist_t *list = NULL; |
789 | 691 |
692 /* | |
2676 | 693 * Read in and unpack the user-supplied nvlist. |
789 | 694 */ |
5094 | 695 if (size == 0) |
789 | 696 return (EINVAL); |
697 | |
698 packed = kmem_alloc(size, KM_SLEEP); | |
699 | |
5094 | 700 if ((error = xcopyin((void *)(uintptr_t)nvl, packed, size)) != 0) { |
789 | 701 kmem_free(packed, size); |
702 return (error); | |
703 } | |
704 | |
5094 | 705 if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) { |
789 | 706 kmem_free(packed, size); |
707 return (error); | |
708 } | |
709 | |
710 kmem_free(packed, size); | |
711 | |
5094 | 712 *nvp = list; |
789 | 713 return (0); |
714 } | |
715 | |
716 static int | |
2676 | 717 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl) |
718 { | |
719 char *packed = NULL; | |
720 size_t size; | |
721 int error; | |
722 | |
723 VERIFY(nvlist_size(nvl, &size, NV_ENCODE_NATIVE) == 0); | |
724 | |
725 if (size > zc->zc_nvlist_dst_size) { | |
726 error = ENOMEM; | |
727 } else { | |
4611 | 728 packed = kmem_alloc(size, KM_SLEEP); |
2676 | 729 VERIFY(nvlist_pack(nvl, &packed, &size, NV_ENCODE_NATIVE, |
730 KM_SLEEP) == 0); | |
731 error = xcopyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst, | |
732 size); | |
733 kmem_free(packed, size); | |
734 } | |
735 | |
736 zc->zc_nvlist_dst_size = size; | |
737 return (error); | |
738 } | |
739 | |
740 static int | |
789 | 741 zfs_ioc_pool_create(zfs_cmd_t *zc) |
742 { | |
743 int error; | |
5094 | 744 nvlist_t *config, *props = NULL; |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
745 char *buf; |
789 | 746 |
5094 | 747 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, |
748 &config)) | |
4988
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
749 return (error); |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
750 |
5094 | 751 if (zc->zc_nvlist_src_size != 0 && (error = |
752 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, &props))) { | |
753 nvlist_free(config); | |
754 return (error); | |
755 } | |
756 | |
4988
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
757 buf = history_str_get(zc); |
789 | 758 |
5094 | 759 error = spa_create(zc->zc_name, config, props, buf); |
789 | 760 |
4988
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
761 if (buf != NULL) |
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
762 history_str_free(buf); |
5094 | 763 |
789 | 764 nvlist_free(config); |
765 | |
5094 | 766 if (props) |
767 nvlist_free(props); | |
768 | |
789 | 769 return (error); |
770 } | |
771 | |
772 static int | |
773 zfs_ioc_pool_destroy(zfs_cmd_t *zc) | |
774 { | |
4543 | 775 int error; |
776 zfs_log_history(zc); | |
777 error = spa_destroy(zc->zc_name); | |
778 return (error); | |
789 | 779 } |
780 | |
781 static int | |
782 zfs_ioc_pool_import(zfs_cmd_t *zc) | |
783 { | |
784 int error; | |
5094 | 785 nvlist_t *config, *props = NULL; |
789 | 786 uint64_t guid; |
787 | |
5094 | 788 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, |
789 &config)) != 0) | |
789 | 790 return (error); |
791 | |
5094 | 792 if (zc->zc_nvlist_src_size != 0 && (error = |
793 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, &props))) { | |
794 nvlist_free(config); | |
795 return (error); | |
796 } | |
797 | |
789 | 798 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 || |
1544 | 799 guid != zc->zc_guid) |
789 | 800 error = EINVAL; |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6492
diff
changeset
|
801 else if (zc->zc_cookie) |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6492
diff
changeset
|
802 error = spa_import_faulted(zc->zc_name, config, |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6492
diff
changeset
|
803 props); |
789 | 804 else |
5094 | 805 error = spa_import(zc->zc_name, config, props); |
789 | 806 |
807 nvlist_free(config); | |
808 | |
5094 | 809 if (props) |
810 nvlist_free(props); | |
811 | |
789 | 812 return (error); |
813 } | |
814 | |
815 static int | |
816 zfs_ioc_pool_export(zfs_cmd_t *zc) | |
817 { | |
4543 | 818 int error; |
819 zfs_log_history(zc); | |
820 error = spa_export(zc->zc_name, NULL); | |
821 return (error); | |
789 | 822 } |
823 | |
824 static int | |
825 zfs_ioc_pool_configs(zfs_cmd_t *zc) | |
826 { | |
827 nvlist_t *configs; | |
828 int error; | |
829 | |
830 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL) | |
831 return (EEXIST); | |
832 | |
2676 | 833 error = put_nvlist(zc, configs); |
789 | 834 |
835 nvlist_free(configs); | |
836 | |
837 return (error); | |
838 } | |
839 | |
840 static int | |
841 zfs_ioc_pool_stats(zfs_cmd_t *zc) | |
842 { | |
843 nvlist_t *config; | |
844 int error; | |
1544 | 845 int ret = 0; |
789 | 846 |
2676 | 847 error = spa_get_stats(zc->zc_name, &config, zc->zc_value, |
848 sizeof (zc->zc_value)); | |
789 | 849 |
850 if (config != NULL) { | |
2676 | 851 ret = put_nvlist(zc, config); |
789 | 852 nvlist_free(config); |
1544 | 853 |
854 /* | |
855 * The config may be present even if 'error' is non-zero. | |
856 * In this case we return success, and preserve the real errno | |
857 * in 'zc_cookie'. | |
858 */ | |
859 zc->zc_cookie = error; | |
789 | 860 } else { |
1544 | 861 ret = error; |
789 | 862 } |
863 | |
1544 | 864 return (ret); |
789 | 865 } |
866 | |
867 /* | |
868 * Try to import the given pool, returning pool stats as appropriate so that | |
869 * user land knows which devices are available and overall pool health. | |
870 */ | |
871 static int | |
872 zfs_ioc_pool_tryimport(zfs_cmd_t *zc) | |
873 { | |
874 nvlist_t *tryconfig, *config; | |
875 int error; | |
876 | |
5094 | 877 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, |
878 &tryconfig)) != 0) | |
789 | 879 return (error); |
880 | |
881 config = spa_tryimport(tryconfig); | |
882 | |
883 nvlist_free(tryconfig); | |
884 | |
885 if (config == NULL) | |
886 return (EINVAL); | |
887 | |
2676 | 888 error = put_nvlist(zc, config); |
789 | 889 nvlist_free(config); |
890 | |
891 return (error); | |
892 } | |
893 | |
894 static int | |
895 zfs_ioc_pool_scrub(zfs_cmd_t *zc) | |
896 { | |
897 spa_t *spa; | |
898 int error; | |
899 | |
2926 | 900 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
901 return (error); | |
902 | |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
7042
diff
changeset
|
903 error = spa_scrub(spa, zc->zc_cookie); |
2926 | 904 |
905 spa_close(spa, FTAG); | |
906 | |
789 | 907 return (error); |
908 } | |
909 | |
910 static int | |
911 zfs_ioc_pool_freeze(zfs_cmd_t *zc) | |
912 { | |
913 spa_t *spa; | |
914 int error; | |
915 | |
916 error = spa_open(zc->zc_name, &spa, FTAG); | |
917 if (error == 0) { | |
918 spa_freeze(spa); | |
919 spa_close(spa, FTAG); | |
920 } | |
921 return (error); | |
922 } | |
923 | |
924 static int | |
1760 | 925 zfs_ioc_pool_upgrade(zfs_cmd_t *zc) |
926 { | |
927 spa_t *spa; | |
928 int error; | |
929 | |
2926 | 930 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
931 return (error); | |
932 | |
5118
c723b1aa9f79
6607671 Able to zpool upgrade a pool to an unknown version number
lling
parents:
5094
diff
changeset
|
933 if (zc->zc_cookie < spa_version(spa) || zc->zc_cookie > SPA_VERSION) { |
c723b1aa9f79
6607671 Able to zpool upgrade a pool to an unknown version number
lling
parents:
5094
diff
changeset
|
934 spa_close(spa, FTAG); |
c723b1aa9f79
6607671 Able to zpool upgrade a pool to an unknown version number
lling
parents:
5094
diff
changeset
|
935 return (EINVAL); |
c723b1aa9f79
6607671 Able to zpool upgrade a pool to an unknown version number
lling
parents:
5094
diff
changeset
|
936 } |
c723b1aa9f79
6607671 Able to zpool upgrade a pool to an unknown version number
lling
parents:
5094
diff
changeset
|
937 |
5094 | 938 spa_upgrade(spa, zc->zc_cookie); |
2926 | 939 spa_close(spa, FTAG); |
940 | |
941 return (error); | |
942 } | |
943 | |
944 static int | |
945 zfs_ioc_pool_get_history(zfs_cmd_t *zc) | |
946 { | |
947 spa_t *spa; | |
948 char *hist_buf; | |
949 uint64_t size; | |
950 int error; | |
951 | |
952 if ((size = zc->zc_history_len) == 0) | |
953 return (EINVAL); | |
954 | |
955 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) | |
956 return (error); | |
957 | |
4577 | 958 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) { |
3863
d56571426115
6529406 zpool history needs to bump the on-disk version
ek110237
parents:
3741
diff
changeset
|
959 spa_close(spa, FTAG); |
d56571426115
6529406 zpool history needs to bump the on-disk version
ek110237
parents:
3741
diff
changeset
|
960 return (ENOTSUP); |
d56571426115
6529406 zpool history needs to bump the on-disk version
ek110237
parents:
3741
diff
changeset
|
961 } |
d56571426115
6529406 zpool history needs to bump the on-disk version
ek110237
parents:
3741
diff
changeset
|
962 |
2926 | 963 hist_buf = kmem_alloc(size, KM_SLEEP); |
964 if ((error = spa_history_get(spa, &zc->zc_history_offset, | |
965 &zc->zc_history_len, hist_buf)) == 0) { | |
4543 | 966 error = xcopyout(hist_buf, |
967 (char *)(uintptr_t)zc->zc_history, | |
2926 | 968 zc->zc_history_len); |
969 } | |
970 | |
971 spa_close(spa, FTAG); | |
972 kmem_free(hist_buf, size); | |
973 return (error); | |
974 } | |
975 | |
976 static int | |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
977 zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
978 { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
979 int error; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
980 |
3912 | 981 if (error = dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value)) |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
982 return (error); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
983 |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
984 return (0); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
985 } |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
986 |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
987 static int |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
988 zfs_ioc_obj_to_path(zfs_cmd_t *zc) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
989 { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
990 objset_t *osp; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
991 int error; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
992 |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
993 if ((error = dmu_objset_open(zc->zc_name, DMU_OST_ZFS, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
994 DS_MODE_USER | DS_MODE_READONLY, &osp)) != 0) |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
995 return (error); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
996 error = zfs_obj_to_path(osp, zc->zc_obj, zc->zc_value, |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
997 sizeof (zc->zc_value)); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
998 dmu_objset_close(osp); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
999 |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
1000 return (error); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
1001 } |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
1002 |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3265
diff
changeset
|
1003 static int |
789 | 1004 zfs_ioc_vdev_add(zfs_cmd_t *zc) |
1005 { | |
1006 spa_t *spa; | |
1007 int error; | |
6423 | 1008 nvlist_t *config, **l2cache, **spares; |
1009 uint_t nl2cache = 0, nspares = 0; | |
789 | 1010 |
1011 error = spa_open(zc->zc_name, &spa, FTAG); | |
1012 if (error != 0) | |
1013 return (error); | |
1014 | |
5450 | 1015 error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, |
1016 &config); | |
1017 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE, | |
1018 &l2cache, &nl2cache); | |
1019 | |
6423 | 1020 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES, |
1021 &spares, &nspares); | |
1022 | |
3912 | 1023 /* |
1024 * A root pool with concatenated devices is not supported. | |
6423 | 1025 * Thus, can not add a device to a root pool. |
1026 * | |
1027 * Intent log device can not be added to a rootpool because | |
1028 * during mountroot, zil is replayed, a seperated log device | |
1029 * can not be accessed during the mountroot time. | |
1030 * | |
1031 * l2cache and spare devices are ok to be added to a rootpool. | |
3912 | 1032 */ |
6423 | 1033 if (spa->spa_bootfs != 0 && nl2cache == 0 && nspares == 0) { |
3912 | 1034 spa_close(spa, FTAG); |
1035 return (EDOM); | |
1036 } | |
1037 | |
5450 | 1038 if (error == 0) { |
789 | 1039 error = spa_vdev_add(spa, config); |
1040 nvlist_free(config); | |
1041 } | |
1042 spa_close(spa, FTAG); | |
1043 return (error); | |
1044 } | |
1045 | |
1046 static int | |
1047 zfs_ioc_vdev_remove(zfs_cmd_t *zc) | |
1048 { | |
2082 | 1049 spa_t *spa; |
1050 int error; | |
1051 | |
1052 error = spa_open(zc->zc_name, &spa, FTAG); | |
1053 if (error != 0) | |
1054 return (error); | |
1055 error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE); | |
1056 spa_close(spa, FTAG); | |
1057 return (error); | |
789 | 1058 } |
1059 | |
1060 static int | |
4451 | 1061 zfs_ioc_vdev_set_state(zfs_cmd_t *zc) |
789 | 1062 { |
1063 spa_t *spa; | |
1064 int error; | |
4451 | 1065 vdev_state_t newstate = VDEV_STATE_UNKNOWN; |
789 | 1066 |
2926 | 1067 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
789 | 1068 return (error); |
4451 | 1069 switch (zc->zc_cookie) { |
1070 case VDEV_STATE_ONLINE: | |
1071 error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate); | |
1072 break; | |
1073 | |
1074 case VDEV_STATE_OFFLINE: | |
1075 error = vdev_offline(spa, zc->zc_guid, zc->zc_obj); | |
1076 break; | |
789 | 1077 |
4451 | 1078 case VDEV_STATE_FAULTED: |
1079 error = vdev_fault(spa, zc->zc_guid); | |
1080 break; | |
789 | 1081 |
4451 | 1082 case VDEV_STATE_DEGRADED: |
1083 error = vdev_degrade(spa, zc->zc_guid); | |
1084 break; | |
1085 | |
1086 default: | |
1087 error = EINVAL; | |
1088 } | |
1089 zc->zc_cookie = newstate; | |
789 | 1090 spa_close(spa, FTAG); |
1091 return (error); | |
1092 } | |
1093 | |
1094 static int | |
1095 zfs_ioc_vdev_attach(zfs_cmd_t *zc) | |
1096 { | |
1097 spa_t *spa; | |
1098 int replacing = zc->zc_cookie; | |
1099 nvlist_t *config; | |
1100 int error; | |
1101 | |
2926 | 1102 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
789 | 1103 return (error); |
1104 | |
5094 | 1105 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, |
1106 &config)) == 0) { | |
1544 | 1107 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing); |
789 | 1108 nvlist_free(config); |
1109 } | |
1110 | |
1111 spa_close(spa, FTAG); | |
1112 return (error); | |
1113 } | |
1114 | |
1115 static int | |
1116 zfs_ioc_vdev_detach(zfs_cmd_t *zc) | |
1117 { | |
1118 spa_t *spa; | |
1119 int error; | |
1120 | |
2926 | 1121 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) |
789 | 1122 return (error); |
1123 | |
1544 | 1124 error = spa_vdev_detach(spa, zc->zc_guid, B_FALSE); |
789 | 1125 |
1126 spa_close(spa, FTAG); | |
1127 return (error); | |
1128 } | |
1129 | |
1130 static int | |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1131 zfs_ioc_vdev_setpath(zfs_cmd_t *zc) |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1132 { |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1133 spa_t *spa; |
2676 | 1134 char *path = zc->zc_value; |
1544 | 1135 uint64_t guid = zc->zc_guid; |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1136 int error; |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1137 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1138 error = spa_open(zc->zc_name, &spa, FTAG); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1139 if (error != 0) |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1140 return (error); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1141 |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1142 error = spa_vdev_setpath(spa, guid, path); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1143 spa_close(spa, FTAG); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1144 return (error); |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1145 } |
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1146 |
5367 | 1147 /* |
1148 * inputs: | |
1149 * zc_name name of filesystem | |
1150 * zc_nvlist_dst_size size of buffer for property nvlist | |
1151 * | |
1152 * outputs: | |
1153 * zc_objset_stats stats | |
1154 * zc_nvlist_dst property nvlist | |
1155 * zc_nvlist_dst_size size of property nvlist | |
1156 */ | |
1354
81359ee1ee63
6362672 import gets confused about overlapping slices
eschrock
parents:
1133
diff
changeset
|
1157 static int |
789 | 1158 zfs_ioc_objset_stats(zfs_cmd_t *zc) |
1159 { | |
1160 objset_t *os = NULL; | |
1161 int error; | |
1356
e021b5e4aa0e
6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents:
1354
diff
changeset
|
1162 nvlist_t *nv; |
789 | 1163 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1164 if (error = dmu_objset_open(zc->zc_name, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1165 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) |
789 | 1166 return (error); |
1167 | |
2885 | 1168 dmu_objset_fast_stat(os, &zc->zc_objset_stats); |
789 | 1169 |
2856 | 1170 if (zc->zc_nvlist_dst != 0 && |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1171 (error = dsl_prop_get_all(os, &nv, FALSE)) == 0) { |
2885 | 1172 dmu_objset_stats(os, nv); |
3087 | 1173 /* |
5147
5e950ccc9585
6596190 "zfs list" is slow due to version property
rm160521
parents:
5118
diff
changeset
|
1174 * NB: zvol_get_stats() will read the objset contents, |
3087 | 1175 * which we aren't supposed to do with a |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1176 * DS_MODE_USER hold, because it could be |
3087 | 1177 * inconsistent. So this is a bit of a workaround... |
1178 */ | |
4577 | 1179 if (!zc->zc_objset_stats.dds_inconsistent) { |
1180 if (dmu_objset_type(os) == DMU_OST_ZVOL) | |
1181 VERIFY(zvol_get_stats(os, nv) == 0); | |
1182 } | |
2676 | 1183 error = put_nvlist(zc, nv); |
1356
e021b5e4aa0e
6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents:
1354
diff
changeset
|
1184 nvlist_free(nv); |
e021b5e4aa0e
6377671 zfs mount -a shouldn't bother checking snapshots
eschrock
parents:
1354
diff
changeset
|
1185 } |
789 | 1186 |
1187 dmu_objset_close(os); | |
1188 return (error); | |
1189 } | |
1190 | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1191 static int |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1192 nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1193 { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1194 uint64_t value; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1195 int error; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1196 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1197 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1198 * zfs_get_zplprop() will either find a value or give us |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1199 * the default value (if there is one). |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1200 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1201 if ((error = zfs_get_zplprop(os, prop, &value)) != 0) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1202 return (error); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1203 VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1204 return (0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1205 } |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1206 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1207 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1208 * inputs: |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1209 * zc_name name of filesystem |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1210 * zc_nvlist_dst_size size of buffer for zpl property nvlist |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1211 * |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1212 * outputs: |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1213 * zc_nvlist_dst zpl property nvlist |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1214 * zc_nvlist_dst_size size of zpl property nvlist |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1215 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1216 static int |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1217 zfs_ioc_objset_zplprops(zfs_cmd_t *zc) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1218 { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1219 objset_t *os; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1220 int err; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1221 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1222 if (err = dmu_objset_open(zc->zc_name, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1223 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1224 return (err); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1225 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1226 dmu_objset_fast_stat(os, &zc->zc_objset_stats); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1227 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1228 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1229 * NB: nvl_add_zplprop() will read the objset contents, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1230 * which we aren't supposed to do with a DS_MODE_USER |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1231 * hold, because it could be inconsistent. |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1232 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1233 if (zc->zc_nvlist_dst != NULL && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1234 !zc->zc_objset_stats.dds_inconsistent && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1235 dmu_objset_type(os) == DMU_OST_ZFS) { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1236 nvlist_t *nv; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1237 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1238 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1239 if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1240 (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1241 (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1242 (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1243 err = put_nvlist(zc, nv); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1244 nvlist_free(nv); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1245 } else { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1246 err = ENOENT; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1247 } |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1248 dmu_objset_close(os); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1249 return (err); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1250 } |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1251 |
5367 | 1252 /* |
1253 * inputs: | |
1254 * zc_name name of filesystem | |
1255 * zc_cookie zap cursor | |
1256 * zc_nvlist_dst_size size of buffer for property nvlist | |
1257 * | |
1258 * outputs: | |
1259 * zc_name name of next filesystem | |
1260 * zc_objset_stats stats | |
1261 * zc_nvlist_dst property nvlist | |
1262 * zc_nvlist_dst_size size of property nvlist | |
1263 */ | |
789 | 1264 static int |
1265 zfs_ioc_dataset_list_next(zfs_cmd_t *zc) | |
1266 { | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1267 objset_t *os; |
789 | 1268 int error; |
1269 char *p; | |
1270 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1271 if (error = dmu_objset_open(zc->zc_name, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1272 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) { |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1273 if (error == ENOENT) |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1274 error = ESRCH; |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1275 return (error); |
789 | 1276 } |
1277 | |
1278 p = strrchr(zc->zc_name, '/'); | |
1279 if (p == NULL || p[1] != '\0') | |
1280 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name)); | |
1281 p = zc->zc_name + strlen(zc->zc_name); | |
1282 | |
1283 do { | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1284 error = dmu_dir_list_next(os, |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1285 sizeof (zc->zc_name) - (p - zc->zc_name), p, |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1286 NULL, &zc->zc_cookie); |
789 | 1287 if (error == ENOENT) |
1288 error = ESRCH; | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1289 } while (error == 0 && !INGLOBALZONE(curproc) && |
789 | 1290 !zone_dataset_visible(zc->zc_name, NULL)); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1291 dmu_objset_close(os); |
789 | 1292 |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1293 /* |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1294 * If it's a hidden dataset (ie. with a '$' in its name), don't |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1295 * try to get stats for it. Userland will skip over it. |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1296 */ |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1297 if (error == 0 && strchr(zc->zc_name, '$') == NULL) |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1298 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ |
789 | 1299 |
1300 return (error); | |
1301 } | |
1302 | |
5367 | 1303 /* |
1304 * inputs: | |
1305 * zc_name name of filesystem | |
1306 * zc_cookie zap cursor | |
1307 * zc_nvlist_dst_size size of buffer for property nvlist | |
1308 * | |
1309 * outputs: | |
1310 * zc_name name of next snapshot | |
1311 * zc_objset_stats stats | |
1312 * zc_nvlist_dst property nvlist | |
1313 * zc_nvlist_dst_size size of property nvlist | |
1314 */ | |
789 | 1315 static int |
1316 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc) | |
1317 { | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1318 objset_t *os; |
789 | 1319 int error; |
1320 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1321 error = dmu_objset_open(zc->zc_name, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1322 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1323 if (error) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1324 return (error == ENOENT ? ESRCH : error); |
789 | 1325 |
1003 | 1326 /* |
1327 * A dataset name of maximum length cannot have any snapshots, | |
1328 * so exit immediately. | |
1329 */ | |
1330 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) { | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1331 dmu_objset_close(os); |
1003 | 1332 return (ESRCH); |
789 | 1333 } |
1334 | |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1335 error = dmu_snapshot_list_next(os, |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1336 sizeof (zc->zc_name) - strlen(zc->zc_name), |
5663
029cc4273b57
6627223 gfs needs to support extended dirent flags
ck153898
parents:
5498
diff
changeset
|
1337 zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie, NULL); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1338 dmu_objset_close(os); |
885
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1339 if (error == 0) |
d925b21dba78
6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents:
849
diff
changeset
|
1340 error = zfs_ioc_objset_stats(zc); /* fill in the stats */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1341 else if (error == ENOENT) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1342 error = ESRCH; |
789 | 1343 |
5367 | 1344 /* if we failed, undo the @ that we tacked on to zc_name */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1345 if (error) |
5367 | 1346 *strchr(zc->zc_name, '@') = '\0'; |
789 | 1347 return (error); |
1348 } | |
1349 | |
6423 | 1350 int |
4787 | 1351 zfs_set_prop_nvlist(const char *name, nvlist_t *nvl) |
789 | 1352 { |
2676 | 1353 nvpair_t *elem; |
1354 int error; | |
1355 uint64_t intval; | |
1356 char *strval; | |
1357 | |
4543 | 1358 /* |
1359 * First validate permission to set all of the properties | |
1360 */ | |
2676 | 1361 elem = NULL; |
1362 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1363 const char *propname = nvpair_name(elem); |
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1364 zfs_prop_t prop = zfs_name_to_prop(propname); |
2676 | 1365 |
5094 | 1366 if (prop == ZPROP_INVAL) { |
2676 | 1367 /* |
1368 * If this is a user-defined property, it must be a | |
1369 * string, and there is no further validation to do. | |
1370 */ | |
1371 if (!zfs_prop_user(propname) || | |
1372 nvpair_type(elem) != DATA_TYPE_STRING) | |
1373 return (EINVAL); | |
1374 | |
5331 | 1375 if (error = zfs_secpolicy_write_perms(name, |
1376 ZFS_DELEG_PERM_USERPROP, CRED())) | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1377 return (error); |
4543 | 1378 continue; |
2676 | 1379 } |
1380 | |
4787 | 1381 if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0) |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1382 return (error); |
2676 | 1383 |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1384 /* |
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1385 * Check that this value is valid for this pool version |
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1386 */ |
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1387 switch (prop) { |
3886
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1388 case ZFS_PROP_COMPRESSION: |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1389 /* |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1390 * If the user specified gzip compression, make sure |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1391 * the SPA supports it. We ignore any errors here since |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1392 * we'll catch them later. |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1393 */ |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1394 if (nvpair_type(elem) == DATA_TYPE_UINT64 && |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1395 nvpair_value_uint64(elem, &intval) == 0) { |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1396 if (intval >= ZIO_COMPRESS_GZIP_1 && |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1397 intval <= ZIO_COMPRESS_GZIP_9 && |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1398 zfs_check_version(name, |
5331 | 1399 SPA_VERSION_GZIP_COMPRESSION)) |
1400 return (ENOTSUP); | |
7042
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1401 |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1402 /* |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1403 * If this is a bootable dataset then |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1404 * verify that the compression algorithm |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1405 * is supported for booting. We must return |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1406 * something other than ENOTSUP since it |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1407 * implies a downrev pool version. |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1408 */ |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1409 if (zfs_is_bootfs(name) && |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1410 !BOOTFS_COMPRESS_VALID(intval)) |
46fc4b6db23e
6721094 Setting certain properties on root pools should not be allowed
gw25295
parents:
6865
diff
changeset
|
1411 return (ERANGE); |
3886
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1412 } |
3291401d66a6
6536602 add zlib compression support and upgrade to version 1.2.3
ahl
parents:
3863
diff
changeset
|
1413 break; |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
1414 |
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
1415 case ZFS_PROP_COPIES: |
5331 | 1416 if (zfs_check_version(name, SPA_VERSION_DITTO_BLOCKS)) |
1417 return (ENOTSUP); | |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
1418 break; |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
1419 |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
1420 case ZFS_PROP_SHARESMB: |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1421 if (zpl_earlier_version(name, ZPL_VERSION_FUID)) |
5977
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
1422 return (ENOTSUP); |
33727f49aeaa
6654731 sharesmb property should only be settable on CIFS aware ZPL
marks
parents:
5663
diff
changeset
|
1423 break; |
4603
c7840c367d00
6494569 zfs recv -d pool/<doesn't exist> core dumps for top-level filesystem backups
ahrens
parents:
4577
diff
changeset
|
1424 } |
5331 | 1425 if ((error = zfs_secpolicy_setprop(name, prop, CRED())) != 0) |
1426 return (error); | |
4543 | 1427 } |
1428 | |
1429 elem = NULL; | |
1430 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) { | |
4670
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1431 const char *propname = nvpair_name(elem); |
002728040e28
6580745 "zfs inherit" can be executed by ordinary user
ahrens
parents:
4611
diff
changeset
|
1432 zfs_prop_t prop = zfs_name_to_prop(propname); |
4543 | 1433 |
5094 | 1434 if (prop == ZPROP_INVAL) { |
4543 | 1435 VERIFY(nvpair_value_string(elem, &strval) == 0); |
1436 error = dsl_prop_set(name, propname, 1, | |
1437 strlen(strval) + 1, strval); | |
1438 if (error == 0) | |
1439 continue; | |
1440 else | |
1441 return (error); | |
1442 } | |
2676 | 1443 |
1444 switch (prop) { | |
1445 case ZFS_PROP_QUOTA: | |
1446 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || | |
4577 | 1447 (error = dsl_dir_set_quota(name, intval)) != 0) |
2676 | 1448 return (error); |
1449 break; | |
1450 | |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1451 case ZFS_PROP_REFQUOTA: |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1452 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1453 (error = dsl_dataset_set_quota(name, intval)) != 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1454 return (error); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1455 break; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1456 |
2676 | 1457 case ZFS_PROP_RESERVATION: |
1458 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || | |
1459 (error = dsl_dir_set_reservation(name, | |
1460 intval)) != 0) | |
1461 return (error); | |
1462 break; | |
789 | 1463 |
5378
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1464 case ZFS_PROP_REFRESERVATION: |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1465 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1466 (error = dsl_dataset_set_reservation(name, |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1467 intval)) != 0) |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1468 return (error); |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1469 break; |
111aa1baa84a
PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents:
5375
diff
changeset
|
1470 |
2676 | 1471 case ZFS_PROP_VOLSIZE: |
1472 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || | |
4787 | 1473 (error = zvol_set_volsize(name, |
1474 ddi_driver_major(zfs_dip), intval)) != 0) | |
2676 | 1475 return (error); |
1476 break; | |
1477 | |
1478 case ZFS_PROP_VOLBLOCKSIZE: | |
1479 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || | |
4577 | 1480 (error = zvol_set_volblocksize(name, intval)) != 0) |
1481 return (error); | |
1482 break; | |
1483 | |
1484 case ZFS_PROP_VERSION: | |
1485 if ((error = nvpair_value_uint64(elem, &intval)) != 0 || | |
1486 (error = zfs_set_version(name, intval)) != 0) | |
2676 | 1487 return (error); |
1488 break; | |
1489 | |
1490 default: | |
1491 if (nvpair_type(elem) == DATA_TYPE_STRING) { | |
1492 if (zfs_prop_get_type(prop) != | |
4787 | 1493 PROP_TYPE_STRING) |
2676 | 1494 return (EINVAL); |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1495 VERIFY(nvpair_value_string(elem, &strval) == 0); |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1496 if ((error = dsl_prop_set(name, |
2676 | 1497 nvpair_name(elem), 1, strlen(strval) + 1, |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1498 strval)) != 0) |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1499 return (error); |
2676 | 1500 } else if (nvpair_type(elem) == DATA_TYPE_UINT64) { |
2885 | 1501 const char *unused; |
1502 | |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1503 VERIFY(nvpair_value_uint64(elem, &intval) == 0); |
2676 | 1504 |
1505 switch (zfs_prop_get_type(prop)) { | |
4787 | 1506 case PROP_TYPE_NUMBER: |
2676 | 1507 break; |
4787 | 1508 case PROP_TYPE_STRING: |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1509 return (EINVAL); |
4787 | 1510 case PROP_TYPE_INDEX: |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1511 if (zfs_prop_index_to_string(prop, |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1512 intval, &unused) != 0) |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1513 return (EINVAL); |
2676 | 1514 break; |
1515 default: | |
4577 | 1516 cmn_err(CE_PANIC, |
1517 "unknown property type"); | |
2676 | 1518 break; |
1519 } | |
1520 | |
2717
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1521 if ((error = dsl_prop_set(name, propname, |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1522 8, 1, &intval)) != 0) |
ed589a32259d
6469385 zfs_set_prop_nvlist range checking is busted
eschrock
parents:
2676
diff
changeset
|
1523 return (error); |
2676 | 1524 } else { |
1525 return (EINVAL); | |
1526 } | |
1527 break; | |
1528 } | |
1529 } | |
1530 | |
1531 return (0); | |
789 | 1532 } |
1533 | |
5367 | 1534 /* |
1535 * inputs: | |
1536 * zc_name name of filesystem | |
1537 * zc_value name of property to inherit | |
1538 * zc_nvlist_src{_size} nvlist of properties to apply | |
1539 * | |
1540 * outputs: none | |
1541 */ | |
789 | 1542 static int |
2676 | 1543 zfs_ioc_set_prop(zfs_cmd_t *zc) |
789 | 1544 { |
2676 | 1545 nvlist_t *nvl; |
1546 int error; | |
789 | 1547 |
5094 | 1548 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, |
1549 &nvl)) != 0) | |
2676 | 1550 return (error); |
1551 | |
4787 | 1552 error = zfs_set_prop_nvlist(zc->zc_name, nvl); |
4543 | 1553 |
2676 | 1554 nvlist_free(nvl); |
1555 return (error); | |
789 | 1556 } |
1557 | |
5367 | 1558 /* |
1559 * inputs: | |
1560 * zc_name name of filesystem | |
1561 * zc_value name of property to inherit | |
1562 * | |
1563 * outputs: none | |
1564 */ | |
789 | 1565 static int |
4849
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1566 zfs_ioc_inherit_prop(zfs_cmd_t *zc) |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1567 { |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1568 /* the property name has been validated by zfs_secpolicy_inherit() */ |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1569 return (dsl_prop_set(zc->zc_name, zc->zc_value, 0, 0, NULL)); |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1570 } |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1571 |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
1572 static int |
4098
0a182c2128e6
6545726 make ZFS_IOC_POOL_*_PROPS in sync with zfs_ioc_pool_props_*
lling
parents:
4007
diff
changeset
|
1573 zfs_ioc_pool_set_props(zfs_cmd_t *zc) |
3912 | 1574 { |
5094 | 1575 nvlist_t *props; |
3912 | 1576 spa_t *spa; |
5094 | 1577 int error; |
3912 | 1578 |
5094 | 1579 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, |
1580 &props))) | |
3912 | 1581 return (error); |
1582 | |
1583 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) { | |
5094 | 1584 nvlist_free(props); |
3912 | 1585 return (error); |
1586 } | |
1587 | |
5094 | 1588 error = spa_prop_set(spa, props); |
3912 | 1589 |
5094 | 1590 nvlist_free(props); |
3912 | 1591 spa_close(spa, FTAG); |
1592 | |
1593 return (error); | |
1594 } | |
1595 | |
1596 static int | |
4098
0a182c2128e6
6545726 make ZFS_IOC_POOL_*_PROPS in sync with zfs_ioc_pool_props_*
lling
parents:
4007
diff
changeset
|
1597 zfs_ioc_pool_get_props(zfs_cmd_t *zc) |
3912 | 1598 { |
1599 spa_t *spa; | |
1600 int error; | |
1601 nvlist_t *nvp = NULL; | |
1602 | |
1603 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) | |
1604 return (error); | |
1605 | |
5094 | 1606 error = spa_prop_get(spa, &nvp); |
3912 | 1607 |
1608 if (error == 0 && zc->zc_nvlist_dst != NULL) | |
1609 error = put_nvlist(zc, nvp); | |
1610 else | |
1611 error = EFAULT; | |
1612 | |
1613 spa_close(spa, FTAG); | |
1614 | |
1615 if (nvp) | |
1616 nvlist_free(nvp); | |
1617 return (error); | |
1618 } | |
1619 | |
1620 static int | |
4543 | 1621 zfs_ioc_iscsi_perm_check(zfs_cmd_t *zc) |
1622 { | |
1623 nvlist_t *nvp; | |
1624 int error; | |
1625 uint32_t uid; | |
1626 uint32_t gid; | |
1627 uint32_t *groups; | |
1628 uint_t group_cnt; | |
1629 cred_t *usercred; | |
1630 | |
5094 | 1631 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, |
1632 &nvp)) != 0) { | |
4543 | 1633 return (error); |
1634 } | |
1635 | |
1636 if ((error = nvlist_lookup_uint32(nvp, | |
1637 ZFS_DELEG_PERM_UID, &uid)) != 0) { | |
1638 nvlist_free(nvp); | |
1639 return (EPERM); | |
1640 } | |
1641 | |
1642 if ((error = nvlist_lookup_uint32(nvp, | |
1643 ZFS_DELEG_PERM_GID, &gid)) != 0) { | |
1644 nvlist_free(nvp); | |
1645 return (EPERM); | |
1646 } | |
1647 | |
1648 if ((error = nvlist_lookup_uint32_array(nvp, ZFS_DELEG_PERM_GROUPS, | |
1649 &groups, &group_cnt)) != 0) { | |
1650 nvlist_free(nvp); | |
1651 return (EPERM); | |
1652 } | |
1653 usercred = cralloc(); | |
1654 if ((crsetugid(usercred, uid, gid) != 0) || | |
1655 (crsetgroups(usercred, group_cnt, (gid_t *)groups) != 0)) { | |
1656 nvlist_free(nvp); | |
1657 crfree(usercred); | |
1658 return (EPERM); | |
1659 } | |
1660 nvlist_free(nvp); | |
1661 error = dsl_deleg_access(zc->zc_name, | |
4787 | 1662 zfs_prop_to_name(ZFS_PROP_SHAREISCSI), usercred); |
4543 | 1663 crfree(usercred); |
1664 return (error); | |
1665 } | |
1666 | |
5367 | 1667 /* |
1668 * inputs: | |
1669 * zc_name name of filesystem | |
1670 * zc_nvlist_src{_size} nvlist of delegated permissions | |
1671 * zc_perm_action allow/unallow flag | |
1672 * | |
1673 * outputs: none | |
1674 */ | |
4543 | 1675 static int |
1676 zfs_ioc_set_fsacl(zfs_cmd_t *zc) | |
1677 { | |
1678 int error; | |
1679 nvlist_t *fsaclnv = NULL; | |
1680 | |
5094 | 1681 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, |
1682 &fsaclnv)) != 0) | |
4543 | 1683 return (error); |
1684 | |
1685 /* | |
1686 * Verify nvlist is constructed correctly | |
1687 */ | |
1688 if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) { | |
1689 nvlist_free(fsaclnv); | |
1690 return (EINVAL); | |
1691 } | |
1692 | |
1693 /* | |
1694 * If we don't have PRIV_SYS_MOUNT, then validate | |
1695 * that user is allowed to hand out each permission in | |
1696 * the nvlist(s) | |
1697 */ | |
1698 | |
4787 | 1699 error = secpolicy_zfs(CRED()); |
4543 | 1700 if (error) { |
4787 | 1701 if (zc->zc_perm_action == B_FALSE) { |
1702 error = dsl_deleg_can_allow(zc->zc_name, | |
1703 fsaclnv, CRED()); | |
1704 } else { | |
1705 error = dsl_deleg_can_unallow(zc->zc_name, | |
1706 fsaclnv, CRED()); | |
1707 } | |
4543 | 1708 } |
1709 | |
1710 if (error == 0) | |
1711 error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action); | |
1712 | |
1713 nvlist_free(fsaclnv); | |
1714 return (error); | |
1715 } | |
1716 | |
5367 | 1717 /* |
1718 * inputs: | |
1719 * zc_name name of filesystem | |
1720 * | |
1721 * outputs: | |
1722 * zc_nvlist_src{_size} nvlist of delegated permissions | |
1723 */ | |
4543 | 1724 static int |
1725 zfs_ioc_get_fsacl(zfs_cmd_t *zc) | |
1726 { | |
1727 nvlist_t *nvp; | |
1728 int error; | |
1729 | |
1730 if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) { | |
1731 error = put_nvlist(zc, nvp); | |
1732 nvlist_free(nvp); | |
1733 } | |
1734 | |
1735 return (error); | |
1736 } | |
1737 | |
5367 | 1738 /* |
1739 * inputs: | |
1740 * zc_name name of volume | |
1741 * | |
1742 * outputs: none | |
1743 */ | |
4543 | 1744 static int |
789 | 1745 zfs_ioc_create_minor(zfs_cmd_t *zc) |
1746 { | |
4787 | 1747 return (zvol_create_minor(zc->zc_name, ddi_driver_major(zfs_dip))); |
789 | 1748 } |
1749 | |
5367 | 1750 /* |
1751 * inputs: | |
1752 * zc_name name of volume | |
1753 * | |
1754 * outputs: none | |
1755 */ | |
789 | 1756 static int |
1757 zfs_ioc_remove_minor(zfs_cmd_t *zc) | |
1758 { | |
2676 | 1759 return (zvol_remove_minor(zc->zc_name)); |
789 | 1760 } |
1761 | |
1762 /* | |
1763 * Search the vfs list for a specified resource. Returns a pointer to it | |
1764 * or NULL if no suitable entry is found. The caller of this routine | |
1765 * is responsible for releasing the returned vfs pointer. | |
1766 */ | |
1767 static vfs_t * | |
1768 zfs_get_vfs(const char *resource) | |
1769 { | |
1770 struct vfs *vfsp; | |
1771 struct vfs *vfs_found = NULL; | |
1772 | |
1773 vfs_list_read_lock(); | |
1774 vfsp = rootvfs; | |
1775 do { | |
1776 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { | |
1777 VFS_HOLD(vfsp); | |
1778 vfs_found = vfsp; | |
1779 break; | |
1780 } | |
1781 vfsp = vfsp->vfs_next; | |
1782 } while (vfsp != rootvfs); | |
1783 vfs_list_unlock(); | |
1784 return (vfs_found); | |
1785 } | |
1786 | |
4543 | 1787 /* ARGSUSED */ |
789 | 1788 static void |
4543 | 1789 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx) |
789 | 1790 { |
5331 | 1791 zfs_creat_t *zct = arg; |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1792 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1793 zfs_create_fs(os, cr, zct->zct_zplprops, tx); |
5331 | 1794 } |
1795 | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1796 #define ZFS_PROP_UNDEFINED ((uint64_t)-1) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1797 |
5331 | 1798 /* |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1799 * inputs: |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1800 * createprops list of properties requested by creator |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1801 * dataset name of dataset we are creating |
5331 | 1802 * |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1803 * outputs: |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1804 * zplprops values for the zplprops we attach to the master node object |
5331 | 1805 * |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1806 * Determine the settings for utf8only, normalization and |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1807 * casesensitivity. Specific values may have been requested by the |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1808 * creator and/or we can inherit values from the parent dataset. If |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1809 * the file system is of too early a vintage, a creator can not |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1810 * request settings for these properties, even if the requested |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1811 * setting is the default value. We don't actually want to create dsl |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1812 * properties for these, so remove them from the source nvlist after |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1813 * processing. |
5331 | 1814 */ |
1815 static int | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1816 zfs_fill_zplprops(const char *dataset, nvlist_t *createprops, |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1817 nvlist_t *zplprops, uint64_t zplver, boolean_t *is_ci) |
5331 | 1818 { |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1819 objset_t *os; |
5331 | 1820 char parentname[MAXNAMELEN]; |
1821 char *cp; | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1822 uint64_t sense = ZFS_PROP_UNDEFINED; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1823 uint64_t norm = ZFS_PROP_UNDEFINED; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1824 uint64_t u8 = ZFS_PROP_UNDEFINED; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1825 int error = 0; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1826 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1827 ASSERT(zplprops != NULL); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1828 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1829 (void) strlcpy(parentname, dataset, sizeof (parentname)); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1830 cp = strrchr(parentname, '/'); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1831 ASSERT(cp != NULL); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1832 cp[0] = '\0'; |
5331 | 1833 |
5375 | 1834 /* |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1835 * Pull out creator prop choices, if any. |
5375 | 1836 */ |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1837 if (createprops) { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1838 (void) nvlist_lookup_uint64(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1839 zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1840 (void) nvlist_remove_all(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1841 zfs_prop_to_name(ZFS_PROP_NORMALIZE)); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1842 (void) nvlist_lookup_uint64(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1843 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1844 (void) nvlist_remove_all(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1845 zfs_prop_to_name(ZFS_PROP_UTF8ONLY)); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1846 (void) nvlist_lookup_uint64(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1847 zfs_prop_to_name(ZFS_PROP_CASE), &sense); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1848 (void) nvlist_remove_all(createprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1849 zfs_prop_to_name(ZFS_PROP_CASE)); |
5331 | 1850 } |
1851 | |
5375 | 1852 /* |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1853 * If the file system or pool is version is too "young" to |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1854 * support normalization and the creator tried to set a value |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1855 * for one of the props, error out. We only need check the |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1856 * ZPL version because we've already checked by now that the |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1857 * SPA version is compatible with the selected ZPL version. |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1858 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1859 if (zplver < ZPL_VERSION_NORMALIZATION && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1860 (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED || |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1861 sense != ZFS_PROP_UNDEFINED)) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1862 return (ENOTSUP); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1863 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1864 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1865 * Put the version in the zplprops |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1866 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1867 VERIFY(nvlist_add_uint64(zplprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1868 zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1869 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1870 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1871 * Open parent object set so we can inherit zplprop values if |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1872 * necessary. |
5375 | 1873 */ |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1874 if (error = dmu_objset_open(parentname, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1875 DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os)) |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1876 return (error); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1877 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1878 if (norm == ZFS_PROP_UNDEFINED) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1879 VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1880 VERIFY(nvlist_add_uint64(zplprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1881 zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1882 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1883 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1884 * If we're normalizing, names must always be valid UTF-8 strings. |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1885 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1886 if (norm) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1887 u8 = 1; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1888 if (u8 == ZFS_PROP_UNDEFINED) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1889 VERIFY(zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1890 VERIFY(nvlist_add_uint64(zplprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1891 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1892 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1893 if (sense == ZFS_PROP_UNDEFINED) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1894 VERIFY(zfs_get_zplprop(os, ZFS_PROP_CASE, &sense) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1895 VERIFY(nvlist_add_uint64(zplprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1896 zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1897 |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1898 if (is_ci) |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1899 *is_ci = (sense == ZFS_CASE_INSENSITIVE); |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1900 |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1901 dmu_objset_close(os); |
5331 | 1902 return (0); |
789 | 1903 } |
1904 | |
5367 | 1905 /* |
1906 * inputs: | |
1907 * zc_objset_type type of objset to create (fs vs zvol) | |
1908 * zc_name name of new objset | |
1909 * zc_value name of snapshot to clone from (may be empty) | |
1910 * zc_nvlist_src{_size} nvlist of properties to apply | |
1911 * | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1912 * outputs: none |
5367 | 1913 */ |
789 | 1914 static int |
1915 zfs_ioc_create(zfs_cmd_t *zc) | |
1916 { | |
1917 objset_t *clone; | |
1918 int error = 0; | |
5331 | 1919 zfs_creat_t zct; |
4543 | 1920 nvlist_t *nvprops = NULL; |
1921 void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx); | |
789 | 1922 dmu_objset_type_t type = zc->zc_objset_type; |
1923 | |
1924 switch (type) { | |
1925 | |
1926 case DMU_OST_ZFS: | |
1927 cbfunc = zfs_create_cb; | |
1928 break; | |
1929 | |
1930 case DMU_OST_ZVOL: | |
1931 cbfunc = zvol_create_cb; | |
1932 break; | |
1933 | |
1934 default: | |
2199 | 1935 cbfunc = NULL; |
6423 | 1936 break; |
2199 | 1937 } |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
1938 if (strchr(zc->zc_name, '@') || |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
1939 strchr(zc->zc_name, '%')) |
789 | 1940 return (EINVAL); |
1941 | |
2676 | 1942 if (zc->zc_nvlist_src != NULL && |
5094 | 1943 (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, |
1944 &nvprops)) != 0) | |
2676 | 1945 return (error); |
1946 | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
1947 zct.zct_zplprops = NULL; |
5331 | 1948 zct.zct_props = nvprops; |
1949 | |
2676 | 1950 if (zc->zc_value[0] != '\0') { |
789 | 1951 /* |
1952 * We're creating a clone of an existing snapshot. | |
1953 */ | |
2676 | 1954 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; |
1955 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0) { | |
4543 | 1956 nvlist_free(nvprops); |
789 | 1957 return (EINVAL); |
2676 | 1958 } |
789 | 1959 |
2676 | 1960 error = dmu_objset_open(zc->zc_value, type, |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
1961 DS_MODE_USER | DS_MODE_READONLY, &clone); |
2676 | 1962 if (error) { |
4543 | 1963 nvlist_free(nvprops); |
789 | 1964 return (error); |
2676 | 1965 } |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1966 |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1967 error = dmu_objset_create(zc->zc_name, type, clone, 0, |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1968 NULL, NULL); |
5331 | 1969 if (error) { |
1970 dmu_objset_close(clone); | |
1971 nvlist_free(nvprops); | |
1972 return (error); | |
1973 } | |
789 | 1974 dmu_objset_close(clone); |
1975 } else { | |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1976 boolean_t is_insensitive = B_FALSE; |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
1977 |
2676 | 1978 if (cbfunc == NULL) { |
4543 | 1979 nvlist_free(nvprops); |
2199 | 1980 return (EINVAL); |
2676 | 1981 } |
1982 | |
789 | 1983 if (type == DMU_OST_ZVOL) { |
2676 | 1984 uint64_t volsize, volblocksize; |
1985 | |
4543 | 1986 if (nvprops == NULL || |
1987 nvlist_lookup_uint64(nvprops, | |
2676 | 1988 zfs_prop_to_name(ZFS_PROP_VOLSIZE), |
1989 &volsize) != 0) { | |
4543 | 1990 nvlist_free(nvprops); |
2676 | 1991 return (EINVAL); |
1992 } | |
1993 | |
4543 | 1994 if ((error = nvlist_lookup_uint64(nvprops, |
2676 | 1995 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE), |
1996 &volblocksize)) != 0 && error != ENOENT) { | |
4543 | 1997 nvlist_free(nvprops); |
2676 | 1998 return (EINVAL); |
1999 } | |
1133
335d069294d1
6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents:
1003
diff
changeset
|
2000 |
2676 | 2001 if (error != 0) |
2002 volblocksize = zfs_prop_default_numeric( | |
2003 ZFS_PROP_VOLBLOCKSIZE); | |
2004 | |
2005 if ((error = zvol_check_volblocksize( | |
2006 volblocksize)) != 0 || | |
2007 (error = zvol_check_volsize(volsize, | |
2008 volblocksize)) != 0) { | |
4543 | 2009 nvlist_free(nvprops); |
789 | 2010 return (error); |
2676 | 2011 } |
4577 | 2012 } else if (type == DMU_OST_ZFS) { |
2013 uint64_t version; | |
5331 | 2014 int error; |
2015 | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2016 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2017 * Default ZPL version to non-FUID capable if the |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2018 * pool is not upgraded to support FUIDs. |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2019 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2020 if (zfs_check_version(zc->zc_name, SPA_VERSION_FUID)) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2021 version = ZPL_VERSION_FUID - 1; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2022 else |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2023 version = ZPL_VERSION; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2024 |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2025 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2026 * Potentially override default ZPL version based |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2027 * on creator's request. |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2028 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2029 (void) nvlist_lookup_uint64(nvprops, |
5331 | 2030 zfs_prop_to_name(ZFS_PROP_VERSION), &version); |
2031 | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2032 /* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2033 * Make sure version we ended up with is kosher |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2034 */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2035 if ((version < ZPL_VERSION_INITIAL || |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2036 version > ZPL_VERSION) || |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2037 (version >= ZPL_VERSION_FUID && |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2038 zfs_check_version(zc->zc_name, SPA_VERSION_FUID))) { |
5331 | 2039 nvlist_free(nvprops); |
2040 return (ENOTSUP); | |
2041 } | |
2042 | |
2043 /* | |
2044 * We have to have normalization and | |
2045 * case-folding flags correct when we do the | |
2046 * file system creation, so go figure them out | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2047 * now. |
5331 | 2048 */ |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2049 VERIFY(nvlist_alloc(&zct.zct_zplprops, |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2050 NV_UNIQUE_NAME, KM_SLEEP) == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2051 error = zfs_fill_zplprops(zc->zc_name, nvprops, |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
2052 zct.zct_zplprops, version, &is_insensitive); |
5331 | 2053 if (error != 0) { |
2054 nvlist_free(nvprops); | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2055 nvlist_free(zct.zct_zplprops); |
5331 | 2056 return (error); |
4577 | 2057 } |
2676 | 2058 } |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
2059 error = dmu_objset_create(zc->zc_name, type, NULL, |
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
6423
diff
changeset
|
2060 is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct); |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2061 nvlist_free(zct.zct_zplprops); |
789 | 2062 } |
2676 | 2063 |
2064 /* | |
2065 * It would be nice to do this atomically. | |
2066 */ | |
2067 if (error == 0) { | |
4787 | 2068 if ((error = zfs_set_prop_nvlist(zc->zc_name, nvprops)) != 0) |
2676 | 2069 (void) dmu_objset_destroy(zc->zc_name); |
2070 } | |
4543 | 2071 nvlist_free(nvprops); |
789 | 2072 return (error); |
2073 } | |
2074 | |
5367 | 2075 /* |
2076 * inputs: | |
2077 * zc_name name of filesystem | |
2078 * zc_value short name of snapshot | |
2079 * zc_cookie recursive flag | |
2080 * | |
2081 * outputs: none | |
2082 */ | |
789 | 2083 static int |
2199 | 2084 zfs_ioc_snapshot(zfs_cmd_t *zc) |
2085 { | |
2676 | 2086 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) |
2199 | 2087 return (EINVAL); |
2088 return (dmu_objset_snapshot(zc->zc_name, | |
2676 | 2089 zc->zc_value, zc->zc_cookie)); |
2199 | 2090 } |
2091 | |
4007 | 2092 int |
2199 | 2093 zfs_unmount_snap(char *name, void *arg) |
789 | 2094 { |
2417 | 2095 vfs_t *vfsp = NULL; |
2199 | 2096 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2097 if (arg) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2098 char *snapname = arg; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2099 int len = strlen(name) + strlen(snapname) + 2; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2100 char *buf = kmem_alloc(len, KM_SLEEP); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2101 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2102 (void) strcpy(buf, name); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2103 (void) strcat(buf, "@"); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2104 (void) strcat(buf, snapname); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2105 vfsp = zfs_get_vfs(buf); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2106 kmem_free(buf, len); |
2417 | 2107 } else if (strchr(name, '@')) { |
2199 | 2108 vfsp = zfs_get_vfs(name); |
2109 } | |
2110 | |
2111 if (vfsp) { | |
2112 /* | |
2113 * Always force the unmount for snapshots. | |
2114 */ | |
2115 int flag = MS_FORCE; | |
789 | 2116 int err; |
2117 | |
2199 | 2118 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) { |
2119 VFS_RELE(vfsp); | |
2120 return (err); | |
2121 } | |
2122 VFS_RELE(vfsp); | |
2123 if ((err = dounmount(vfsp, flag, kcred)) != 0) | |
2124 return (err); | |
2125 } | |
2126 return (0); | |
2127 } | |
2128 | |
5367 | 2129 /* |
2130 * inputs: | |
2131 * zc_name name of filesystem | |
2132 * zc_value short name of snapshot | |
2133 * | |
2134 * outputs: none | |
2135 */ | |
2199 | 2136 static int |
2137 zfs_ioc_destroy_snaps(zfs_cmd_t *zc) | |
2138 { | |
2139 int err; | |
789 | 2140 |
2676 | 2141 if (snapshot_namecheck(zc->zc_value, NULL, NULL) != 0) |
2199 | 2142 return (EINVAL); |
2143 err = dmu_objset_find(zc->zc_name, | |
2676 | 2144 zfs_unmount_snap, zc->zc_value, DS_FIND_CHILDREN); |
2199 | 2145 if (err) |
2146 return (err); | |
2676 | 2147 return (dmu_snapshots_destroy(zc->zc_name, zc->zc_value)); |
2199 | 2148 } |
2149 | |
5367 | 2150 /* |
2151 * inputs: | |
2152 * zc_name name of dataset to destroy | |
2153 * zc_objset_type type of objset | |
2154 * | |
2155 * outputs: none | |
2156 */ | |
2199 | 2157 static int |
2158 zfs_ioc_destroy(zfs_cmd_t *zc) | |
2159 { | |
2160 if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS) { | |
2161 int err = zfs_unmount_snap(zc->zc_name, NULL); | |
2162 if (err) | |
2163 return (err); | |
789 | 2164 } |
2165 | |
2166 return (dmu_objset_destroy(zc->zc_name)); | |
2167 } | |
2168 | |
5367 | 2169 /* |
2170 * inputs: | |
5446 | 2171 * zc_name name of dataset to rollback (to most recent snapshot) |
5367 | 2172 * |
2173 * outputs: none | |
2174 */ | |
789 | 2175 static int |
2176 zfs_ioc_rollback(zfs_cmd_t *zc) | |
2177 { | |
5446 | 2178 objset_t *os; |
2179 int error; | |
2180 zfsvfs_t *zfsvfs = NULL; | |
2181 | |
2182 /* | |
2183 * Get the zfsvfs for the receiving objset. There | |
2184 * won't be one if we're operating on a zvol, if the | |
2185 * objset doesn't exist yet, or is not mounted. | |
2186 */ | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2187 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, DS_MODE_USER, &os); |
5446 | 2188 if (error) |
2189 return (error); | |
2190 | |
2191 if (dmu_objset_type(os) == DMU_OST_ZFS) { | |
2192 mutex_enter(&os->os->os_user_ptr_lock); | |
2193 zfsvfs = dmu_objset_get_user(os); | |
2194 if (zfsvfs != NULL) | |
2195 VFS_HOLD(zfsvfs->z_vfs); | |
2196 mutex_exit(&os->os->os_user_ptr_lock); | |
2197 } | |
2198 | |
2199 if (zfsvfs != NULL) { | |
2200 char osname[MAXNAMELEN]; | |
2201 int mode; | |
2202 | |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2203 error = zfs_suspend_fs(zfsvfs, osname, &mode); |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2204 if (error == 0) { |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2205 int resume_err; |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2206 |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2207 ASSERT(strcmp(osname, zc->zc_name) == 0); |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2208 error = dmu_objset_rollback(os); |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2209 resume_err = zfs_resume_fs(zfsvfs, osname, mode); |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2210 error = error ? error : resume_err; |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2211 } else { |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2212 dmu_objset_close(os); |
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2213 } |
5446 | 2214 VFS_RELE(zfsvfs->z_vfs); |
2215 } else { | |
2216 error = dmu_objset_rollback(os); | |
2217 } | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2218 /* Note, the dmu_objset_rollback() releases the objset for us. */ |
5446 | 2219 |
2220 return (error); | |
789 | 2221 } |
2222 | |
5367 | 2223 /* |
2224 * inputs: | |
2225 * zc_name old name of dataset | |
2226 * zc_value new name of dataset | |
2227 * zc_cookie recursive flag (only valid for snapshots) | |
2228 * | |
2229 * outputs: none | |
2230 */ | |
789 | 2231 static int |
2232 zfs_ioc_rename(zfs_cmd_t *zc) | |
2233 { | |
4490 | 2234 boolean_t recursive = zc->zc_cookie & 1; |
4007 | 2235 |
2676 | 2236 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0'; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2237 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2238 strchr(zc->zc_value, '%')) |
789 | 2239 return (EINVAL); |
2240 | |
4007 | 2241 /* |
2242 * Unmount snapshot unless we're doing a recursive rename, | |
2243 * in which case the dataset code figures out which snapshots | |
2244 * to unmount. | |
2245 */ | |
2246 if (!recursive && strchr(zc->zc_name, '@') != NULL && | |
789 | 2247 zc->zc_objset_type == DMU_OST_ZFS) { |
2199 | 2248 int err = zfs_unmount_snap(zc->zc_name, NULL); |
2249 if (err) | |
2250 return (err); | |
789 | 2251 } |
4007 | 2252 return (dmu_objset_rename(zc->zc_name, zc->zc_value, recursive)); |
789 | 2253 } |
2254 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2255 static void |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2256 clear_props(char *dataset, nvlist_t *props) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2257 { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2258 zfs_cmd_t *zc; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2259 nvpair_t *prop; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2260 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2261 if (props == NULL) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2262 return; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2263 zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2264 (void) strcpy(zc->zc_name, dataset); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2265 for (prop = nvlist_next_nvpair(props, NULL); prop; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2266 prop = nvlist_next_nvpair(props, prop)) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2267 (void) strcpy(zc->zc_value, nvpair_name(prop)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2268 if (zfs_secpolicy_inherit(zc, CRED()) == 0) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2269 (void) zfs_ioc_inherit_prop(zc); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2270 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2271 kmem_free(zc, sizeof (zfs_cmd_t)); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2272 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2273 |
5367 | 2274 /* |
2275 * inputs: | |
2276 * zc_name name of containing filesystem | |
2277 * zc_nvlist_src{_size} nvlist of properties to apply | |
2278 * zc_value name of snapshot to create | |
2279 * zc_string name of clone origin (if DRR_FLAG_CLONE) | |
2280 * zc_cookie file descriptor to recv from | |
2281 * zc_begin_record the BEGIN record of the stream (not byteswapped) | |
2282 * zc_guid force flag | |
2283 * | |
2284 * outputs: | |
2285 * zc_cookie number of bytes read | |
2286 */ | |
789 | 2287 static int |
5367 | 2288 zfs_ioc_recv(zfs_cmd_t *zc) |
789 | 2289 { |
2290 file_t *fp; | |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2291 objset_t *os; |
5367 | 2292 dmu_recv_cookie_t drc; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2293 zfsvfs_t *zfsvfs = NULL; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2294 boolean_t force = (boolean_t)zc->zc_guid; |
789 | 2295 int error, fd; |
5367 | 2296 offset_t off; |
2297 nvlist_t *props = NULL; | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2298 nvlist_t *origprops = NULL; |
5367 | 2299 objset_t *origin = NULL; |
2300 char *tosnap; | |
2301 char tofs[ZFS_MAXNAMELEN]; | |
789 | 2302 |
3265
967e0fca6143
6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents:
3087
diff
changeset
|
2303 if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 || |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2304 strchr(zc->zc_value, '@') == NULL || |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2305 strchr(zc->zc_value, '%')) |
3265
967e0fca6143
6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents:
3087
diff
changeset
|
2306 return (EINVAL); |
967e0fca6143
6463140 zfs recv with a snapshot name that has 2 @@ in a row succeeds
ahrens
parents:
3087
diff
changeset
|
2307 |
5367 | 2308 (void) strcpy(tofs, zc->zc_value); |
2309 tosnap = strchr(tofs, '@'); | |
2310 *tosnap = '\0'; | |
2311 tosnap++; | |
2312 | |
2313 if (zc->zc_nvlist_src != NULL && | |
2314 (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size, | |
2315 &props)) != 0) | |
2316 return (error); | |
2317 | |
789 | 2318 fd = zc->zc_cookie; |
2319 fp = getf(fd); | |
5367 | 2320 if (fp == NULL) { |
2321 nvlist_free(props); | |
789 | 2322 return (EBADF); |
5367 | 2323 } |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2324 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2325 if (dmu_objset_open(tofs, DMU_OST_ANY, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2326 DS_MODE_USER | DS_MODE_READONLY, &os) == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2327 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2328 * Try to get the zfsvfs for the receiving objset. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2329 * There won't be one if we're operating on a zvol, |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2330 * if the objset doesn't exist yet, or is not mounted. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2331 */ |
5446 | 2332 mutex_enter(&os->os->os_user_ptr_lock); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2333 if (zfsvfs = dmu_objset_get_user(os)) { |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2334 if (!mutex_tryenter(&zfsvfs->z_online_recv_lock)) { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2335 mutex_exit(&os->os->os_user_ptr_lock); |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2336 dmu_objset_close(os); |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2337 zfsvfs = NULL; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2338 error = EBUSY; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2339 goto out; |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2340 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2341 VFS_HOLD(zfsvfs->z_vfs); |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2342 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2343 mutex_exit(&os->os->os_user_ptr_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2344 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2345 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2346 * If new properties are supplied, they are to completely |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2347 * replace the existing ones, so stash away the existing ones. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2348 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2349 if (props) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2350 (void) dsl_prop_get_all(os, &origprops, TRUE); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2351 |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2352 dmu_objset_close(os); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2353 } |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2354 |
5367 | 2355 if (zc->zc_string[0]) { |
2356 error = dmu_objset_open(zc->zc_string, DMU_OST_ANY, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2357 DS_MODE_USER | DS_MODE_READONLY, &origin); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2358 if (error) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2359 goto out; |
5367 | 2360 } |
2361 | |
2362 error = dmu_recv_begin(tofs, tosnap, &zc->zc_begin_record, | |
2363 force, origin, zfsvfs != NULL, &drc); | |
2364 if (origin) | |
2365 dmu_objset_close(origin); | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2366 if (error) |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2367 goto out; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2368 |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2369 /* |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2370 * Reset properties. We do this before we receive the stream |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2371 * so that the properties are applied to the new data. |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2372 */ |
5367 | 2373 if (props) { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2374 clear_props(tofs, origprops); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2375 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2376 * XXX - Note, this is all-or-nothing; should be best-effort. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2377 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2378 (void) zfs_set_prop_nvlist(tofs, props); |
5367 | 2379 } |
2380 | |
2381 off = fp->f_offset; | |
2382 error = dmu_recv_stream(&drc, fp->f_vnode, &off); | |
2383 | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2384 if (error == 0 && zfsvfs) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2385 char osname[MAXNAMELEN]; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2386 int mode; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2387 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2388 /* online recv */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2389 error = zfs_suspend_fs(zfsvfs, osname, &mode); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2390 if (error == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2391 int resume_err; |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2392 |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2393 error = dmu_recv_end(&drc); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2394 resume_err = zfs_resume_fs(zfsvfs, osname, mode); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2395 error = error ? error : resume_err; |
5367 | 2396 } else { |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2397 dmu_recv_abort_cleanup(&drc); |
5367 | 2398 } |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2399 } else if (error == 0) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2400 error = dmu_recv_end(&drc); |
6083
23e77aa611b1
6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents:
5977
diff
changeset
|
2401 } |
5367 | 2402 |
2403 zc->zc_cookie = off - fp->f_offset; | |
2404 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) | |
2405 fp->f_offset = off; | |
2885 | 2406 |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2407 /* |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2408 * On error, restore the original props. |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2409 */ |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2410 if (error && props) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2411 clear_props(tofs, props); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2412 (void) zfs_set_prop_nvlist(tofs, origprops); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2413 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2414 out: |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2415 if (zfsvfs) { |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2416 mutex_exit(&zfsvfs->z_online_recv_lock); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2417 VFS_RELE(zfsvfs->z_vfs); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2418 } |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2419 nvlist_free(props); |
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2420 nvlist_free(origprops); |
789 | 2421 releasef(fd); |
2422 return (error); | |
2423 } | |
2424 | |
5367 | 2425 /* |
2426 * inputs: | |
2427 * zc_name name of snapshot to send | |
2428 * zc_value short name of incremental fromsnap (may be empty) | |
2429 * zc_cookie file descriptor to send stream to | |
2430 * zc_obj fromorigin flag (mutually exclusive with zc_value) | |
2431 * | |
2432 * outputs: none | |
2433 */ | |
789 | 2434 static int |
5367 | 2435 zfs_ioc_send(zfs_cmd_t *zc) |
789 | 2436 { |
2437 objset_t *fromsnap = NULL; | |
2438 objset_t *tosnap; | |
2439 file_t *fp; | |
2440 int error; | |
5367 | 2441 offset_t off; |
789 | 2442 |
2443 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2444 DS_MODE_USER | DS_MODE_READONLY, &tosnap); |
789 | 2445 if (error) |
2446 return (error); | |
2447 | |
2676 | 2448 if (zc->zc_value[0] != '\0') { |
2885 | 2449 char buf[MAXPATHLEN]; |
2450 char *cp; | |
2451 | |
2452 (void) strncpy(buf, zc->zc_name, sizeof (buf)); | |
2453 cp = strchr(buf, '@'); | |
2454 if (cp) | |
2455 *(cp+1) = 0; | |
2456 (void) strncat(buf, zc->zc_value, sizeof (buf)); | |
2457 error = dmu_objset_open(buf, DMU_OST_ANY, | |
6689
47572a2f5e73
6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents:
6643
diff
changeset
|
2458 DS_MODE_USER | DS_MODE_READONLY, &fromsnap); |
789 | 2459 if (error) { |
2460 dmu_objset_close(tosnap); | |
2461 return (error); | |
2462 } | |
2463 } | |
2464 | |
2465 fp = getf(zc->zc_cookie); | |
2466 if (fp == NULL) { | |
2467 dmu_objset_close(tosnap); | |
2468 if (fromsnap) | |
2469 dmu_objset_close(fromsnap); | |
2470 return (EBADF); | |
2471 } | |
2472 | |
5367 | 2473 off = fp->f_offset; |
2474 error = dmu_sendbackup(tosnap, fromsnap, zc->zc_obj, fp->f_vnode, &off); | |
2475 | |
2476 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0) | |
2477 fp->f_offset = off; | |
789 | 2478 releasef(zc->zc_cookie); |
2479 if (fromsnap) | |
2480 dmu_objset_close(fromsnap); | |
2481 dmu_objset_close(tosnap); | |
2482 return (error); | |
2483 } | |
2484 | |
1544 | 2485 static int |
2486 zfs_ioc_inject_fault(zfs_cmd_t *zc) | |
2487 { | |
2488 int id, error; | |
2489 | |
2490 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id, | |
2491 &zc->zc_inject_record); | |
2492 | |
2493 if (error == 0) | |
2494 zc->zc_guid = (uint64_t)id; | |
2495 | |
2496 return (error); | |
2497 } | |
2498 | |
2499 static int | |
2500 zfs_ioc_clear_fault(zfs_cmd_t *zc) | |
2501 { | |
2502 return (zio_clear_fault((int)zc->zc_guid)); | |
2503 } | |
2504 | |
2505 static int | |
2506 zfs_ioc_inject_list_next(zfs_cmd_t *zc) | |
2507 { | |
2508 int id = (int)zc->zc_guid; | |
2509 int error; | |
2510 | |
2511 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name), | |
2512 &zc->zc_inject_record); | |
2513 | |
2514 zc->zc_guid = id; | |
2515 | |
2516 return (error); | |
2517 } | |
2518 | |
2519 static int | |
2520 zfs_ioc_error_log(zfs_cmd_t *zc) | |
2521 { | |
2522 spa_t *spa; | |
2523 int error; | |
2676 | 2524 size_t count = (size_t)zc->zc_nvlist_dst_size; |
1544 | 2525 |
2526 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) | |
2527 return (error); | |
2528 | |
2676 | 2529 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst, |
1544 | 2530 &count); |
2531 if (error == 0) | |
2676 | 2532 zc->zc_nvlist_dst_size = count; |
1544 | 2533 else |
2676 | 2534 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa); |
1544 | 2535 |
2536 spa_close(spa, FTAG); | |
2537 | |
2538 return (error); | |
2539 } | |
2540 | |
2541 static int | |
2542 zfs_ioc_clear(zfs_cmd_t *zc) | |
2543 { | |
2544 spa_t *spa; | |
2545 vdev_t *vd; | |
4808 | 2546 uint64_t txg; |
1544 | 2547 int error; |
2548 | |
2549 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) | |
2550 return (error); | |
2551 | |
5329 | 2552 /* |
2553 * Try to resume any I/Os which may have been suspended | |
2554 * as a result of a complete pool failure. | |
2555 */ | |
2556 if (!list_is_empty(&spa->spa_zio_list)) { | |
2557 if (zio_vdev_resume_io(spa) != 0) { | |
2558 spa_close(spa, FTAG); | |
2559 return (EIO); | |
2560 } | |
2561 } | |
2562 | |
4451 | 2563 txg = spa_vdev_enter(spa); |
1544 | 2564 |
2676 | 2565 if (zc->zc_guid == 0) { |
1544 | 2566 vd = NULL; |
6643
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6492
diff
changeset
|
2567 } else { |
3a34b0dbb107
6625086 changing cachefile doesn't remove old cache on last user
eschrock
parents:
6492
diff
changeset
|
2568 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE); |
5450 | 2569 if (vd == NULL) { |
2570 (void) spa_vdev_exit(spa, NULL, txg, ENODEV); | |
2571 spa_close(spa, FTAG); | |
2572 return (ENODEV); | |
2573 } | |
1544 | 2574 } |
2575 | |
5329 | 2576 vdev_clear(spa, vd, B_TRUE); |
1544 | 2577 |
4451 | 2578 (void) spa_vdev_exit(spa, NULL, txg, 0); |
1544 | 2579 |
2580 spa_close(spa, FTAG); | |
2581 | |
2582 return (0); | |
2583 } | |
2584 | |
5367 | 2585 /* |
2586 * inputs: | |
2587 * zc_name name of filesystem | |
2588 * zc_value name of origin snapshot | |
2589 * | |
2590 * outputs: none | |
2591 */ | |
1544 | 2592 static int |
2082 | 2593 zfs_ioc_promote(zfs_cmd_t *zc) |
2594 { | |
2417 | 2595 char *cp; |
2596 | |
2597 /* | |
2598 * We don't need to unmount *all* the origin fs's snapshots, but | |
2599 * it's easier. | |
2600 */ | |
2676 | 2601 cp = strchr(zc->zc_value, '@'); |
2417 | 2602 if (cp) |
2603 *cp = '\0'; | |
2676 | 2604 (void) dmu_objset_find(zc->zc_value, |
2417 | 2605 zfs_unmount_snap, NULL, DS_FIND_SNAPSHOTS); |
2082 | 2606 return (dsl_dataset_promote(zc->zc_name)); |
2607 } | |
2608 | |
4543 | 2609 /* |
2610 * We don't want to have a hard dependency | |
2611 * against some special symbols in sharefs | |
5331 | 2612 * nfs, and smbsrv. Determine them if needed when |
4543 | 2613 * the first file system is shared. |
5331 | 2614 * Neither sharefs, nfs or smbsrv are unloadable modules. |
4543 | 2615 */ |
5331 | 2616 int (*znfsexport_fs)(void *arg); |
4543 | 2617 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t); |
5331 | 2618 int (*zsmbexport_fs)(void *arg, boolean_t add_share); |
2619 | |
2620 int zfs_nfsshare_inited; | |
2621 int zfs_smbshare_inited; | |
2622 | |
4543 | 2623 ddi_modhandle_t nfs_mod; |
2624 ddi_modhandle_t sharefs_mod; | |
5331 | 2625 ddi_modhandle_t smbsrv_mod; |
4543 | 2626 kmutex_t zfs_share_lock; |
2627 | |
2628 static int | |
5331 | 2629 zfs_init_sharefs() |
2630 { | |
2631 int error; | |
2632 | |
2633 ASSERT(MUTEX_HELD(&zfs_share_lock)); | |
2634 /* Both NFS and SMB shares also require sharetab support. */ | |
2635 if (sharefs_mod == NULL && ((sharefs_mod = | |
2636 ddi_modopen("fs/sharefs", | |
2637 KRTLD_MODE_FIRST, &error)) == NULL)) { | |
2638 return (ENOSYS); | |
2639 } | |
2640 if (zshare_fs == NULL && ((zshare_fs = | |
2641 (int (*)(enum sharefs_sys_op, share_t *, uint32_t)) | |
2642 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) { | |
2643 return (ENOSYS); | |
2644 } | |
2645 return (0); | |
2646 } | |
2647 | |
2648 static int | |
4543 | 2649 zfs_ioc_share(zfs_cmd_t *zc) |
2650 { | |
2651 int error; | |
2652 int opcode; | |
2653 | |
5331 | 2654 switch (zc->zc_share.z_sharetype) { |
2655 case ZFS_SHARE_NFS: | |
2656 case ZFS_UNSHARE_NFS: | |
2657 if (zfs_nfsshare_inited == 0) { | |
2658 mutex_enter(&zfs_share_lock); | |
2659 if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs", | |
2660 KRTLD_MODE_FIRST, &error)) == NULL)) { | |
2661 mutex_exit(&zfs_share_lock); | |
2662 return (ENOSYS); | |
2663 } | |
2664 if (znfsexport_fs == NULL && | |
2665 ((znfsexport_fs = (int (*)(void *)) | |
2666 ddi_modsym(nfs_mod, | |
2667 "nfs_export", &error)) == NULL)) { | |
2668 mutex_exit(&zfs_share_lock); | |
2669 return (ENOSYS); | |
2670 } | |
2671 error = zfs_init_sharefs(); | |
2672 if (error) { | |
2673 mutex_exit(&zfs_share_lock); | |
2674 return (ENOSYS); | |
2675 } | |
2676 zfs_nfsshare_inited = 1; | |
4543 | 2677 mutex_exit(&zfs_share_lock); |
2678 } | |
5331 | 2679 break; |
2680 case ZFS_SHARE_SMB: | |
2681 case ZFS_UNSHARE_SMB: | |
2682 if (zfs_smbshare_inited == 0) { | |
2683 mutex_enter(&zfs_share_lock); | |
2684 if (smbsrv_mod == NULL && ((smbsrv_mod = | |
2685 ddi_modopen("drv/smbsrv", | |
2686 KRTLD_MODE_FIRST, &error)) == NULL)) { | |
2687 mutex_exit(&zfs_share_lock); | |
2688 return (ENOSYS); | |
2689 } | |
2690 if (zsmbexport_fs == NULL && ((zsmbexport_fs = | |
2691 (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod, | |
6139
5c743b207bf9
6541120 Configuration is not propagated to SMB kernel module
jb150015
parents:
6083
diff
changeset
|
2692 "smb_server_share", &error)) == NULL)) { |
5331 | 2693 mutex_exit(&zfs_share_lock); |
2694 return (ENOSYS); | |
2695 } | |
2696 error = zfs_init_sharefs(); | |
2697 if (error) { | |
2698 mutex_exit(&zfs_share_lock); | |
2699 return (ENOSYS); | |
2700 } | |
2701 zfs_smbshare_inited = 1; | |
4543 | 2702 mutex_exit(&zfs_share_lock); |
2703 } | |
5331 | 2704 break; |
2705 default: | |
2706 return (EINVAL); | |
4543 | 2707 } |
2708 | |
5331 | 2709 switch (zc->zc_share.z_sharetype) { |
2710 case ZFS_SHARE_NFS: | |
2711 case ZFS_UNSHARE_NFS: | |
2712 if (error = | |
2713 znfsexport_fs((void *) | |
2714 (uintptr_t)zc->zc_share.z_exportdata)) | |
2715 return (error); | |
2716 break; | |
2717 case ZFS_SHARE_SMB: | |
2718 case ZFS_UNSHARE_SMB: | |
2719 if (error = zsmbexport_fs((void *) | |
2720 (uintptr_t)zc->zc_share.z_exportdata, | |
2721 zc->zc_share.z_sharetype == ZFS_SHARE_SMB ? | |
2722 B_TRUE : B_FALSE)) { | |
2723 return (error); | |
2724 } | |
2725 break; | |
2726 } | |
2727 | |
2728 opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS || | |
2729 zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ? | |
4543 | 2730 SHAREFS_ADD : SHAREFS_REMOVE; |
2731 | |
5331 | 2732 /* |
2733 * Add or remove share from sharetab | |
2734 */ | |
4543 | 2735 error = zshare_fs(opcode, |
2736 (void *)(uintptr_t)zc->zc_share.z_sharedata, | |
2737 zc->zc_share.z_sharemax); | |
2738 | |
2739 return (error); | |
2740 | |
2741 } | |
2742 | |
2743 /* | |
4988
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
2744 * pool create, destroy, and export don't log the history as part of |
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
2745 * zfsdev_ioctl, but rather zfs_ioc_pool_create, and zfs_ioc_pool_export |
db8abd9846d4
6595467 libzfs consumers should be allowed to write their own history (or none at all)
ek110237
parents:
4849
diff
changeset
|
2746 * do the logging of those commands. |
4543 | 2747 */ |
789 | 2748 static zfs_ioc_vec_t zfs_ioc_vec[] = { |
4715
e8d212dda064
6535695 Panic: shpp->sh_eof == shpp->sh_pool_create_len, file: ../../common/fs/zfs/spa_history.c, line: 235
ek110237
parents:
4670
diff
changeset
|
2749 { zfs_ioc_pool_create, zfs_secpolicy_config, POOL_NAME, B_FALSE }, |
4577 | 2750 { zfs_ioc_pool_destroy, zfs_secpolicy_config, POOL_NAME, B_FALSE }, |
2751 { zfs_ioc_pool_import, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2752 { zfs_ioc_pool_export, zfs_secpolicy_config, POOL_NAME, B_FALSE }, | |
2753 { zfs_ioc_pool_configs, zfs_secpolicy_none, NO_NAME, B_FALSE }, | |
2754 { zfs_ioc_pool_stats, zfs_secpolicy_read, POOL_NAME, B_FALSE }, | |
2755 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, NO_NAME, B_FALSE }, | |
2756 { zfs_ioc_pool_scrub, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2757 { zfs_ioc_pool_freeze, zfs_secpolicy_config, NO_NAME, B_FALSE }, | |
2758 { zfs_ioc_pool_upgrade, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2759 { zfs_ioc_pool_get_history, zfs_secpolicy_config, POOL_NAME, B_FALSE }, | |
2760 { zfs_ioc_vdev_add, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2761 { zfs_ioc_vdev_remove, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2762 { zfs_ioc_vdev_set_state, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2763 { zfs_ioc_vdev_attach, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2764 { zfs_ioc_vdev_detach, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2765 { zfs_ioc_vdev_setpath, zfs_secpolicy_config, POOL_NAME, B_FALSE }, | |
2766 { zfs_ioc_objset_stats, zfs_secpolicy_read, DATASET_NAME, B_FALSE }, | |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5450
diff
changeset
|
2767 { zfs_ioc_objset_zplprops, zfs_secpolicy_read, DATASET_NAME, B_FALSE }, |
4543 | 2768 { zfs_ioc_dataset_list_next, zfs_secpolicy_read, |
4577 | 2769 DATASET_NAME, B_FALSE }, |
4543 | 2770 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, |
4577 | 2771 DATASET_NAME, B_FALSE }, |
2772 { zfs_ioc_set_prop, zfs_secpolicy_none, DATASET_NAME, B_TRUE }, | |
2773 { zfs_ioc_create_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE }, | |
2774 { zfs_ioc_remove_minor, zfs_secpolicy_minor, DATASET_NAME, B_FALSE }, | |
2775 { zfs_ioc_create, zfs_secpolicy_create, DATASET_NAME, B_TRUE }, | |
2776 { zfs_ioc_destroy, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE }, | |
2777 { zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME, B_TRUE }, | |
2778 { zfs_ioc_rename, zfs_secpolicy_rename, DATASET_NAME, B_TRUE }, | |
5367 | 2779 { zfs_ioc_recv, zfs_secpolicy_receive, DATASET_NAME, B_TRUE }, |
2780 { zfs_ioc_send, zfs_secpolicy_send, DATASET_NAME, B_TRUE }, | |
4577 | 2781 { zfs_ioc_inject_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE }, |
2782 { zfs_ioc_clear_fault, zfs_secpolicy_inject, NO_NAME, B_FALSE }, | |
2783 { zfs_ioc_inject_list_next, zfs_secpolicy_inject, NO_NAME, B_FALSE }, | |
2784 { zfs_ioc_error_log, zfs_secpolicy_inject, POOL_NAME, B_FALSE }, | |
2785 { zfs_ioc_clear, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2786 { zfs_ioc_promote, zfs_secpolicy_promote, DATASET_NAME, B_TRUE }, | |
2787 { zfs_ioc_destroy_snaps, zfs_secpolicy_destroy, DATASET_NAME, B_TRUE }, | |
2788 { zfs_ioc_snapshot, zfs_secpolicy_snapshot, DATASET_NAME, B_TRUE }, | |
2789 { zfs_ioc_dsobj_to_dsname, zfs_secpolicy_config, POOL_NAME, B_FALSE }, | |
2790 { zfs_ioc_obj_to_path, zfs_secpolicy_config, NO_NAME, B_FALSE }, | |
2791 { zfs_ioc_pool_set_props, zfs_secpolicy_config, POOL_NAME, B_TRUE }, | |
2792 { zfs_ioc_pool_get_props, zfs_secpolicy_read, POOL_NAME, B_FALSE }, | |
2793 { zfs_ioc_set_fsacl, zfs_secpolicy_fsacl, DATASET_NAME, B_TRUE }, | |
2794 { zfs_ioc_get_fsacl, zfs_secpolicy_read, DATASET_NAME, B_FALSE }, | |
4543 | 2795 { zfs_ioc_iscsi_perm_check, zfs_secpolicy_iscsi, |
4577 | 2796 DATASET_NAME, B_FALSE }, |
4849
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
2797 { zfs_ioc_share, zfs_secpolicy_share, DATASET_NAME, B_FALSE }, |
3a61e0a9a953
6536043 arc_byteswap_func_t and dmu_byteswap_func_t are redundant
ahrens
parents:
4808
diff
changeset
|
2798 { zfs_ioc_inherit_prop, zfs_secpolicy_inherit, DATASET_NAME, B_TRUE }, |
789 | 2799 }; |
2800 | |
2801 static int | |
2802 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp) | |
2803 { | |
2804 zfs_cmd_t *zc; | |
2805 uint_t vec; | |
2199 | 2806 int error, rc; |
789 | 2807 |
2808 if (getminor(dev) != 0) | |
2809 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp)); | |
2810 | |
2811 vec = cmd - ZFS_IOC; | |
4787 | 2812 ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip)); |
789 | 2813 |
2814 if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0])) | |
2815 return (EINVAL); | |
2816 | |
2817 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); | |
2818 | |
2819 error = xcopyin((void *)arg, zc, sizeof (zfs_cmd_t)); | |
2820 | |
4787 | 2821 if (error == 0) |
4543 | 2822 error = zfs_ioc_vec[vec].zvec_secpolicy(zc, cr); |
789 | 2823 |
2824 /* | |
2825 * Ensure that all pool/dataset names are valid before we pass down to | |
2826 * the lower layers. | |
2827 */ | |
2828 if (error == 0) { | |
2829 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0'; | |
2830 switch (zfs_ioc_vec[vec].zvec_namecheck) { | |
4577 | 2831 case POOL_NAME: |
789 | 2832 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0) |
2833 error = EINVAL; | |
2834 break; | |
2835 | |
4577 | 2836 case DATASET_NAME: |
789 | 2837 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0) |
2838 error = EINVAL; | |
2839 break; | |
2856 | 2840 |
4577 | 2841 case NO_NAME: |
2856 | 2842 break; |
789 | 2843 } |
2844 } | |
2845 | |
2846 if (error == 0) | |
2847 error = zfs_ioc_vec[vec].zvec_func(zc); | |
2848 | |
2199 | 2849 rc = xcopyout(zc, (void *)arg, sizeof (zfs_cmd_t)); |
4543 | 2850 if (error == 0) { |
2199 | 2851 error = rc; |
4543 | 2852 if (zfs_ioc_vec[vec].zvec_his_log == B_TRUE) |
2853 zfs_log_history(zc); | |
2854 } | |
789 | 2855 |
2856 kmem_free(zc, sizeof (zfs_cmd_t)); | |
2857 return (error); | |
2858 } | |
2859 | |
2860 static int | |
2861 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) | |
2862 { | |
2863 if (cmd != DDI_ATTACH) | |
2864 return (DDI_FAILURE); | |
2865 | |
2866 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0, | |
2867 DDI_PSEUDO, 0) == DDI_FAILURE) | |
2868 return (DDI_FAILURE); | |
2869 | |
2870 zfs_dip = dip; | |
2871 | |
2872 ddi_report_dev(dip); | |
2873 | |
2874 return (DDI_SUCCESS); | |
2875 } | |
2876 | |
2877 static int | |
2878 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) | |
2879 { | |
2880 if (spa_busy() || zfs_busy() || zvol_busy()) | |
2881 return (DDI_FAILURE); | |
2882 | |
2883 if (cmd != DDI_DETACH) | |
2884 return (DDI_FAILURE); | |
2885 | |
2886 zfs_dip = NULL; | |
2887 | |
2888 ddi_prop_remove_all(dip); | |
2889 ddi_remove_minor_node(dip, NULL); | |
2890 | |
2891 return (DDI_SUCCESS); | |
2892 } | |
2893 | |
2894 /*ARGSUSED*/ | |
2895 static int | |
2896 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) | |
2897 { | |
2898 switch (infocmd) { | |
2899 case DDI_INFO_DEVT2DEVINFO: | |
2900 *result = zfs_dip; | |
2901 return (DDI_SUCCESS); | |
2902 | |
2903 case DDI_INFO_DEVT2INSTANCE: | |
849
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2904 *result = (void *)0; |
789 | 2905 return (DDI_SUCCESS); |
2906 } | |
2907 | |
2908 return (DDI_FAILURE); | |
2909 } | |
2910 | |
2911 /* | |
2912 * OK, so this is a little weird. | |
2913 * | |
2914 * /dev/zfs is the control node, i.e. minor 0. | |
2915 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0. | |
2916 * | |
2917 * /dev/zfs has basically nothing to do except serve up ioctls, | |
2918 * so most of the standard driver entry points are in zvol.c. | |
2919 */ | |
2920 static struct cb_ops zfs_cb_ops = { | |
2921 zvol_open, /* open */ | |
2922 zvol_close, /* close */ | |
2923 zvol_strategy, /* strategy */ | |
2924 nodev, /* print */ | |
6423 | 2925 zvol_dump, /* dump */ |
789 | 2926 zvol_read, /* read */ |
2927 zvol_write, /* write */ | |
2928 zfsdev_ioctl, /* ioctl */ | |
2929 nodev, /* devmap */ | |
2930 nodev, /* mmap */ | |
2931 nodev, /* segmap */ | |
2932 nochpoll, /* poll */ | |
2933 ddi_prop_op, /* prop_op */ | |
2934 NULL, /* streamtab */ | |
2935 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */ | |
2936 CB_REV, /* version */ | |
3638
6b28ebc717aa
6496357 spec_fsync() is useless on devices that do write caching
billm
parents:
3444
diff
changeset
|
2937 nodev, /* async read */ |
6b28ebc717aa
6496357 spec_fsync() is useless on devices that do write caching
billm
parents:
3444
diff
changeset
|
2938 nodev, /* async write */ |
789 | 2939 }; |
2940 | |
2941 static struct dev_ops zfs_dev_ops = { | |
2942 DEVO_REV, /* version */ | |
2943 0, /* refcnt */ | |
2944 zfs_info, /* info */ | |
2945 nulldev, /* identify */ | |
2946 nulldev, /* probe */ | |
2947 zfs_attach, /* attach */ | |
2948 zfs_detach, /* detach */ | |
2949 nodev, /* reset */ | |
2950 &zfs_cb_ops, /* driver operations */ | |
2951 NULL /* no bus operations */ | |
2952 }; | |
2953 | |
2954 static struct modldrv zfs_modldrv = { | |
4577 | 2955 &mod_driverops, "ZFS storage pool version " SPA_VERSION_STRING, |
2676 | 2956 &zfs_dev_ops |
789 | 2957 }; |
2958 | |
2959 static struct modlinkage modlinkage = { | |
2960 MODREV_1, | |
2961 (void *)&zfs_modlfs, | |
2962 (void *)&zfs_modldrv, | |
2963 NULL | |
2964 }; | |
2965 | |
4720
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
2966 |
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
2967 uint_t zfs_fsyncer_key; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2968 extern uint_t rrw_tsd_key; |
4720
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
2969 |
789 | 2970 int |
2971 _init(void) | |
2972 { | |
2973 int error; | |
2974 | |
849
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2975 spa_init(FREAD | FWRITE); |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2976 zfs_init(); |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2977 zvol_init(); |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2978 |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2979 if ((error = mod_install(&modlinkage)) != 0) { |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2980 zvol_fini(); |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2981 zfs_fini(); |
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2982 spa_fini(); |
789 | 2983 return (error); |
849
8d799fd81a9b
6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents:
789
diff
changeset
|
2984 } |
789 | 2985 |
4720
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
2986 tsd_create(&zfs_fsyncer_key, NULL); |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
5147
diff
changeset
|
2987 tsd_create(&rrw_tsd_key, NULL); |
4720
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
2988 |
789 | 2989 error = ldi_ident_from_mod(&modlinkage, &zfs_li); |
2990 ASSERT(error == 0); | |
4543 | 2991 mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL); |
789 | 2992 |
2993 return (0); | |
2994 } | |
2995 | |
2996 int | |
2997 _fini(void) | |
2998 { | |
2999 int error; | |
3000 | |
1544 | 3001 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled) |
789 | 3002 return (EBUSY); |
3003 | |
3004 if ((error = mod_remove(&modlinkage)) != 0) | |
3005 return (error); | |
3006 | |
3007 zvol_fini(); | |
3008 zfs_fini(); | |
3009 spa_fini(); | |
5331 | 3010 if (zfs_nfsshare_inited) |
4543 | 3011 (void) ddi_modclose(nfs_mod); |
5331 | 3012 if (zfs_smbshare_inited) |
3013 (void) ddi_modclose(smbsrv_mod); | |
3014 if (zfs_nfsshare_inited || zfs_smbshare_inited) | |
4543 | 3015 (void) ddi_modclose(sharefs_mod); |
789 | 3016 |
4720
8edc0d2e6f3f
6535160 Lock contention on zl_lock from zil_commit
fr157268
parents:
4715
diff
changeset
|
3017 tsd_destroy(&zfs_fsyncer_key); |
789 | 3018 ldi_ident_release(zfs_li); |
3019 zfs_li = NULL; | |
4543 | 3020 mutex_destroy(&zfs_share_lock); |
789 | 3021 |
3022 return (error); | |
3023 } | |
3024 | |
3025 int | |
3026 _info(struct modinfo *modinfop) | |
3027 { | |
3028 return (mod_info(&modlinkage, modinfop)); | |
3029 } |