annotate usr/src/uts/common/fs/zfs/zfs_ioctl.c @ 1133:335d069294d1

6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code 6360844 zvol has an incorrect efi_version in it's EFI label. 6361271 volsize & reservation not consistent while volume size < 128k
author eschrock
date Thu, 15 Dec 2005 18:34:13 -0800
parents ce99098d6a9b
children 81359ee1ee63
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
2 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
3 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
4 * The contents of this file are subject to the terms of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
5 * Common Development and Distribution License, Version 1.0 only
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
6 * (the "License"). You may not use this file except in compliance
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
7 * with the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
8 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
10 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
11 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
12 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
13 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
14 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
16 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
17 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
18 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
19 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
20 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
21 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
22 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
24 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
25 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
27 #pragma ident "%Z%%M% %I% %E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
29 #include <sys/types.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
30 #include <sys/param.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
31 #include <sys/errno.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
32 #include <sys/uio.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
33 #include <sys/buf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
34 #include <sys/modctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
35 #include <sys/open.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
36 #include <sys/file.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
37 #include <sys/kmem.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
38 #include <sys/conf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
39 #include <sys/cmn_err.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
40 #include <sys/stat.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
41 #include <sys/zfs_ioctl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
42 #include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
43 #include <sys/spa.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
44 #include <sys/vdev.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
45 #include <sys/dmu.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
46 #include <sys/dsl_dir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
47 #include <sys/dsl_dataset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
48 #include <sys/dsl_prop.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
49 #include <sys/ddi.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
50 #include <sys/sunddi.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
51 #include <sys/sunldi.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
52 #include <sys/policy.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
53 #include <sys/zone.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
54 #include <sys/nvpair.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
55 #include <sys/pathname.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
56 #include <sys/mount.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
57 #include <sys/sdt.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
58 #include <sys/fs/zfs.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
59 #include <sys/zfs_ctldir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
60
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
61 #include "zfs_namecheck.h"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
62
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
63 extern struct modlfs zfs_modlfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
64
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
65 extern void zfs_init(void);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
66 extern void zfs_fini(void);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
67
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
68 ldi_ident_t zfs_li = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
69 dev_info_t *zfs_dip;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
70
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
71 typedef int zfs_ioc_func_t(zfs_cmd_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
72 typedef int zfs_secpolicy_func_t(const char *, const char *, cred_t *);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
73
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
74 typedef struct zfs_ioc_vec {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
75 zfs_ioc_func_t *zvec_func;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
76 zfs_secpolicy_func_t *zvec_secpolicy;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
77 enum {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
78 no_name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
79 pool_name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
80 dataset_name
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
81 } zvec_namecheck;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
82 } zfs_ioc_vec_t;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
83
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
84 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
85 void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
86 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
87 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
88 const char *newfile;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
89 char buf[256];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
90 va_list adx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
91
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
92 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
93 * Get rid of annoying "../common/" prefix to filename.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
94 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
95 newfile = strrchr(file, '/');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
96 if (newfile != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
97 newfile = newfile + 1; /* Get rid of leading / */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
98 } else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
99 newfile = file;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
100 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
101
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
102 va_start(adx, fmt);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
103 (void) vsnprintf(buf, sizeof (buf), fmt, adx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
104 va_end(adx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
106 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
107 * To get this data, use the zfs-dprintf probe as so:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
108 * dtrace -q -n 'zfs-dprintf \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
109 * /stringof(arg0) == "dbuf.c"/ \
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
110 * {printf("%s: %s", stringof(arg1), stringof(arg3))}'
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
111 * arg0 = file name
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
112 * arg1 = function name
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
113 * arg2 = line number
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
114 * arg3 = message
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
115 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
116 DTRACE_PROBE4(zfs__dprintf,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
117 char *, newfile, char *, func, int, line, char *, buf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
118 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
119
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
120 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
121 * Policy for top-level read operations (list pools). Requires no privileges,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
122 * and can be used in the local zone, as there is no associated dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
123 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
124 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
125 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
126 zfs_secpolicy_none(const char *unused1, const char *unused2, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
127 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
128 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
129 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
130
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
131 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
132 * Policy for dataset read operations (list children, get statistics). Requires
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
133 * no privileges, but must be visible in the local zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
134 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
135 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
136 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
137 zfs_secpolicy_read(const char *dataset, const char *unused, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
138 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
139 if (INGLOBALZONE(curproc) ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
140 zone_dataset_visible(dataset, NULL))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
141 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
142
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
143 return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
144 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
145
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
146 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
147 zfs_dozonecheck(const char *dataset, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
148 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
149 uint64_t zoned;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
150 int writable = 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
151
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
152 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
153 * The dataset must be visible by this zone -- check this first
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
154 * so they don't see EPERM on something they shouldn't know about.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
155 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
156 if (!INGLOBALZONE(curproc) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
157 !zone_dataset_visible(dataset, &writable))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
158 return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
159
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
160 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
161 return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
162
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
163 if (INGLOBALZONE(curproc)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
164 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
165 * If the fs is zoned, only root can access it from the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
166 * global zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
167 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
168 if (secpolicy_zfs(cr) && zoned)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
169 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
170 } else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
171 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
172 * If we are in a local zone, the 'zoned' property must be set.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
173 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
174 if (!zoned)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
175 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
176
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
177 /* must be writable by this zone */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
178 if (!writable)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
179 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
180 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
181 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
182 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
183
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
184 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
185 * Policy for dataset write operations (create children, set properties, etc).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
186 * Requires SYS_MOUNT privilege, and must be writable in the local zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
187 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
188 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
189 int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
190 zfs_secpolicy_write(const char *dataset, const char *unused, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
191 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
192 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
193
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
194 if (error = zfs_dozonecheck(dataset, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
195 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
196
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
197 return (secpolicy_zfs(cr));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
198 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
199
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
200 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
201 * Policy for operations that want to write a dataset's parent:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
202 * create, destroy, snapshot, clone, restore.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
203 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
204 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
205 zfs_secpolicy_parent(const char *dataset, const char *unused, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
206 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
207 char parentname[MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
208 char *cp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
209
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
210 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
211 * Remove the @bla or /bla from the end of the name to get the parent.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
212 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
213 (void) strncpy(parentname, dataset, sizeof (parentname));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
214 cp = strrchr(parentname, '@');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
215 if (cp != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
216 cp[0] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
217 } else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
218 cp = strrchr(parentname, '/');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
219 if (cp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
220 return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
221 cp[0] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
222
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
223 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
224
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
225 return (zfs_secpolicy_write(parentname, unused, cr));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
226 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
227
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
228 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
229 * Policy for dataset write operations (create children, set properties, etc).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
230 * Requires SYS_MOUNT privilege, and must be writable in the local zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
231 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
232 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
233 zfs_secpolicy_setprop(const char *dataset, const char *prop, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
234 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
235 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
236
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
237 if (error = zfs_dozonecheck(dataset, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
238 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
239
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
240 if (strcmp(prop, "zoned") == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
241 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
242 * Disallow setting of 'zoned' from within a local zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
243 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
244 if (!INGLOBALZONE(curproc))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
245 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
246 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
247
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
248 return (secpolicy_zfs(cr));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
249 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
250
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
251 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
252 * Security policy for setting the quota. This is the same as
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
253 * zfs_secpolicy_write, except that the local zone may not change the quota at
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
254 * the zone-property setpoint.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
255 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
256 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
257 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
258 zfs_secpolicy_quota(const char *dataset, const char *unused, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
259 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
260 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
261
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
262 if (error = zfs_dozonecheck(dataset, cr))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
263 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
264
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
265 if (!INGLOBALZONE(curproc)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
266 uint64_t zoned;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
267 char setpoint[MAXNAMELEN];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
268 int dslen;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
269 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
270 * Unprivileged users are allowed to modify the quota
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
271 * on things *under* (ie. contained by) the thing they
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
272 * own.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
273 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
274 if (dsl_prop_get_integer(dataset, "zoned", &zoned, setpoint))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
275 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
276 if (!zoned) /* this shouldn't happen */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
277 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
278 dslen = strlen(dataset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
279 if (dslen <= strlen(setpoint))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
280 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
281 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
282
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
283 return (secpolicy_zfs(cr));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
284 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
285
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
286 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
287 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
288 * SYS_CONFIG privilege, which is not available in a local zone.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
289 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
290 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
291 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
292 zfs_secpolicy_config(const char *unused, const char *unused2, cred_t *cr)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
293 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
294 if (secpolicy_sys_config(cr, B_FALSE) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
295 return (EPERM);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
296
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
297 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
298 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
299
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
300 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
301 * Returns the nvlist as specified by the user in the zfs_cmd_t.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
302 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
303 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
304 get_config(zfs_cmd_t *zc, nvlist_t **nvp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
305 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
306 char *packed;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
307 size_t size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
308 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
309 nvlist_t *config = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
310
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
311 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
312 * Read in and unpack the user-supplied nvlist. By this point, we know
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
313 * that the user has the SYS_CONFIG privilege, so allocating arbitrary
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
314 * sized regions of memory should not be a problem.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
315 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
316 if ((size = zc->zc_config_src_size) == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
317 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
318
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
319 packed = kmem_alloc(size, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
320
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
321 if ((error = xcopyin((void *)(uintptr_t)zc->zc_config_src, packed,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
322 size)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
323 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
324 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
325 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
326
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
327 if ((error = nvlist_unpack(packed, size, &config, 0)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
328 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
329 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
330 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
331
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
332 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
333
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
334 *nvp = config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
335 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
336 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
337
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
338 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
339 zfs_ioc_pool_create(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
340 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
341 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
342 nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
343
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
344 if ((error = get_config(zc, &config)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
345 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
346
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
347 error = spa_create(zc->zc_name, config, zc->zc_root[0] == '\0' ?
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
348 NULL : zc->zc_root);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
349
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
350 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
351
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
352 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
353 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
354
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
355 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
356 zfs_ioc_pool_destroy(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
357 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
358 return (spa_destroy(zc->zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
359 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
360
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
361 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
362 zfs_ioc_pool_import(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
363 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
364 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
365 nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
366 uint64_t guid;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
367
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
368 if ((error = get_config(zc, &config)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
369 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
370
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
371 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
372 guid != zc->zc_pool_guid)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
373 error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
374 else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
375 error = spa_import(zc->zc_name, config,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
376 zc->zc_root[0] == '\0' ? NULL : zc->zc_root);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
377
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
378 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
379
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
380 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
381 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
382
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
383 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
384 zfs_ioc_pool_export(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
385 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
386 return (spa_export(zc->zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
387 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
388
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
389 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
390 zfs_ioc_pool_configs(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
391 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
392 nvlist_t *configs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
393 char *packed = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
394 size_t size = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
395 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
396
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
397 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
398 return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
399
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
400 VERIFY(nvlist_pack(configs, &packed, &size, NV_ENCODE_NATIVE, 0) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
401
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
402 if (size > zc->zc_config_dst_size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
403 error = ENOMEM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
404 else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
405 error = xcopyout(packed, (void *)(uintptr_t)zc->zc_config_dst,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
406 size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
407
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
408 zc->zc_config_dst_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
409
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
410 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
411 nvlist_free(configs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
412
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
413 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
414 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
415
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
416 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
417 zfs_ioc_pool_guid(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
418 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
419 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
420 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
421
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
422 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
423 if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
424 zc->zc_pool_guid = spa_guid(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
425 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
426 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
427 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
428 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
429
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
430 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
431 zfs_ioc_pool_stats(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
432 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
433 nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
434 char *packed = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
435 size_t size = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
436 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
437
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
438 error = spa_get_stats(zc->zc_name, &config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
439
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
440 if (config != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
441 VERIFY(nvlist_pack(config, &packed, &size,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
442 NV_ENCODE_NATIVE, 0) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
443
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
444 if (size > zc->zc_config_dst_size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
445 error = ENOMEM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
446 else if (xcopyout(packed, (void *)(uintptr_t)zc->zc_config_dst,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
447 size))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
448 error = EFAULT;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
449
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
450 zc->zc_config_dst_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
451
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
452 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
453 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
454 } else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
455 ASSERT(error != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
456 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
457
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
458 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
459 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
461 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
462 * Try to import the given pool, returning pool stats as appropriate so that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
463 * user land knows which devices are available and overall pool health.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
464 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
465 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
466 zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
467 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
468 nvlist_t *tryconfig, *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
469 char *packed = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
470 size_t size = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
471 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
472
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
473 if ((error = get_config(zc, &tryconfig)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
474 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
475
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
476 config = spa_tryimport(tryconfig);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
477
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
478 nvlist_free(tryconfig);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
479
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
480 if (config == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
481 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
482
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
483 VERIFY(nvlist_pack(config, &packed, &size, NV_ENCODE_NATIVE, 0) == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
485 if (size > zc->zc_config_dst_size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
486 error = ENOMEM;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
487 else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
488 error = xcopyout(packed, (void *)(uintptr_t)zc->zc_config_dst,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
489 size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
490
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
491 zc->zc_config_dst_size = size;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
492
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
493 kmem_free(packed, size);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
494 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
495
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
496 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
497 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
498
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
499 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
500 zfs_ioc_pool_scrub(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
501 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
502 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
503 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
504
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
505 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
506 if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
507 error = spa_scrub(spa, zc->zc_cookie, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
508 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
509 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
510 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
511 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
512
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
513 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
514 zfs_ioc_pool_freeze(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
515 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
516 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
517 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
518
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
519 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
520 if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
521 spa_freeze(spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
522 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
523 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
524 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
525 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
526
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
527 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
528 zfs_ioc_vdev_add(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
529 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
530 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
531 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
532 nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
533
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
534 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
535 if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
536 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
537
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
538 if ((error = get_config(zc, &config)) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
539 error = spa_vdev_add(spa, config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
540 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
541 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
542
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
543 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
544 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
545 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
546
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
547 /* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
548 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
549 zfs_ioc_vdev_remove(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
550 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
551 return (ENOTSUP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
552 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
553
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
554 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
555 zfs_ioc_vdev_online(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
556 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
557 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
558 char *path = zc->zc_prop_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
559 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
560
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
561 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
562 if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
563 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
564 error = vdev_online(spa, path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
565 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
566 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
567 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
569 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
570 zfs_ioc_vdev_offline(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
571 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
572 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
573 char *path = zc->zc_prop_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
574 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
575
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
576 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
577 if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
578 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
579 error = vdev_offline(spa, path);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
580 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
581 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
582 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
583
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
584 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
585 zfs_ioc_vdev_attach(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
586 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
587 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
588 char *path = zc->zc_prop_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
589 int replacing = zc->zc_cookie;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
590 nvlist_t *config;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
591 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
592
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
593 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
594 if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
595 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
597 if ((error = get_config(zc, &config)) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
598 error = spa_vdev_attach(spa, path, config, replacing);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
599 nvlist_free(config);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
600 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
601
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
602 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
603 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
604 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
605
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
606 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
607 zfs_ioc_vdev_detach(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
608 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
609 spa_t *spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
610 char *path = zc->zc_prop_value;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
611 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
612
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
613 error = spa_open(zc->zc_name, &spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
614 if (error != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
615 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
616
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
617 error = spa_vdev_detach(spa, path, 0, B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
618
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
619 spa_close(spa, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
620 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
621 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
622
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
623 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
624 zfs_get_stats(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
625 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
626 char *name = zc->zc_name;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
627 zfs_stats_t *zs = &zc->zc_zfs_stats;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
628 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
629
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
630 bzero(zs, sizeof (zfs_stats_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
631
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
632 if ((error = dsl_prop_get_integer(name, "atime",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
633 &zs->zs_atime, zs->zs_atime_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
634 (error = dsl_prop_get_integer(name, "recordsize",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
635 &zs->zs_recordsize, zs->zs_recordsize_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
636 (error = dsl_prop_get_integer(name, "readonly",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
637 &zs->zs_readonly, zs->zs_readonly_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
638 (error = dsl_prop_get_integer(name, "devices",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
639 &zs->zs_devices, zs->zs_devices_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
640 (error = dsl_prop_get_integer(name, "setuid",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
641 &zs->zs_setuid, zs->zs_setuid_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
642 (error = dsl_prop_get_integer(name, "exec",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
643 &zs->zs_exec, zs->zs_exec_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
644 (error = dsl_prop_get_string(name, "mountpoint", zs->zs_mountpoint,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
645 sizeof (zs->zs_mountpoint), zs->zs_mountpoint_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
646 (error = dsl_prop_get_string(name, "sharenfs", zs->zs_sharenfs,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
647 sizeof (zs->zs_sharenfs), zs->zs_sharenfs_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
648 (error = dsl_prop_get_integer(name, "aclmode",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
649 &zs->zs_acl_mode, zs->zs_acl_mode_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
650 (error = dsl_prop_get_integer(name, "snapdir",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
651 &zs->zs_snapdir, zs->zs_snapdir_setpoint)) != 0 ||
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
652 (error = dsl_prop_get_integer(name, "aclinherit",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
653 &zs->zs_acl_inherit, zs->zs_acl_inherit_setpoint)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
654 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
655
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
656 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
657 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
658
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
659 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
660 zfs_ioc_objset_stats(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
661 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
662 objset_t *os = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
663 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
664
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
665 retry:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
666 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
667 DS_MODE_STANDARD | DS_MODE_READONLY, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
668 if (error != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
669 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
670 * This is ugly: dmu_objset_open() can return EBUSY if
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
671 * the objset is held exclusively. Fortunately this hold is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
672 * only for a short while, so we retry here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
673 * This avoids user code having to handle EBUSY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
674 * for example for a "zfs list".
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
675 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
676 if (error == EBUSY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
677 delay(1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
678 goto retry;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
679 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
680 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
681 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
682
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
683 dmu_objset_stats(os, &zc->zc_objset_stats);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
684
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
685 switch (zc->zc_objset_stats.dds_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
686
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
687 case DMU_OST_ZFS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
688 error = zfs_get_stats(zc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
689 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
690
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
691 case DMU_OST_ZVOL:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
692 error = zvol_get_stats(zc, os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
693 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
694 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
695
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
696 dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
697 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
698 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
699
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
700 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
701 zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
702 {
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
703 objset_t *os;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
704 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
705 char *p;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
706
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
707 retry:
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
708 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
709 DS_MODE_STANDARD | DS_MODE_READONLY, &os);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
710 if (error != 0) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
711 /*
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
712 * This is ugly: dmu_objset_open() can return EBUSY if
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
713 * the objset is held exclusively. Fortunately this hold is
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
714 * only for a short while, so we retry here.
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
715 * This avoids user code having to handle EBUSY,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
716 * for example for a "zfs list".
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
717 */
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
718 if (error == EBUSY) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
719 delay(1);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
720 goto retry;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
721 }
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
722 if (error == ENOENT)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
723 error = ESRCH;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
724 return (error);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
725 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
726
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
727 p = strrchr(zc->zc_name, '/');
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
728 if (p == NULL || p[1] != '\0')
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
729 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
730 p = zc->zc_name + strlen(zc->zc_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
731
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
732 do {
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
733 error = dmu_dir_list_next(os,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
734 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
735 NULL, &zc->zc_cookie);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
736 if (error == ENOENT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
737 error = ESRCH;
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
738 } while (error == 0 && !INGLOBALZONE(curproc) &&
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
739 !zone_dataset_visible(zc->zc_name, NULL));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
740
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
741 /*
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
742 * 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
743 * 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
744 */
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
745 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
746 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
747
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
748 dmu_objset_close(os);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
749 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
750 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
751
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
752 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
753 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
754 {
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
755 objset_t *os;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
756 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
757
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
758 retry:
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
759 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
760 DS_MODE_STANDARD | DS_MODE_READONLY, &os);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
761 if (error != 0) {
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
762 /*
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
763 * This is ugly: dmu_objset_open() can return EBUSY if
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
764 * the objset is held exclusively. Fortunately this hold is
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
765 * only for a short while, so we retry here.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
766 * This avoids user code having to handle EBUSY,
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
767 * for example for a "zfs list".
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
768 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
769 if (error == EBUSY) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
770 delay(1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
771 goto retry;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
772 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
773 if (error == ENOENT)
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
774 error = ESRCH;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
775 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
776 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
777
1003
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
778 /*
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
779 * A dataset name of maximum length cannot have any snapshots,
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
780 * so exit immediately.
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
781 */
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
782 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
783 dmu_objset_close(os);
1003
ce99098d6a9b 6350417 long name will cause rename a dataset panic
lling
parents: 885
diff changeset
784 return (ESRCH);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
785 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
786
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
787 error = dmu_snapshot_list_next(os,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
788 sizeof (zc->zc_name) - strlen(zc->zc_name),
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
789 zc->zc_name + strlen(zc->zc_name), NULL, &zc->zc_cookie);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
790 if (error == ENOENT)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
791 error = ESRCH;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
792
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
793 if (error == 0)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
794 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
795
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 849
diff changeset
796 dmu_objset_close(os);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
797 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
798 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
799
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
800 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
801 zfs_ioc_set_prop(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
802 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
803 return (dsl_prop_set(zc->zc_name, zc->zc_prop_name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
804 zc->zc_intsz, zc->zc_numints, zc->zc_prop_value));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
805 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
806
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
807 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
808 zfs_ioc_set_quota(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
809 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
810 return (dsl_dir_set_quota(zc->zc_name, zc->zc_cookie));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
811 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
812
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
813 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
814 zfs_ioc_set_reservation(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
815 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
816 return (dsl_dir_set_reservation(zc->zc_name, zc->zc_cookie));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
817 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
818
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
819 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
820 zfs_ioc_set_volsize(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
821 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
822 return (zvol_set_volsize(zc));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
823 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
824
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
825 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
826 zfs_ioc_set_volblocksize(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
827 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
828 return (zvol_set_volblocksize(zc));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
829 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
830
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
831 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
832 zfs_ioc_create_minor(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
833 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
834 return (zvol_create_minor(zc));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
835 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
836
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
837 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
838 zfs_ioc_remove_minor(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
839 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
840 return (zvol_remove_minor(zc));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
841 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
842
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
843 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
844 * Search the vfs list for a specified resource. Returns a pointer to it
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
845 * or NULL if no suitable entry is found. The caller of this routine
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
846 * is responsible for releasing the returned vfs pointer.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
847 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
848 static vfs_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
849 zfs_get_vfs(const char *resource)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
850 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
851 struct vfs *vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
852 struct vfs *vfs_found = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
853
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
854 vfs_list_read_lock();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
855 vfsp = rootvfs;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
856 do {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
857 if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
858 VFS_HOLD(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
859 vfs_found = vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
860 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
861 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
862 vfsp = vfsp->vfs_next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
863 } while (vfsp != rootvfs);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
864 vfs_list_unlock();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
865 return (vfs_found);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
866 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
867
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
868 static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
869 zfs_create_cb(objset_t *os, void *arg, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
870 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
871 zfs_cmd_t *zc = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
872 zfs_create_fs(os, (cred_t *)(uintptr_t)zc->zc_cred, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
873 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
874
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
875 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
876 zfs_ioc_create(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
877 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
878 objset_t *clone;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
879 int error = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
880 void (*cbfunc)(objset_t *os, void *arg, dmu_tx_t *tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
881 dmu_objset_type_t type = zc->zc_objset_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
882
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
883 switch (type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
884
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
885 case DMU_OST_ZFS:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
886 cbfunc = zfs_create_cb;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
887 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
888
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
889 case DMU_OST_ZVOL:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
890 cbfunc = zvol_create_cb;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
891 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
892
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
893 default:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
894 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
895 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
896
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
897 if (zc->zc_filename[0] != '\0') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
898 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
899 * We're creating a clone of an existing snapshot.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
900 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
901 zc->zc_filename[sizeof (zc->zc_filename) - 1] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
902 if (dataset_namecheck(zc->zc_filename, NULL, NULL) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
903 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
904
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
905 error = dmu_objset_open(zc->zc_filename, type,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
906 DS_MODE_STANDARD | DS_MODE_READONLY, &clone);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
907 if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
908 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
909 error = dmu_objset_create(zc->zc_name, type, clone, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
910 dmu_objset_close(clone);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
911 } else if (strchr(zc->zc_name, '@') != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
912 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
913 * We're taking a snapshot of an existing dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
914 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
915 error = dmu_objset_create(zc->zc_name, type, NULL, NULL, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
916 } else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
917 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
918 * We're creating a new dataset.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
919 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
920 if (type == DMU_OST_ZVOL) {
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
921
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
922 if ((error = zvol_check_volblocksize(zc)) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
923 return (error);
1133
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
924
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
925 if ((error = zvol_check_volsize(zc,
335d069294d1 6357470 vdev_raidz.c has unused RAIDZ_SINGLE define, code
eschrock
parents: 1003
diff changeset
926 zc->zc_volblocksize)) != 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
927 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
928 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
929 error = dmu_objset_create(zc->zc_name, type, NULL, cbfunc, zc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
930 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
931 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
932 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
933
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
934 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
935 zfs_ioc_destroy(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
936 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
937 if (strchr(zc->zc_name, '@') != NULL &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
938 zc->zc_objset_type == DMU_OST_ZFS) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
939 vfs_t *vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
940 int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
941
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
942 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
943 * Snapshots under .zfs control must be unmounted
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
944 * before they can be destroyed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
945 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
946 if ((vfsp = zfs_get_vfs(zc->zc_name)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
947 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
948 * Always force the unmount for snapshots.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
949 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
950 int flag = MS_FORCE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
951
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
952 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
953 VFS_RELE(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
954 return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
955 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
956 VFS_RELE(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
957 if ((err = dounmount(vfsp, flag, kcred)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
958 return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
959 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
960 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
961
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
962 return (dmu_objset_destroy(zc->zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
963 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
964
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
965 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
966 zfs_ioc_rollback(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
967 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
968 return (dmu_objset_rollback(zc->zc_name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
969 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
970
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
971 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
972 zfs_ioc_rename(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
973 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
974 zc->zc_prop_value[sizeof (zc->zc_prop_value) - 1] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
975 if (dataset_namecheck(zc->zc_prop_value, NULL, NULL) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
976 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
977
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
978 if (strchr(zc->zc_name, '@') != NULL &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
979 zc->zc_objset_type == DMU_OST_ZFS) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
980 vfs_t *vfsp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
981 int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
982
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
983 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
984 * Snapshots under .zfs control must be unmounted
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
985 * before they can be renamed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
986 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
987 if ((vfsp = zfs_get_vfs(zc->zc_name)) != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
988 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
989 * Always force the unmount for snapshots.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
990 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
991 int flag = MS_FORCE;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
992
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
993 if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
994 VFS_RELE(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
995 return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
996 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
997 VFS_RELE(vfsp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
998 if ((err = dounmount(vfsp, flag, kcred)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
999 return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1000 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1001 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1002
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1003 return (dmu_objset_rename(zc->zc_name, zc->zc_prop_value));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1004 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1005
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1006 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1007 zfs_ioc_recvbackup(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1008 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1009 file_t *fp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1010 int error, fd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1011
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1012 fd = zc->zc_cookie;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1013 fp = getf(fd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1014 if (fp == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1015 return (EBADF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1016 error = dmu_recvbackup(&zc->zc_begin_record, &zc->zc_cookie,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1017 fp->f_vnode, fp->f_offset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1018 releasef(fd);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1019 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1020 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1021
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1022 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1023 zfs_ioc_sendbackup(zfs_cmd_t *zc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1024 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1025 objset_t *fromsnap = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1026 objset_t *tosnap;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1027 file_t *fp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1028 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1029
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1030 error = dmu_objset_open(zc->zc_name, DMU_OST_ANY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1031 DS_MODE_STANDARD | DS_MODE_READONLY, &tosnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1032 if (error)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1033 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1034
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1035 if (zc->zc_prop_value[0] != '\0') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1036 error = dmu_objset_open(zc->zc_prop_value, DMU_OST_ANY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1037 DS_MODE_STANDARD | DS_MODE_READONLY, &fromsnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1038 if (error) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1039 dmu_objset_close(tosnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1040 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1041 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1042 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1043
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1044 fp = getf(zc->zc_cookie);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1045 if (fp == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1046 dmu_objset_close(tosnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1047 if (fromsnap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1048 dmu_objset_close(fromsnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1049 return (EBADF);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1050 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1051
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1052 error = dmu_sendbackup(tosnap, fromsnap, fp->f_vnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1053
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1054 releasef(zc->zc_cookie);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1055 if (fromsnap)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1056 dmu_objset_close(fromsnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1057 dmu_objset_close(tosnap);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1058 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1059 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1060
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1061 static zfs_ioc_vec_t zfs_ioc_vec[] = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1062 { zfs_ioc_pool_create, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1063 { zfs_ioc_pool_destroy, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1064 { zfs_ioc_pool_import, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1065 { zfs_ioc_pool_export, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1066 { zfs_ioc_pool_configs, zfs_secpolicy_none, no_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1067 { zfs_ioc_pool_guid, zfs_secpolicy_read, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1068 { zfs_ioc_pool_stats, zfs_secpolicy_read, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1069 { zfs_ioc_pool_tryimport, zfs_secpolicy_config, no_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1070 { zfs_ioc_pool_scrub, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1071 { zfs_ioc_pool_freeze, zfs_secpolicy_config, no_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1072 { zfs_ioc_vdev_add, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1073 { zfs_ioc_vdev_remove, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1074 { zfs_ioc_vdev_online, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1075 { zfs_ioc_vdev_offline, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1076 { zfs_ioc_vdev_attach, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1077 { zfs_ioc_vdev_detach, zfs_secpolicy_config, pool_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1078 { zfs_ioc_objset_stats, zfs_secpolicy_read, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1079 { zfs_ioc_dataset_list_next, zfs_secpolicy_read, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1080 { zfs_ioc_snapshot_list_next, zfs_secpolicy_read, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1081 { zfs_ioc_set_prop, zfs_secpolicy_setprop, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1082 { zfs_ioc_set_quota, zfs_secpolicy_quota, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1083 { zfs_ioc_set_reservation, zfs_secpolicy_write, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1084 { zfs_ioc_set_volsize, zfs_secpolicy_config, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1085 { zfs_ioc_set_volblocksize, zfs_secpolicy_config, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1086 { zfs_ioc_create_minor, zfs_secpolicy_config, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1087 { zfs_ioc_remove_minor, zfs_secpolicy_config, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1088 { zfs_ioc_create, zfs_secpolicy_parent, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1089 { zfs_ioc_destroy, zfs_secpolicy_parent, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1090 { zfs_ioc_rollback, zfs_secpolicy_write, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1091 { zfs_ioc_rename, zfs_secpolicy_write, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1092 { zfs_ioc_recvbackup, zfs_secpolicy_write, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1093 { zfs_ioc_sendbackup, zfs_secpolicy_write, dataset_name },
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1094 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1095
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1096 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1097 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1098 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1099 zfs_cmd_t *zc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1100 uint_t vec;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1101 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1103 if (getminor(dev) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1104 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1106 vec = cmd - ZFS_IOC;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1107
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1108 if (vec >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1109 return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1111 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1112
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1113 error = xcopyin((void *)arg, zc, sizeof (zfs_cmd_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1114
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1115 if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1116 zc->zc_cred = (uintptr_t)cr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1117 zc->zc_dev = dev;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1118 error = zfs_ioc_vec[vec].zvec_secpolicy(zc->zc_name,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1119 zc->zc_prop_name, cr);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1120 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1121
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1122 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1123 * Ensure that all pool/dataset names are valid before we pass down to
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1124 * the lower layers.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1125 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1126 if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1127 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1128 switch (zfs_ioc_vec[vec].zvec_namecheck) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1129 case pool_name:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1130 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1131 error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1132 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1133
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1134 case dataset_name:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1135 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1136 error = EINVAL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1137 break;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1138 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1139 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1140
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1141 if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1142 error = zfs_ioc_vec[vec].zvec_func(zc);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1143
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1144 if (error == 0 || error == ENOMEM) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1145 int rc = xcopyout(zc, (void *)arg, sizeof (zfs_cmd_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1146 if (error == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1147 error = rc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1148 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1149
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1150 kmem_free(zc, sizeof (zfs_cmd_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1151 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1152 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1153
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1154 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1155 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1156 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1157 if (cmd != DDI_ATTACH)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1158 return (DDI_FAILURE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1159
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1160 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1161 DDI_PSEUDO, 0) == DDI_FAILURE)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1162 return (DDI_FAILURE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1164 zfs_dip = dip;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1165
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1166 ddi_report_dev(dip);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1167
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1168 return (DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1169 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1170
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1171 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1172 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1173 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1174 if (spa_busy() || zfs_busy() || zvol_busy())
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1175 return (DDI_FAILURE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1176
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1177 if (cmd != DDI_DETACH)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1178 return (DDI_FAILURE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1179
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1180 zfs_dip = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1182 ddi_prop_remove_all(dip);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1183 ddi_remove_minor_node(dip, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1184
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1185 return (DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1186 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1187
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1188 /*ARGSUSED*/
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1189 static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1190 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1191 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1192 switch (infocmd) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1193 case DDI_INFO_DEVT2DEVINFO:
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1194 *result = zfs_dip;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1195 return (DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1196
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1197 case DDI_INFO_DEVT2INSTANCE:
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1198 *result = (void *)0;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1199 return (DDI_SUCCESS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1200 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1202 return (DDI_FAILURE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1203 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1205 /*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1206 * OK, so this is a little weird.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1207 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1208 * /dev/zfs is the control node, i.e. minor 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1209 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1210 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1211 * /dev/zfs has basically nothing to do except serve up ioctls,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1212 * so most of the standard driver entry points are in zvol.c.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1213 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1214 static struct cb_ops zfs_cb_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1215 zvol_open, /* open */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1216 zvol_close, /* close */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1217 zvol_strategy, /* strategy */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1218 nodev, /* print */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1219 nodev, /* dump */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1220 zvol_read, /* read */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1221 zvol_write, /* write */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1222 zfsdev_ioctl, /* ioctl */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1223 nodev, /* devmap */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1224 nodev, /* mmap */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1225 nodev, /* segmap */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1226 nochpoll, /* poll */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1227 ddi_prop_op, /* prop_op */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1228 NULL, /* streamtab */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1229 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1230 CB_REV, /* version */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1231 zvol_aread, /* async read */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1232 zvol_awrite, /* async write */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1233 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1234
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1235 static struct dev_ops zfs_dev_ops = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1236 DEVO_REV, /* version */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1237 0, /* refcnt */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1238 zfs_info, /* info */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1239 nulldev, /* identify */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1240 nulldev, /* probe */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1241 zfs_attach, /* attach */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1242 zfs_detach, /* detach */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1243 nodev, /* reset */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1244 &zfs_cb_ops, /* driver operations */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1245 NULL /* no bus operations */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1246 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1247
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1248 static struct modldrv zfs_modldrv = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1249 &mod_driverops, "ZFS storage pool version 1", &zfs_dev_ops
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1250 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1251
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1252 static struct modlinkage modlinkage = {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1253 MODREV_1,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1254 (void *)&zfs_modlfs,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1255 (void *)&zfs_modldrv,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1256 NULL
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1257 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1258
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1259 int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1260 _init(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1261 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1262 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1263
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1264 spa_init(FREAD | FWRITE);
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1265 zfs_init();
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1266 zvol_init();
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1267
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1268 if ((error = mod_install(&modlinkage)) != 0) {
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1269 zvol_fini();
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1270 zfs_fini();
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1271 spa_fini();
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1272 return (error);
849
8d799fd81a9b 6345023 /dev/zfs fails to open once ZFS module is unloaded
bonwick
parents: 789
diff changeset
1273 }
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1274
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1275 error = ldi_ident_from_mod(&modlinkage, &zfs_li);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1276 ASSERT(error == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1277
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1278 return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1279 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1280
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1281 int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1282 _fini(void)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1283 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1284 int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1285
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1286 if (spa_busy() || zfs_busy() || zvol_busy())
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1287 return (EBUSY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1288
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1289 if ((error = mod_remove(&modlinkage)) != 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1290 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1291
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1292 zvol_fini();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1293 zfs_fini();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1294 spa_fini();
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1295
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1296 ldi_ident_release(zfs_li);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1297 zfs_li = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1298
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1299 return (error);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1300 }
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1301
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1302 int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1303 _info(struct modinfo *modinfop)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1304 {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1305 return (mod_info(&modlinkage, modinfop));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
1306 }