Print this page
8520 lzc_rollback_to should support rolling back to origin
7198 libzfs should gracefully handle EINVAL from lzc_rollback
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Dan McDonald <danmcd@joyent.com>
NEX-16623 Ability to set properties for multiple datasets/snapshots during single sync-round
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-16502 libshare needs to support SMB in a zone
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-15279 support NFS server in zone
NEX-15520 online NFS shares cause zoneadm halt to hang in nfs_export_zone_fini
Portions contributed by: Dan Kruchinin dan.kruchinin@nexenta.com
Portions contributed by: Stepan Zastupov stepan.zastupov@gmail.com
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-8600 Destroying a KRRP session takes too long
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-5736 implement autoreplace matching based on FRU slot number
NEX-6200 hot spares are not reactivated after reinserting into enclosure
NEX-9403 need to update FRU for spare and l2cache devices
NEX-9404 remove lofi autoreplace support from syseventd
NEX-9409 hotsparing doesn't work for vdevs without FRU
NEX-9424 zfs`vdev_online() needs better notification about state changes
Portions contributed by: Alek Pinchuk <alek@nexenta.com>
Portions contributed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-7822 40Gb Intel XL710 NIC performance data
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-8827 AUTOSNAP: can't register recursive zone when there is a child under autosnappool/volumegrou
Reviewed by: Alex Deiter <alex.deiter@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-8106 async ZFS event notifications don't need to announce publish failure
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-6490 Unable to destroy filesystem with receive_resume_token
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-6213 KRRP: System panics if recv-stream does not have snap-properties
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Alexey Komarov <alexey.komarov@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-5553 ZFS auto-trim, manual-trim and scrub can race and deadlock
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-5795 Rename 'wrc' as 'wbc' in the source and in the tech docs
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-5272 KRRP: replicate snapshot properties
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Alexey Komarov <alexey.komarov@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-5268 WBC: add sysevent migration-done
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-5060 WBC: Writecache and deduplication should not be used together
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-4830 writecache=off leaks data on special vdev (the data will never migrate)
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-4608 WRC: Possible deadlock during the disabling of WRC for a dataset
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
4986 receiving replication stream fails if any snapshot exceeds refquota
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Gordon Ross <gordon.ross@nexenta.com>
6388 Failure of userland copy should return EFAULT
Reviewed by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Dan Kimmel <dan.kimmel@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
6328 Fix cstyle errors in zfs codebase (fix studio)
6328 Fix cstyle errors in zfs codebase
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Alex Reece <alex@delphix.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Jorgen Lundman <lundman@lundman.net>
Approved by: Robert Mustacchi <rm@joyent.com>
2605 want to resume interrupted zfs send
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Xin Li <delphij@freebsd.org>
Reviewed by: Arne Jansen <sensille@gmx.net>
Approved by: Dan McDonald <danmcd@omniti.com>
6286 ZFS internal error when set large block on bootfs
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Andriy Gapon <avg@FreeBSD.org>
Approved by: Robert Mustacchi <rm@joyent.com>
4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R (fix studio build)
4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Prakash Surya <prakash.surya@delphix.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Garrett D'Amore <garrett@damore.org>
6096 ZFS_SMB_ACL_RENAME needs to cleanup better
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Reviewed by: George Wilson <gwilson@zfsmail.com>
Approved by: Robert Mustacchi <rm@joyent.com>
5946 zfs_ioc_space_snaps must check that firstsnap and lastsnap refer to snapshots
5945 zfs_ioc_send_space must ensure that fromsnap refers to a snapshot
Reviewed by: Steven Hartland <killing@multiplay.co.uk>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Approved by: Gordon Ross <gordon.ross@nexenta.com>
5515 dataset user hold doesn't reject empty tags
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Approved by: Matthew Ahrens <mahrens@delphix.com>
5765 add support for estimating send stream size with lzc_send_space when source is a bookmark
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com>
Reviewed by: Steven Hartland <killing@multiplay.co.uk>
Reviewed by: Bayard Bell <buffer.g.overflow@gmail.com>
Approved by: Albert Lee <trisk@nexenta.com>
NEX-4476 WRC: Allow to use write back cache per tree of datasets
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Revert "NEX-4476 WRC: Allow to use write back cache per tree of datasets"
This reverts commit fe97b74444278a6f36fec93179133641296312da.
NEX-4476 WRC: Allow to use write back cache per tree of datasets
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-4194 WRC does not migrate data when idle
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-4206 Event 'recv' should contain information that received ds is new
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Alexey Komarov <alexey.komarov@nexenta.com>
NEX-4044 remove sha1crc32 in preparation with upstream merge of edon-r and skien
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Conflicts:
usr/src/uts/common/fs/zfs/sys/zio_checksum.h
NEX-3984 On-demand TRIM
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Conflicts:
usr/src/common/zfs/zpool_prop.c
usr/src/uts/common/sys/fs/zfs.h
NEX-3964 It should not be allowed to rename a snapshot that its new name is matched to the prefix of in-kernel autosnapshots
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3878 Bogus address kernel panic in nvlist_copy_pairs from snmpd whilst exporting a zpool
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3921 Memory leaks in ZFS_IOC_OBJSET_STATS_NVL implementation
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
NEX-3010 e1000g use after free on start failure
Reviewed by: Marcel Telka <marcel.telka@nexenta.com>
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3731 fixed incorrect behavior of zpool export/destroy for faulted pool that is caused by krrp-check (lint)
NEX-3731 fixed incorrect behavior of zpool export/destroy for faulted pool that is caused by krrp-check
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
NEX-3723 Want ZFS dataset bulk listing support
Reviewed by: Josef Sipek <josef.sipek@nexenta.com>
NEX-2195 zfs panic assertion failed: strcmp(zn->zn_key_orig, mze->mze_name) != 0
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-3726 CBC decrypt returns encrypted data
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3709 Fixed KRRP/WRC code style and KRRP related warnings that are showed by 'git nits'
Reviewed by: Alek Pinchuk <alek@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3558 KRRP Integration
NEX-3165 need some dedup improvements
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
NEX-3070 Panic in zpool_create_features_002_pos test
NEX-2935 want async notification for certain ZFS changes (fix)
NEX-2935 want async notification for certain ZFS changes (lint)
NEX-2935 want async notification for certain ZFS changes
OS-103 handle CoS descriptor persistent references across vdev operations
OS-102 add man page info and tests for vdev/CoS properties and ZFS meta features
OS-80 support for vdev and CoS properties for the new I/O scheduler
OS-95 lint warning introduced by OS-61
Remaining fixes for the illumos merge
Moved closed ZFS files to open repo, changed Makefiles accordingly
Removed unneeded weak symbols
Issue #34: Add feature flag for the compount checksum - sha1crc32
Contributors: Boris Protopopov
Fixup merge results
OS-15 ensure that truss continues to work
OS-15 revert changes to put_nvlist
re #13850 Refactor ZFS config discovery IOCs to libzfs_core patterns
re 13748 added zpool export -c option
zpool export -c command exports specified pool while keeping its latest
configuration in the cache file for subsequent zpool import -c.
re #12619 rb4429 More dp->dp_config_rwlock holds
re #13204 rb4280 zfs receive/rollback deadlock
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
Bug 11205: add missing libzfs_closed_stubs.c to fix opensource-only build.
ZFS plus work: special vdevs, cos, cos/vdev properties
Bug 10481 - Dry run option in 'zfs send' isn't the same as in NexentaStor 3.1
re #7550 rb2134 lint-clean nza-kernel
re #6815 rb1758 need WORM in nza-kernel (4.0)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ new/usr/src/uts/common/fs/zfs/zfs_ioctl.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 + */
25 +
26 +/*
24 27 * Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
25 28 * Portions Copyright 2011 Martin Matuska
26 29 * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
27 - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
28 30 * Copyright (c) 2014, 2016 Joyent, Inc. All rights reserved.
29 31 * Copyright (c) 2011, 2017 by Delphix. All rights reserved.
30 32 * Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
31 33 * Copyright (c) 2013 Steven Hartland. All rights reserved.
32 34 * Copyright (c) 2014 Integros [integros.com]
35 + * Copyright 2018 Nexenta Systems, Inc.
33 36 * Copyright 2016 Toomas Soome <tsoome@me.com>
34 37 * Copyright 2017 RackTop Systems.
35 38 * Copyright (c) 2017 Datto Inc.
36 39 */
37 40
38 41 /*
39 42 * ZFS ioctls.
40 43 *
41 44 * This file handles the ioctls to /dev/zfs, used for configuring ZFS storage
42 45 * pools and filesystems, e.g. with /sbin/zfs and /sbin/zpool.
43 46 *
44 47 * There are two ways that we handle ioctls: the legacy way where almost
45 48 * all of the logic is in the ioctl callback, and the new way where most
46 49 * of the marshalling is handled in the common entry point, zfsdev_ioctl().
47 50 *
48 51 * Non-legacy ioctls should be registered by calling
49 52 * zfs_ioctl_register() from zfs_ioctl_init(). The ioctl is invoked
50 53 * from userland by lzc_ioctl().
51 54 *
52 55 * The registration arguments are as follows:
53 56 *
54 57 * const char *name
55 58 * The name of the ioctl. This is used for history logging. If the
56 59 * ioctl returns successfully (the callback returns 0), and allow_log
57 60 * is true, then a history log entry will be recorded with the input &
58 61 * output nvlists. The log entry can be printed with "zpool history -i".
59 62 *
60 63 * zfs_ioc_t ioc
61 64 * The ioctl request number, which userland will pass to ioctl(2).
62 65 * The ioctl numbers can change from release to release, because
63 66 * the caller (libzfs) must be matched to the kernel.
64 67 *
65 68 * zfs_secpolicy_func_t *secpolicy
66 69 * This function will be called before the zfs_ioc_func_t, to
67 70 * determine if this operation is permitted. It should return EPERM
68 71 * on failure, and 0 on success. Checks include determining if the
69 72 * dataset is visible in this zone, and if the user has either all
70 73 * zfs privileges in the zone (SYS_MOUNT), or has been granted permission
71 74 * to do this operation on this dataset with "zfs allow".
72 75 *
73 76 * zfs_ioc_namecheck_t namecheck
74 77 * This specifies what to expect in the zfs_cmd_t:zc_name -- a pool
75 78 * name, a dataset name, or nothing. If the name is not well-formed,
76 79 * the ioctl will fail and the callback will not be called.
77 80 * Therefore, the callback can assume that the name is well-formed
78 81 * (e.g. is null-terminated, doesn't have more than one '@' character,
79 82 * doesn't have invalid characters).
80 83 *
81 84 * zfs_ioc_poolcheck_t pool_check
82 85 * This specifies requirements on the pool state. If the pool does
83 86 * not meet them (is suspended or is readonly), the ioctl will fail
84 87 * and the callback will not be called. If any checks are specified
85 88 * (i.e. it is not POOL_CHECK_NONE), namecheck must not be NO_NAME.
86 89 * Multiple checks can be or-ed together (e.g. POOL_CHECK_SUSPENDED |
87 90 * POOL_CHECK_READONLY).
88 91 *
89 92 * boolean_t smush_outnvlist
90 93 * If smush_outnvlist is true, then the output is presumed to be a
91 94 * list of errors, and it will be "smushed" down to fit into the
92 95 * caller's buffer, by removing some entries and replacing them with a
93 96 * single "N_MORE_ERRORS" entry indicating how many were removed. See
94 97 * nvlist_smush() for details. If smush_outnvlist is false, and the
95 98 * outnvlist does not fit into the userland-provided buffer, then the
96 99 * ioctl will fail with ENOMEM.
97 100 *
98 101 * zfs_ioc_func_t *func
99 102 * The callback function that will perform the operation.
100 103 *
101 104 * The callback should return 0 on success, or an error number on
102 105 * failure. If the function fails, the userland ioctl will return -1,
103 106 * and errno will be set to the callback's return value. The callback
104 107 * will be called with the following arguments:
105 108 *
106 109 * const char *name
107 110 * The name of the pool or dataset to operate on, from
108 111 * zfs_cmd_t:zc_name. The 'namecheck' argument specifies the
109 112 * expected type (pool, dataset, or none).
110 113 *
111 114 * nvlist_t *innvl
112 115 * The input nvlist, deserialized from zfs_cmd_t:zc_nvlist_src. Or
113 116 * NULL if no input nvlist was provided. Changes to this nvlist are
114 117 * ignored. If the input nvlist could not be deserialized, the
115 118 * ioctl will fail and the callback will not be called.
116 119 *
117 120 * nvlist_t *outnvl
118 121 * The output nvlist, initially empty. The callback can fill it in,
119 122 * and it will be returned to userland by serializing it into
120 123 * zfs_cmd_t:zc_nvlist_dst. If it is non-empty, and serialization
121 124 * fails (e.g. because the caller didn't supply a large enough
122 125 * buffer), then the overall ioctl will fail. See the
123 126 * 'smush_nvlist' argument above for additional behaviors.
124 127 *
125 128 * There are two typical uses of the output nvlist:
126 129 * - To return state, e.g. property values. In this case,
127 130 * smush_outnvlist should be false. If the buffer was not large
128 131 * enough, the caller will reallocate a larger buffer and try
129 132 * the ioctl again.
130 133 *
131 134 * - To return multiple errors from an ioctl which makes on-disk
132 135 * changes. In this case, smush_outnvlist should be true.
133 136 * Ioctls which make on-disk modifications should generally not
134 137 * use the outnvl if they succeed, because the caller can not
135 138 * distinguish between the operation failing, and
136 139 * deserialization failing.
137 140 */
138 141
139 142 #include <sys/types.h>
140 143 #include <sys/param.h>
141 144 #include <sys/errno.h>
142 145 #include <sys/uio.h>
143 146 #include <sys/buf.h>
144 147 #include <sys/modctl.h>
145 148 #include <sys/open.h>
146 149 #include <sys/file.h>
147 150 #include <sys/kmem.h>
148 151 #include <sys/conf.h>
|
↓ open down ↓ |
106 lines elided |
↑ open up ↑ |
149 152 #include <sys/cmn_err.h>
150 153 #include <sys/stat.h>
151 154 #include <sys/zfs_ioctl.h>
152 155 #include <sys/zfs_vfsops.h>
153 156 #include <sys/zfs_znode.h>
154 157 #include <sys/zap.h>
155 158 #include <sys/spa.h>
156 159 #include <sys/spa_impl.h>
157 160 #include <sys/vdev.h>
158 161 #include <sys/priv_impl.h>
162 +#include <sys/autosnap.h>
159 163 #include <sys/dmu.h>
160 164 #include <sys/dsl_dir.h>
161 165 #include <sys/dsl_dataset.h>
162 166 #include <sys/dsl_prop.h>
163 167 #include <sys/dsl_deleg.h>
168 +#include <sys/dsl_synctask.h>
164 169 #include <sys/dmu_objset.h>
165 170 #include <sys/dmu_impl.h>
166 171 #include <sys/dmu_tx.h>
167 172 #include <sys/ddi.h>
168 173 #include <sys/sunddi.h>
169 174 #include <sys/sunldi.h>
170 175 #include <sys/policy.h>
171 176 #include <sys/zone.h>
172 177 #include <sys/nvpair.h>
173 178 #include <sys/pathname.h>
174 179 #include <sys/mount.h>
175 180 #include <sys/sdt.h>
176 181 #include <sys/fs/zfs.h>
177 182 #include <sys/zfs_ctldir.h>
178 183 #include <sys/zfs_dir.h>
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
179 184 #include <sys/zfs_onexit.h>
180 185 #include <sys/zvol.h>
181 186 #include <sys/dsl_scan.h>
182 187 #include <sharefs/share.h>
183 188 #include <sys/dmu_objset.h>
184 189 #include <sys/dmu_send.h>
185 190 #include <sys/dsl_destroy.h>
186 191 #include <sys/dsl_bookmark.h>
187 192 #include <sys/dsl_userhold.h>
188 193 #include <sys/zfeature.h>
194 +#include <sys/cos.h>
195 +#include <sys/cos_impl.h>
196 +#include <sys/zfeature.h>
197 +#include <sys/sysevent.h>
198 +#include <sys/sysevent_impl.h>
189 199 #include <sys/zcp.h>
190 200 #include <sys/zio_checksum.h>
191 -#include <sys/vdev_removal.h>
192 201
193 202 #include "zfs_namecheck.h"
194 203 #include "zfs_prop.h"
195 204 #include "zfs_deleg.h"
196 205 #include "zfs_comutil.h"
206 +#include "zfs_errno.h"
197 207
198 208 #include "lua.h"
199 209 #include "lauxlib.h"
200 210
201 211 extern struct modlfs zfs_modlfs;
202 212
203 213 extern void zfs_init(void);
204 214 extern void zfs_fini(void);
205 215
206 216 ldi_ident_t zfs_li = NULL;
207 217 dev_info_t *zfs_dip;
208 218
209 219 uint_t zfs_fsyncer_key;
210 220 extern uint_t rrw_tsd_key;
211 221 static uint_t zfs_allow_log_key;
212 222
213 223 typedef int zfs_ioc_legacy_func_t(zfs_cmd_t *);
214 224 typedef int zfs_ioc_func_t(const char *, nvlist_t *, nvlist_t *);
215 225 typedef int zfs_secpolicy_func_t(zfs_cmd_t *, nvlist_t *, cred_t *);
216 226
217 227 typedef enum {
218 228 NO_NAME,
219 229 POOL_NAME,
220 230 DATASET_NAME
221 231 } zfs_ioc_namecheck_t;
222 232
223 233 typedef enum {
224 234 POOL_CHECK_NONE = 1 << 0,
225 235 POOL_CHECK_SUSPENDED = 1 << 1,
226 236 POOL_CHECK_READONLY = 1 << 2,
227 237 } zfs_ioc_poolcheck_t;
228 238
229 239 typedef struct zfs_ioc_vec {
230 240 zfs_ioc_legacy_func_t *zvec_legacy_func;
231 241 zfs_ioc_func_t *zvec_func;
232 242 zfs_secpolicy_func_t *zvec_secpolicy;
233 243 zfs_ioc_namecheck_t zvec_namecheck;
234 244 boolean_t zvec_allow_log;
235 245 zfs_ioc_poolcheck_t zvec_pool_check;
236 246 boolean_t zvec_smush_outnvlist;
237 247 const char *zvec_name;
238 248 } zfs_ioc_vec_t;
239 249
240 250 /* This array is indexed by zfs_userquota_prop_t */
241 251 static const char *userquota_perms[] = {
242 252 ZFS_DELEG_PERM_USERUSED,
243 253 ZFS_DELEG_PERM_USERQUOTA,
244 254 ZFS_DELEG_PERM_GROUPUSED,
245 255 ZFS_DELEG_PERM_GROUPQUOTA,
246 256 };
247 257
248 258 static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
249 259 static int zfs_check_settable(const char *name, nvpair_t *property,
|
↓ open down ↓ |
43 lines elided |
↑ open up ↑ |
250 260 cred_t *cr);
251 261 static int zfs_check_clearable(char *dataset, nvlist_t *props,
252 262 nvlist_t **errors);
253 263 static int zfs_fill_zplprops_root(uint64_t, nvlist_t *, nvlist_t *,
254 264 boolean_t *);
255 265 int zfs_set_prop_nvlist(const char *, zprop_source_t, nvlist_t *, nvlist_t *);
256 266 static int get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp);
257 267
258 268 static int zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature);
259 269
270 +static int
271 +zfs_is_wormed_ds(dsl_dataset_t *ds)
272 +{
273 + char worminfo[13] = {0};
274 +
275 + if (dsl_prop_get_ds(ds, "nms:worm", 1, 12, &worminfo, NULL) == 0 &&
276 + worminfo[0] && strcmp(worminfo, "0") != 0 &&
277 + strcmp(worminfo, "off") != 0 && strcmp(worminfo, "-") != 0) {
278 + return (1);
279 + }
280 + return (0);
281 +}
282 +
283 +static int
284 +zfs_is_wormed(const char *name)
285 +{
286 + char worminfo[13] = {0};
287 + char cname[MAXNAMELEN];
288 + char *end;
289 +
290 + (void) strlcpy(cname, name, MAXNAMELEN);
291 + end = strchr(cname, '@');
292 + if (end)
293 + *end = 0;
294 +
295 + if (dsl_prop_get(cname, "nms:worm", 1, 12, &worminfo, NULL) == 0 &&
296 + worminfo[0] && strcmp(worminfo, "0") != 0 &&
297 + strcmp(worminfo, "off") != 0 && strcmp(worminfo, "-") != 0) {
298 + return (1);
299 + }
300 + return (0);
301 +}
302 +
260 303 /* _NOTE(PRINTFLIKE(4)) - this is printf-like, but lint is too whiney */
261 304 void
262 305 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
263 306 {
264 307 const char *newfile;
265 308 char buf[512];
266 309 va_list adx;
267 310
268 311 /*
269 312 * Get rid of annoying "../common/" prefix to filename.
270 313 */
271 314 newfile = strrchr(file, '/');
272 315 if (newfile != NULL) {
273 316 newfile = newfile + 1; /* Get rid of leading / */
274 317 } else {
275 318 newfile = file;
276 319 }
277 320
278 321 va_start(adx, fmt);
279 322 (void) vsnprintf(buf, sizeof (buf), fmt, adx);
280 323 va_end(adx);
281 324
282 325 /*
283 326 * To get this data, use the zfs-dprintf probe as so:
284 327 * dtrace -q -n 'zfs-dprintf \
285 328 * /stringof(arg0) == "dbuf.c"/ \
286 329 * {printf("%s: %s", stringof(arg1), stringof(arg3))}'
287 330 * arg0 = file name
288 331 * arg1 = function name
289 332 * arg2 = line number
290 333 * arg3 = message
291 334 */
292 335 DTRACE_PROBE4(zfs__dprintf,
293 336 char *, newfile, char *, func, int, line, char *, buf);
294 337 }
295 338
296 339 static void
297 340 history_str_free(char *buf)
298 341 {
299 342 kmem_free(buf, HIS_MAX_RECORD_LEN);
300 343 }
301 344
302 345 static char *
303 346 history_str_get(zfs_cmd_t *zc)
304 347 {
305 348 char *buf;
306 349
307 350 if (zc->zc_history == NULL)
308 351 return (NULL);
309 352
310 353 buf = kmem_alloc(HIS_MAX_RECORD_LEN, KM_SLEEP);
311 354 if (copyinstr((void *)(uintptr_t)zc->zc_history,
312 355 buf, HIS_MAX_RECORD_LEN, NULL) != 0) {
313 356 history_str_free(buf);
314 357 return (NULL);
315 358 }
316 359
317 360 buf[HIS_MAX_RECORD_LEN -1] = '\0';
318 361
319 362 return (buf);
320 363 }
321 364
322 365 /*
323 366 * Check to see if the named dataset is currently defined as bootable
324 367 */
325 368 static boolean_t
326 369 zfs_is_bootfs(const char *name)
327 370 {
328 371 objset_t *os;
329 372
330 373 if (dmu_objset_hold(name, FTAG, &os) == 0) {
331 374 boolean_t ret;
332 375 ret = (dmu_objset_id(os) == spa_bootfs(dmu_objset_spa(os)));
333 376 dmu_objset_rele(os, FTAG);
334 377 return (ret);
335 378 }
336 379 return (B_FALSE);
337 380 }
338 381
339 382 /*
340 383 * Return non-zero if the spa version is less than requested version.
341 384 */
342 385 static int
343 386 zfs_earlier_version(const char *name, int version)
344 387 {
345 388 spa_t *spa;
346 389
347 390 if (spa_open(name, &spa, FTAG) == 0) {
348 391 if (spa_version(spa) < version) {
349 392 spa_close(spa, FTAG);
350 393 return (1);
351 394 }
352 395 spa_close(spa, FTAG);
353 396 }
354 397 return (0);
355 398 }
356 399
357 400 /*
358 401 * Return TRUE if the ZPL version is less than requested version.
359 402 */
360 403 static boolean_t
361 404 zpl_earlier_version(const char *name, int version)
362 405 {
363 406 objset_t *os;
364 407 boolean_t rc = B_TRUE;
365 408
366 409 if (dmu_objset_hold(name, FTAG, &os) == 0) {
367 410 uint64_t zplversion;
368 411
369 412 if (dmu_objset_type(os) != DMU_OST_ZFS) {
370 413 dmu_objset_rele(os, FTAG);
371 414 return (B_TRUE);
372 415 }
373 416 /* XXX reading from non-owned objset */
374 417 if (zfs_get_zplprop(os, ZFS_PROP_VERSION, &zplversion) == 0)
375 418 rc = zplversion < version;
376 419 dmu_objset_rele(os, FTAG);
377 420 }
378 421 return (rc);
379 422 }
380 423
381 424 static void
382 425 zfs_log_history(zfs_cmd_t *zc)
383 426 {
384 427 spa_t *spa;
385 428 char *buf;
386 429
387 430 if ((buf = history_str_get(zc)) == NULL)
388 431 return;
389 432
390 433 if (spa_open(zc->zc_name, &spa, FTAG) == 0) {
391 434 if (spa_version(spa) >= SPA_VERSION_ZPOOL_HISTORY)
392 435 (void) spa_history_log(spa, buf);
393 436 spa_close(spa, FTAG);
394 437 }
395 438 history_str_free(buf);
396 439 }
397 440
398 441 /*
399 442 * Policy for top-level read operations (list pools). Requires no privileges,
400 443 * and can be used in the local zone, as there is no associated dataset.
401 444 */
402 445 /* ARGSUSED */
403 446 static int
404 447 zfs_secpolicy_none(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
405 448 {
406 449 return (0);
407 450 }
408 451
409 452 /*
410 453 * Policy for dataset read operations (list children, get statistics). Requires
411 454 * no privileges, but must be visible in the local zone.
412 455 */
413 456 /* ARGSUSED */
414 457 static int
415 458 zfs_secpolicy_read(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
416 459 {
417 460 if (INGLOBALZONE(curproc) ||
418 461 zone_dataset_visible(zc->zc_name, NULL))
419 462 return (0);
420 463
421 464 return (SET_ERROR(ENOENT));
422 465 }
423 466
424 467 static int
425 468 zfs_dozonecheck_impl(const char *dataset, uint64_t zoned, cred_t *cr)
426 469 {
427 470 int writable = 1;
428 471
429 472 /*
430 473 * The dataset must be visible by this zone -- check this first
431 474 * so they don't see EPERM on something they shouldn't know about.
432 475 */
433 476 if (!INGLOBALZONE(curproc) &&
434 477 !zone_dataset_visible(dataset, &writable))
435 478 return (SET_ERROR(ENOENT));
436 479
437 480 if (INGLOBALZONE(curproc)) {
438 481 /*
439 482 * If the fs is zoned, only root can access it from the
440 483 * global zone.
441 484 */
442 485 if (secpolicy_zfs(cr) && zoned)
443 486 return (SET_ERROR(EPERM));
444 487 } else {
445 488 /*
446 489 * If we are in a local zone, the 'zoned' property must be set.
447 490 */
448 491 if (!zoned)
449 492 return (SET_ERROR(EPERM));
450 493
451 494 /* must be writable by this zone */
452 495 if (!writable)
453 496 return (SET_ERROR(EPERM));
454 497 }
455 498 return (0);
456 499 }
457 500
458 501 static int
459 502 zfs_dozonecheck(const char *dataset, cred_t *cr)
460 503 {
461 504 uint64_t zoned;
462 505
463 506 if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
464 507 return (SET_ERROR(ENOENT));
465 508
466 509 return (zfs_dozonecheck_impl(dataset, zoned, cr));
467 510 }
468 511
469 512 static int
470 513 zfs_dozonecheck_ds(const char *dataset, dsl_dataset_t *ds, cred_t *cr)
471 514 {
472 515 uint64_t zoned;
473 516
474 517 if (dsl_prop_get_int_ds(ds, "zoned", &zoned))
475 518 return (SET_ERROR(ENOENT));
476 519
477 520 return (zfs_dozonecheck_impl(dataset, zoned, cr));
478 521 }
479 522
480 523 static int
481 524 zfs_secpolicy_write_perms_ds(const char *name, dsl_dataset_t *ds,
482 525 const char *perm, cred_t *cr)
483 526 {
484 527 int error;
485 528
486 529 error = zfs_dozonecheck_ds(name, ds, cr);
487 530 if (error == 0) {
488 531 error = secpolicy_zfs(cr);
489 532 if (error != 0)
490 533 error = dsl_deleg_access_impl(ds, perm, cr);
491 534 }
492 535 return (error);
493 536 }
494 537
495 538 static int
496 539 zfs_secpolicy_write_perms(const char *name, const char *perm, cred_t *cr)
497 540 {
498 541 int error;
499 542 dsl_dataset_t *ds;
500 543 dsl_pool_t *dp;
501 544
502 545 /*
503 546 * First do a quick check for root in the global zone, which
504 547 * is allowed to do all write_perms. This ensures that zfs_ioc_*
505 548 * will get to handle nonexistent datasets.
506 549 */
507 550 if (INGLOBALZONE(curproc) && secpolicy_zfs(cr) == 0)
508 551 return (0);
509 552
510 553 error = dsl_pool_hold(name, FTAG, &dp);
511 554 if (error != 0)
512 555 return (error);
513 556
514 557 error = dsl_dataset_hold(dp, name, FTAG, &ds);
515 558 if (error != 0) {
516 559 dsl_pool_rele(dp, FTAG);
517 560 return (error);
518 561 }
519 562
520 563 error = zfs_secpolicy_write_perms_ds(name, ds, perm, cr);
521 564
522 565 dsl_dataset_rele(ds, FTAG);
523 566 dsl_pool_rele(dp, FTAG);
524 567 return (error);
525 568 }
526 569
527 570 /*
528 571 * Policy for setting the security label property.
529 572 *
530 573 * Returns 0 for success, non-zero for access and other errors.
531 574 */
532 575 static int
533 576 zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
534 577 {
535 578 char ds_hexsl[MAXNAMELEN];
536 579 bslabel_t ds_sl, new_sl;
537 580 boolean_t new_default = FALSE;
538 581 uint64_t zoned;
539 582 int needed_priv = -1;
540 583 int error;
541 584
542 585 /* First get the existing dataset label. */
543 586 error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
544 587 1, sizeof (ds_hexsl), &ds_hexsl, NULL);
545 588 if (error != 0)
546 589 return (SET_ERROR(EPERM));
547 590
548 591 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
549 592 new_default = TRUE;
550 593
551 594 /* The label must be translatable */
552 595 if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
553 596 return (SET_ERROR(EINVAL));
554 597
555 598 /*
556 599 * In a non-global zone, disallow attempts to set a label that
557 600 * doesn't match that of the zone; otherwise no other checks
558 601 * are needed.
559 602 */
560 603 if (!INGLOBALZONE(curproc)) {
561 604 if (new_default || !blequal(&new_sl, CR_SL(CRED())))
562 605 return (SET_ERROR(EPERM));
563 606 return (0);
564 607 }
565 608
566 609 /*
567 610 * For global-zone datasets (i.e., those whose zoned property is
568 611 * "off", verify that the specified new label is valid for the
569 612 * global zone.
570 613 */
571 614 if (dsl_prop_get_integer(name,
572 615 zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
573 616 return (SET_ERROR(EPERM));
574 617 if (!zoned) {
575 618 if (zfs_check_global_label(name, strval) != 0)
576 619 return (SET_ERROR(EPERM));
577 620 }
578 621
579 622 /*
580 623 * If the existing dataset label is nondefault, check if the
581 624 * dataset is mounted (label cannot be changed while mounted).
582 625 * Get the zfsvfs; if there isn't one, then the dataset isn't
583 626 * mounted (or isn't a dataset, doesn't exist, ...).
584 627 */
585 628 if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
586 629 objset_t *os;
587 630 static char *setsl_tag = "setsl_tag";
588 631
589 632 /*
590 633 * Try to own the dataset; abort if there is any error,
591 634 * (e.g., already mounted, in use, or other error).
592 635 */
593 636 error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
594 637 setsl_tag, &os);
595 638 if (error != 0)
596 639 return (SET_ERROR(EPERM));
597 640
598 641 dmu_objset_disown(os, setsl_tag);
599 642
600 643 if (new_default) {
601 644 needed_priv = PRIV_FILE_DOWNGRADE_SL;
602 645 goto out_check;
603 646 }
604 647
605 648 if (hexstr_to_label(strval, &new_sl) != 0)
606 649 return (SET_ERROR(EPERM));
607 650
608 651 if (blstrictdom(&ds_sl, &new_sl))
609 652 needed_priv = PRIV_FILE_DOWNGRADE_SL;
610 653 else if (blstrictdom(&new_sl, &ds_sl))
611 654 needed_priv = PRIV_FILE_UPGRADE_SL;
612 655 } else {
613 656 /* dataset currently has a default label */
614 657 if (!new_default)
615 658 needed_priv = PRIV_FILE_UPGRADE_SL;
616 659 }
617 660
618 661 out_check:
619 662 if (needed_priv != -1)
620 663 return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
621 664 return (0);
622 665 }
623 666
624 667 static int
625 668 zfs_secpolicy_setprop(const char *dsname, zfs_prop_t prop, nvpair_t *propval,
626 669 cred_t *cr)
627 670 {
628 671 char *strval;
629 672
630 673 /*
631 674 * Check permissions for special properties.
632 675 */
633 676 switch (prop) {
634 677 case ZFS_PROP_ZONED:
635 678 /*
636 679 * Disallow setting of 'zoned' from within a local zone.
637 680 */
638 681 if (!INGLOBALZONE(curproc))
639 682 return (SET_ERROR(EPERM));
640 683 break;
641 684
642 685 case ZFS_PROP_QUOTA:
643 686 case ZFS_PROP_FILESYSTEM_LIMIT:
644 687 case ZFS_PROP_SNAPSHOT_LIMIT:
645 688 if (!INGLOBALZONE(curproc)) {
646 689 uint64_t zoned;
647 690 char setpoint[ZFS_MAX_DATASET_NAME_LEN];
648 691 /*
649 692 * Unprivileged users are allowed to modify the
650 693 * limit on things *under* (ie. contained by)
651 694 * the thing they own.
652 695 */
653 696 if (dsl_prop_get_integer(dsname, "zoned", &zoned,
654 697 setpoint))
655 698 return (SET_ERROR(EPERM));
656 699 if (!zoned || strlen(dsname) <= strlen(setpoint))
657 700 return (SET_ERROR(EPERM));
658 701 }
659 702 break;
660 703
661 704 case ZFS_PROP_MLSLABEL:
662 705 if (!is_system_labeled())
663 706 return (SET_ERROR(EPERM));
664 707
665 708 if (nvpair_value_string(propval, &strval) == 0) {
666 709 int err;
667 710
668 711 err = zfs_set_slabel_policy(dsname, strval, CRED());
669 712 if (err != 0)
670 713 return (err);
671 714 }
672 715 break;
673 716 }
674 717
675 718 return (zfs_secpolicy_write_perms(dsname, zfs_prop_to_name(prop), cr));
676 719 }
677 720
678 721 /* ARGSUSED */
679 722 static int
680 723 zfs_secpolicy_set_fsacl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
681 724 {
682 725 int error;
683 726
684 727 error = zfs_dozonecheck(zc->zc_name, cr);
685 728 if (error != 0)
686 729 return (error);
687 730
688 731 /*
689 732 * permission to set permissions will be evaluated later in
690 733 * dsl_deleg_can_allow()
691 734 */
692 735 return (0);
693 736 }
694 737
695 738 /* ARGSUSED */
696 739 static int
697 740 zfs_secpolicy_rollback(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
698 741 {
699 742 return (zfs_secpolicy_write_perms(zc->zc_name,
700 743 ZFS_DELEG_PERM_ROLLBACK, cr));
701 744 }
702 745
703 746 /* ARGSUSED */
704 747 static int
705 748 zfs_secpolicy_send(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
706 749 {
707 750 dsl_pool_t *dp;
708 751 dsl_dataset_t *ds;
709 752 char *cp;
710 753 int error;
711 754
712 755 /*
713 756 * Generate the current snapshot name from the given objsetid, then
714 757 * use that name for the secpolicy/zone checks.
715 758 */
716 759 cp = strchr(zc->zc_name, '@');
717 760 if (cp == NULL)
718 761 return (SET_ERROR(EINVAL));
719 762 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
720 763 if (error != 0)
721 764 return (error);
722 765
723 766 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &ds);
724 767 if (error != 0) {
725 768 dsl_pool_rele(dp, FTAG);
726 769 return (error);
727 770 }
728 771
729 772 dsl_dataset_name(ds, zc->zc_name);
730 773
731 774 error = zfs_secpolicy_write_perms_ds(zc->zc_name, ds,
732 775 ZFS_DELEG_PERM_SEND, cr);
733 776 dsl_dataset_rele(ds, FTAG);
734 777 dsl_pool_rele(dp, FTAG);
735 778
736 779 return (error);
737 780 }
738 781
739 782 /* ARGSUSED */
740 783 static int
741 784 zfs_secpolicy_send_new(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
742 785 {
743 786 return (zfs_secpolicy_write_perms(zc->zc_name,
744 787 ZFS_DELEG_PERM_SEND, cr));
745 788 }
746 789
747 790 /* ARGSUSED */
748 791 static int
749 792 zfs_secpolicy_deleg_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
750 793 {
751 794 vnode_t *vp;
752 795 int error;
753 796
754 797 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
755 798 NO_FOLLOW, NULL, &vp)) != 0)
756 799 return (error);
757 800
758 801 /* Now make sure mntpnt and dataset are ZFS */
759 802
760 803 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
761 804 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
762 805 zc->zc_name) != 0)) {
763 806 VN_RELE(vp);
764 807 return (SET_ERROR(EPERM));
|
↓ open down ↓ |
495 lines elided |
↑ open up ↑ |
765 808 }
766 809
767 810 VN_RELE(vp);
768 811 return (dsl_deleg_access(zc->zc_name,
769 812 ZFS_DELEG_PERM_SHARE, cr));
770 813 }
771 814
772 815 int
773 816 zfs_secpolicy_share(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
774 817 {
775 - if (!INGLOBALZONE(curproc))
776 - return (SET_ERROR(EPERM));
777 -
778 818 if (secpolicy_nfs(cr) == 0) {
779 819 return (0);
780 820 } else {
781 821 return (zfs_secpolicy_deleg_share(zc, innvl, cr));
782 822 }
783 823 }
784 824
785 825 int
786 826 zfs_secpolicy_smb_acl(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
787 827 {
788 - if (!INGLOBALZONE(curproc))
789 - return (SET_ERROR(EPERM));
790 -
791 828 if (secpolicy_smb(cr) == 0) {
792 829 return (0);
793 830 } else {
794 831 return (zfs_secpolicy_deleg_share(zc, innvl, cr));
795 832 }
796 833 }
797 834
798 835 static int
799 836 zfs_get_parent(const char *datasetname, char *parent, int parentsize)
800 837 {
801 838 char *cp;
802 839
803 840 /*
804 841 * Remove the @bla or /bla from the end of the name to get the parent.
805 842 */
806 843 (void) strncpy(parent, datasetname, parentsize);
807 844 cp = strrchr(parent, '@');
808 845 if (cp != NULL) {
809 846 cp[0] = '\0';
810 847 } else {
811 848 cp = strrchr(parent, '/');
812 849 if (cp == NULL)
813 850 return (SET_ERROR(ENOENT));
814 851 cp[0] = '\0';
815 852 }
816 853
817 854 return (0);
818 855 }
819 856
820 857 int
821 858 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
822 859 {
823 860 int error;
824 861
825 862 if ((error = zfs_secpolicy_write_perms(name,
826 863 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
827 864 return (error);
828 865
829 866 return (zfs_secpolicy_write_perms(name, ZFS_DELEG_PERM_DESTROY, cr));
830 867 }
831 868
832 869 /* ARGSUSED */
833 870 static int
834 871 zfs_secpolicy_destroy(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
835 872 {
836 873 return (zfs_secpolicy_destroy_perms(zc->zc_name, cr));
837 874 }
838 875
839 876 /*
840 877 * Destroying snapshots with delegated permissions requires
841 878 * descendant mount and destroy permissions.
842 879 */
843 880 /* ARGSUSED */
844 881 static int
845 882 zfs_secpolicy_destroy_snaps(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
846 883 {
847 884 nvlist_t *snaps;
848 885 nvpair_t *pair, *nextpair;
849 886 int error = 0;
850 887
851 888 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
852 889 return (SET_ERROR(EINVAL));
853 890 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
854 891 pair = nextpair) {
855 892 nextpair = nvlist_next_nvpair(snaps, pair);
856 893 error = zfs_secpolicy_destroy_perms(nvpair_name(pair), cr);
857 894 if (error == ENOENT) {
858 895 /*
859 896 * Ignore any snapshots that don't exist (we consider
860 897 * them "already destroyed"). Remove the name from the
861 898 * nvl here in case the snapshot is created between
862 899 * now and when we try to destroy it (in which case
863 900 * we don't want to destroy it since we haven't
864 901 * checked for permission).
865 902 */
866 903 fnvlist_remove_nvpair(snaps, pair);
867 904 error = 0;
868 905 }
869 906 if (error != 0)
870 907 break;
871 908 }
872 909
873 910 return (error);
874 911 }
875 912
876 913 int
877 914 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
878 915 {
879 916 char parentname[ZFS_MAX_DATASET_NAME_LEN];
880 917 int error;
881 918
882 919 if ((error = zfs_secpolicy_write_perms(from,
883 920 ZFS_DELEG_PERM_RENAME, cr)) != 0)
884 921 return (error);
885 922
886 923 if ((error = zfs_secpolicy_write_perms(from,
887 924 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
888 925 return (error);
889 926
890 927 if ((error = zfs_get_parent(to, parentname,
891 928 sizeof (parentname))) != 0)
892 929 return (error);
893 930
894 931 if ((error = zfs_secpolicy_write_perms(parentname,
895 932 ZFS_DELEG_PERM_CREATE, cr)) != 0)
896 933 return (error);
897 934
898 935 if ((error = zfs_secpolicy_write_perms(parentname,
899 936 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
900 937 return (error);
901 938
902 939 return (error);
903 940 }
904 941
905 942 /* ARGSUSED */
906 943 static int
907 944 zfs_secpolicy_rename(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
908 945 {
909 946 return (zfs_secpolicy_rename_perms(zc->zc_name, zc->zc_value, cr));
910 947 }
911 948
912 949 /* ARGSUSED */
913 950 static int
914 951 zfs_secpolicy_promote(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
915 952 {
916 953 dsl_pool_t *dp;
917 954 dsl_dataset_t *clone;
918 955 int error;
919 956
920 957 error = zfs_secpolicy_write_perms(zc->zc_name,
921 958 ZFS_DELEG_PERM_PROMOTE, cr);
922 959 if (error != 0)
923 960 return (error);
924 961
925 962 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
926 963 if (error != 0)
927 964 return (error);
928 965
929 966 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &clone);
930 967
931 968 if (error == 0) {
932 969 char parentname[ZFS_MAX_DATASET_NAME_LEN];
933 970 dsl_dataset_t *origin = NULL;
934 971 dsl_dir_t *dd;
935 972 dd = clone->ds_dir;
936 973
937 974 error = dsl_dataset_hold_obj(dd->dd_pool,
938 975 dsl_dir_phys(dd)->dd_origin_obj, FTAG, &origin);
939 976 if (error != 0) {
940 977 dsl_dataset_rele(clone, FTAG);
941 978 dsl_pool_rele(dp, FTAG);
942 979 return (error);
943 980 }
944 981
945 982 error = zfs_secpolicy_write_perms_ds(zc->zc_name, clone,
946 983 ZFS_DELEG_PERM_MOUNT, cr);
947 984
948 985 dsl_dataset_name(origin, parentname);
949 986 if (error == 0) {
950 987 error = zfs_secpolicy_write_perms_ds(parentname, origin,
951 988 ZFS_DELEG_PERM_PROMOTE, cr);
952 989 }
953 990 dsl_dataset_rele(clone, FTAG);
954 991 dsl_dataset_rele(origin, FTAG);
955 992 }
956 993 dsl_pool_rele(dp, FTAG);
957 994 return (error);
958 995 }
959 996
960 997 /* ARGSUSED */
961 998 static int
962 999 zfs_secpolicy_recv(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
963 1000 {
964 1001 int error;
965 1002
966 1003 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
967 1004 ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
968 1005 return (error);
969 1006
970 1007 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
971 1008 ZFS_DELEG_PERM_MOUNT, cr)) != 0)
972 1009 return (error);
973 1010
974 1011 return (zfs_secpolicy_write_perms(zc->zc_name,
975 1012 ZFS_DELEG_PERM_CREATE, cr));
976 1013 }
977 1014
978 1015 int
979 1016 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
980 1017 {
981 1018 return (zfs_secpolicy_write_perms(name,
982 1019 ZFS_DELEG_PERM_SNAPSHOT, cr));
983 1020 }
984 1021
985 1022 /*
986 1023 * Check for permission to create each snapshot in the nvlist.
987 1024 */
988 1025 /* ARGSUSED */
989 1026 static int
990 1027 zfs_secpolicy_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
991 1028 {
992 1029 nvlist_t *snaps;
993 1030 int error = 0;
994 1031 nvpair_t *pair;
995 1032
996 1033 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
997 1034 return (SET_ERROR(EINVAL));
998 1035 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
999 1036 pair = nvlist_next_nvpair(snaps, pair)) {
1000 1037 char *name = nvpair_name(pair);
1001 1038 char *atp = strchr(name, '@');
1002 1039
1003 1040 if (atp == NULL) {
1004 1041 error = SET_ERROR(EINVAL);
1005 1042 break;
1006 1043 }
1007 1044 *atp = '\0';
1008 1045 error = zfs_secpolicy_snapshot_perms(name, cr);
1009 1046 *atp = '@';
1010 1047 if (error != 0)
1011 1048 break;
1012 1049 }
1013 1050 return (error);
1014 1051 }
1015 1052
1016 1053 /*
1017 1054 * Check for permission to create each snapshot in the nvlist.
1018 1055 */
1019 1056 /* ARGSUSED */
1020 1057 static int
1021 1058 zfs_secpolicy_bookmark(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1022 1059 {
1023 1060 int error = 0;
1024 1061
1025 1062 for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
1026 1063 pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
1027 1064 char *name = nvpair_name(pair);
1028 1065 char *hashp = strchr(name, '#');
1029 1066
1030 1067 if (hashp == NULL) {
1031 1068 error = SET_ERROR(EINVAL);
1032 1069 break;
1033 1070 }
1034 1071 *hashp = '\0';
1035 1072 error = zfs_secpolicy_write_perms(name,
|
↓ open down ↓ |
235 lines elided |
↑ open up ↑ |
1036 1073 ZFS_DELEG_PERM_BOOKMARK, cr);
1037 1074 *hashp = '#';
1038 1075 if (error != 0)
1039 1076 break;
1040 1077 }
1041 1078 return (error);
1042 1079 }
1043 1080
1044 1081 /* ARGSUSED */
1045 1082 static int
1046 -zfs_secpolicy_remap(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1047 -{
1048 - return (zfs_secpolicy_write_perms(zc->zc_name,
1049 - ZFS_DELEG_PERM_REMAP, cr));
1050 -}
1051 -
1052 -/* ARGSUSED */
1053 -static int
1054 1083 zfs_secpolicy_destroy_bookmarks(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1055 1084 {
1056 1085 nvpair_t *pair, *nextpair;
1057 1086 int error = 0;
1058 1087
1059 1088 for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
1060 1089 pair = nextpair) {
1061 1090 char *name = nvpair_name(pair);
1062 1091 char *hashp = strchr(name, '#');
1063 1092 nextpair = nvlist_next_nvpair(innvl, pair);
1064 1093
1065 1094 if (hashp == NULL) {
1066 1095 error = SET_ERROR(EINVAL);
1067 1096 break;
1068 1097 }
1069 1098
1070 1099 *hashp = '\0';
1071 1100 error = zfs_secpolicy_write_perms(name,
1072 1101 ZFS_DELEG_PERM_DESTROY, cr);
1073 1102 *hashp = '#';
1074 1103 if (error == ENOENT) {
1075 1104 /*
1076 1105 * Ignore any filesystems that don't exist (we consider
1077 1106 * their bookmarks "already destroyed"). Remove
1078 1107 * the name from the nvl here in case the filesystem
1079 1108 * is created between now and when we try to destroy
1080 1109 * the bookmark (in which case we don't want to
1081 1110 * destroy it since we haven't checked for permission).
1082 1111 */
1083 1112 fnvlist_remove_nvpair(innvl, pair);
1084 1113 error = 0;
1085 1114 }
1086 1115 if (error != 0)
1087 1116 break;
1088 1117 }
1089 1118
1090 1119 return (error);
1091 1120 }
1092 1121
1093 1122 /* ARGSUSED */
1094 1123 static int
1095 1124 zfs_secpolicy_log_history(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1096 1125 {
1097 1126 /*
1098 1127 * Even root must have a proper TSD so that we know what pool
1099 1128 * to log to.
1100 1129 */
1101 1130 if (tsd_get(zfs_allow_log_key) == NULL)
1102 1131 return (SET_ERROR(EPERM));
1103 1132 return (0);
1104 1133 }
1105 1134
1106 1135 static int
1107 1136 zfs_secpolicy_create_clone(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1108 1137 {
1109 1138 char parentname[ZFS_MAX_DATASET_NAME_LEN];
1110 1139 int error;
1111 1140 char *origin;
1112 1141
1113 1142 if ((error = zfs_get_parent(zc->zc_name, parentname,
1114 1143 sizeof (parentname))) != 0)
1115 1144 return (error);
1116 1145
1117 1146 if (nvlist_lookup_string(innvl, "origin", &origin) == 0 &&
1118 1147 (error = zfs_secpolicy_write_perms(origin,
1119 1148 ZFS_DELEG_PERM_CLONE, cr)) != 0)
1120 1149 return (error);
1121 1150
1122 1151 if ((error = zfs_secpolicy_write_perms(parentname,
1123 1152 ZFS_DELEG_PERM_CREATE, cr)) != 0)
1124 1153 return (error);
1125 1154
1126 1155 return (zfs_secpolicy_write_perms(parentname,
1127 1156 ZFS_DELEG_PERM_MOUNT, cr));
1128 1157 }
1129 1158
1130 1159 /*
1131 1160 * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires
1132 1161 * SYS_CONFIG privilege, which is not available in a local zone.
1133 1162 */
1134 1163 /* ARGSUSED */
1135 1164 static int
1136 1165 zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1137 1166 {
1138 1167 if (secpolicy_sys_config(cr, B_FALSE) != 0)
1139 1168 return (SET_ERROR(EPERM));
1140 1169
1141 1170 return (0);
1142 1171 }
1143 1172
1144 1173 /*
1145 1174 * Policy for object to name lookups.
1146 1175 */
1147 1176 /* ARGSUSED */
1148 1177 static int
1149 1178 zfs_secpolicy_diff(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1150 1179 {
1151 1180 int error;
1152 1181
1153 1182 if ((error = secpolicy_sys_config(cr, B_FALSE)) == 0)
1154 1183 return (0);
1155 1184
1156 1185 error = zfs_secpolicy_write_perms(zc->zc_name, ZFS_DELEG_PERM_DIFF, cr);
1157 1186 return (error);
1158 1187 }
1159 1188
1160 1189 /*
1161 1190 * Policy for fault injection. Requires all privileges.
1162 1191 */
1163 1192 /* ARGSUSED */
1164 1193 static int
1165 1194 zfs_secpolicy_inject(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1166 1195 {
1167 1196 return (secpolicy_zinject(cr));
1168 1197 }
1169 1198
1170 1199 /* ARGSUSED */
1171 1200 static int
1172 1201 zfs_secpolicy_inherit_prop(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1173 1202 {
1174 1203 zfs_prop_t prop = zfs_name_to_prop(zc->zc_value);
1175 1204
1176 1205 if (prop == ZPROP_INVAL) {
1177 1206 if (!zfs_prop_user(zc->zc_value))
1178 1207 return (SET_ERROR(EINVAL));
1179 1208 return (zfs_secpolicy_write_perms(zc->zc_name,
1180 1209 ZFS_DELEG_PERM_USERPROP, cr));
1181 1210 } else {
1182 1211 return (zfs_secpolicy_setprop(zc->zc_name, prop,
1183 1212 NULL, cr));
1184 1213 }
1185 1214 }
1186 1215
1187 1216 static int
1188 1217 zfs_secpolicy_userspace_one(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1189 1218 {
1190 1219 int err = zfs_secpolicy_read(zc, innvl, cr);
1191 1220 if (err)
1192 1221 return (err);
1193 1222
1194 1223 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
1195 1224 return (SET_ERROR(EINVAL));
1196 1225
1197 1226 if (zc->zc_value[0] == 0) {
1198 1227 /*
1199 1228 * They are asking about a posix uid/gid. If it's
1200 1229 * themself, allow it.
1201 1230 */
1202 1231 if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
1203 1232 zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
1204 1233 if (zc->zc_guid == crgetuid(cr))
1205 1234 return (0);
1206 1235 } else {
1207 1236 if (groupmember(zc->zc_guid, cr))
1208 1237 return (0);
1209 1238 }
1210 1239 }
1211 1240
1212 1241 return (zfs_secpolicy_write_perms(zc->zc_name,
1213 1242 userquota_perms[zc->zc_objset_type], cr));
1214 1243 }
1215 1244
1216 1245 static int
1217 1246 zfs_secpolicy_userspace_many(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1218 1247 {
1219 1248 int err = zfs_secpolicy_read(zc, innvl, cr);
1220 1249 if (err)
1221 1250 return (err);
1222 1251
1223 1252 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
1224 1253 return (SET_ERROR(EINVAL));
1225 1254
1226 1255 return (zfs_secpolicy_write_perms(zc->zc_name,
1227 1256 userquota_perms[zc->zc_objset_type], cr));
1228 1257 }
1229 1258
1230 1259 /* ARGSUSED */
1231 1260 static int
1232 1261 zfs_secpolicy_userspace_upgrade(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1233 1262 {
1234 1263 return (zfs_secpolicy_setprop(zc->zc_name, ZFS_PROP_VERSION,
1235 1264 NULL, cr));
1236 1265 }
1237 1266
1238 1267 /* ARGSUSED */
1239 1268 static int
1240 1269 zfs_secpolicy_hold(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1241 1270 {
1242 1271 nvpair_t *pair;
1243 1272 nvlist_t *holds;
1244 1273 int error;
1245 1274
1246 1275 error = nvlist_lookup_nvlist(innvl, "holds", &holds);
1247 1276 if (error != 0)
1248 1277 return (SET_ERROR(EINVAL));
1249 1278
1250 1279 for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
1251 1280 pair = nvlist_next_nvpair(holds, pair)) {
1252 1281 char fsname[ZFS_MAX_DATASET_NAME_LEN];
1253 1282 error = dmu_fsname(nvpair_name(pair), fsname);
1254 1283 if (error != 0)
1255 1284 return (error);
1256 1285 error = zfs_secpolicy_write_perms(fsname,
1257 1286 ZFS_DELEG_PERM_HOLD, cr);
1258 1287 if (error != 0)
1259 1288 return (error);
1260 1289 }
1261 1290 return (0);
1262 1291 }
1263 1292
1264 1293 /* ARGSUSED */
1265 1294 static int
1266 1295 zfs_secpolicy_release(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1267 1296 {
1268 1297 nvpair_t *pair;
1269 1298 int error;
1270 1299
1271 1300 for (pair = nvlist_next_nvpair(innvl, NULL); pair != NULL;
1272 1301 pair = nvlist_next_nvpair(innvl, pair)) {
1273 1302 char fsname[ZFS_MAX_DATASET_NAME_LEN];
1274 1303 error = dmu_fsname(nvpair_name(pair), fsname);
1275 1304 if (error != 0)
1276 1305 return (error);
1277 1306 error = zfs_secpolicy_write_perms(fsname,
1278 1307 ZFS_DELEG_PERM_RELEASE, cr);
1279 1308 if (error != 0)
1280 1309 return (error);
1281 1310 }
1282 1311 return (0);
1283 1312 }
1284 1313
1285 1314 /*
1286 1315 * Policy for allowing temporary snapshots to be taken or released
1287 1316 */
1288 1317 static int
1289 1318 zfs_secpolicy_tmp_snapshot(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
1290 1319 {
1291 1320 /*
1292 1321 * A temporary snapshot is the same as a snapshot,
1293 1322 * hold, destroy and release all rolled into one.
1294 1323 * Delegated diff alone is sufficient that we allow this.
1295 1324 */
1296 1325 int error;
1297 1326
1298 1327 if ((error = zfs_secpolicy_write_perms(zc->zc_name,
1299 1328 ZFS_DELEG_PERM_DIFF, cr)) == 0)
1300 1329 return (0);
1301 1330
1302 1331 error = zfs_secpolicy_snapshot_perms(zc->zc_name, cr);
1303 1332 if (error == 0)
1304 1333 error = zfs_secpolicy_hold(zc, innvl, cr);
1305 1334 if (error == 0)
1306 1335 error = zfs_secpolicy_release(zc, innvl, cr);
1307 1336 if (error == 0)
1308 1337 error = zfs_secpolicy_destroy(zc, innvl, cr);
1309 1338 return (error);
1310 1339 }
1311 1340
1312 1341 /*
1313 1342 * Returns the nvlist as specified by the user in the zfs_cmd_t.
1314 1343 */
1315 1344 static int
1316 1345 get_nvlist(uint64_t nvl, uint64_t size, int iflag, nvlist_t **nvp)
1317 1346 {
1318 1347 char *packed;
1319 1348 int error;
1320 1349 nvlist_t *list = NULL;
1321 1350
1322 1351 /*
1323 1352 * Read in and unpack the user-supplied nvlist.
1324 1353 */
1325 1354 if (size == 0)
1326 1355 return (SET_ERROR(EINVAL));
1327 1356
1328 1357 packed = kmem_alloc(size, KM_SLEEP);
1329 1358
1330 1359 if ((error = ddi_copyin((void *)(uintptr_t)nvl, packed, size,
1331 1360 iflag)) != 0) {
1332 1361 kmem_free(packed, size);
1333 1362 return (SET_ERROR(EFAULT));
1334 1363 }
1335 1364
1336 1365 if ((error = nvlist_unpack(packed, size, &list, 0)) != 0) {
1337 1366 kmem_free(packed, size);
1338 1367 return (error);
1339 1368 }
1340 1369
1341 1370 kmem_free(packed, size);
1342 1371
1343 1372 *nvp = list;
1344 1373 return (0);
1345 1374 }
1346 1375
1347 1376 /*
1348 1377 * Reduce the size of this nvlist until it can be serialized in 'max' bytes.
1349 1378 * Entries will be removed from the end of the nvlist, and one int32 entry
1350 1379 * named "N_MORE_ERRORS" will be added indicating how many entries were
1351 1380 * removed.
1352 1381 */
1353 1382 static int
1354 1383 nvlist_smush(nvlist_t *errors, size_t max)
1355 1384 {
1356 1385 size_t size;
1357 1386
1358 1387 size = fnvlist_size(errors);
1359 1388
1360 1389 if (size > max) {
1361 1390 nvpair_t *more_errors;
1362 1391 int n = 0;
1363 1392
1364 1393 if (max < 1024)
1365 1394 return (SET_ERROR(ENOMEM));
1366 1395
1367 1396 fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0);
1368 1397 more_errors = nvlist_prev_nvpair(errors, NULL);
1369 1398
1370 1399 do {
1371 1400 nvpair_t *pair = nvlist_prev_nvpair(errors,
1372 1401 more_errors);
1373 1402 fnvlist_remove_nvpair(errors, pair);
1374 1403 n++;
1375 1404 size = fnvlist_size(errors);
|
↓ open down ↓ |
312 lines elided |
↑ open up ↑ |
1376 1405 } while (size > max);
1377 1406
1378 1407 fnvlist_remove_nvpair(errors, more_errors);
1379 1408 fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, n);
1380 1409 ASSERT3U(fnvlist_size(errors), <=, max);
1381 1410 }
1382 1411
1383 1412 return (0);
1384 1413 }
1385 1414
1415 +/*
1416 + * Callers will know whether there's anything to unpack based on ret non-0/errno
1417 + * set to ENOMEM, but observers (e.g truss) need the message properly marked to
1418 + * know if it should be unpacked and displayed. Don't marked as filled unless
1419 + * completely successful. If there's a non-empty nvlist, set size to its nvl
1420 + * size as resize hint.
1421 + */
1386 1422 static int
1387 1423 put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
1388 1424 {
1389 1425 char *packed = NULL;
1390 1426 int error = 0;
1391 1427 size_t size;
1392 1428
1393 1429 size = fnvlist_size(nvl);
1394 1430
1431 + zc->zc_nvlist_dst_filled = B_FALSE;
1395 1432 if (size > zc->zc_nvlist_dst_size) {
1396 1433 error = SET_ERROR(ENOMEM);
1397 1434 } else {
1398 1435 packed = fnvlist_pack(nvl, &size);
1399 1436 if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
1400 1437 size, zc->zc_iflags) != 0)
1401 1438 error = SET_ERROR(EFAULT);
1439 + else
1440 + zc->zc_nvlist_dst_filled = B_TRUE;
1402 1441 fnvlist_pack_free(packed, size);
1403 1442 }
1404 1443
1405 1444 zc->zc_nvlist_dst_size = size;
1406 - zc->zc_nvlist_dst_filled = B_TRUE;
1407 1445 return (error);
1408 1446 }
1409 1447
1448 +static int
1449 +getzfsvfs_from_ds(dsl_dataset_t *ds, zfsvfs_t **zfvp)
1450 +{
1451 + objset_t *os;
1452 + int error;
1453 + dsl_pool_t *dp;
1454 +
1455 + dp = ds->ds_dir->dd_pool;
1456 + dsl_pool_config_enter(dp, FTAG);
1457 +
1458 + /*
1459 + * IU: we probably need to hold dataset here.
1460 + * For now let's assume we do.
1461 + * May need revision later.
1462 + */
1463 + dsl_dataset_long_hold(ds, FTAG);
1464 + error = dmu_objset_from_ds(ds, &os);
1465 + if (dmu_objset_type(os) != DMU_OST_ZFS) {
1466 + dsl_dataset_long_rele(ds, FTAG);
1467 + dsl_pool_config_exit(dp, FTAG);
1468 + return (EINVAL);
1469 + }
1470 +
1471 + mutex_enter(&os->os_user_ptr_lock);
1472 + *zfvp = dmu_objset_get_user(os);
1473 + if (*zfvp) {
1474 + VFS_HOLD((*zfvp)->z_vfs);
1475 + } else {
1476 + error = ESRCH;
1477 + }
1478 + mutex_exit(&os->os_user_ptr_lock);
1479 + dsl_dataset_long_rele(ds, FTAG);
1480 + dsl_pool_config_exit(dp, FTAG);
1481 + return (error);
1482 +}
1483 +
1410 1484 int
1411 1485 getzfsvfs_impl(objset_t *os, zfsvfs_t **zfvp)
1412 1486 {
1413 1487 int error = 0;
1414 1488 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1415 1489 return (SET_ERROR(EINVAL));
1416 1490 }
1417 1491
1418 1492 mutex_enter(&os->os_user_ptr_lock);
1419 1493 *zfvp = dmu_objset_get_user(os);
1420 1494 if (*zfvp) {
1421 1495 VFS_HOLD((*zfvp)->z_vfs);
1422 1496 } else {
1423 1497 error = SET_ERROR(ESRCH);
1424 1498 }
1425 1499 mutex_exit(&os->os_user_ptr_lock);
1426 1500 return (error);
1427 1501 }
1428 1502
1429 1503 int
1430 1504 getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
1431 1505 {
1432 1506 objset_t *os;
1433 1507 int error;
1434 1508
1435 1509 error = dmu_objset_hold(dsname, FTAG, &os);
1436 1510 if (error != 0)
1437 1511 return (error);
1438 1512
1439 1513 error = getzfsvfs_impl(os, zfvp);
1440 1514 dmu_objset_rele(os, FTAG);
1441 1515 return (error);
1442 1516 }
1443 1517
1444 1518 /*
1445 1519 * Find a zfsvfs_t for a mounted filesystem, or create our own, in which
1446 1520 * case its z_vfs will be NULL, and it will be opened as the owner.
1447 1521 * If 'writer' is set, the z_teardown_lock will be held for RW_WRITER,
1448 1522 * which prevents all vnode ops from running.
1449 1523 */
1450 1524 static int
1451 1525 zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
1452 1526 {
1453 1527 int error = 0;
1454 1528
1455 1529 if (getzfsvfs(name, zfvp) != 0)
1456 1530 error = zfsvfs_create(name, zfvp);
1457 1531 if (error == 0) {
1458 1532 rrm_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
1459 1533 RW_READER, tag);
1460 1534 if ((*zfvp)->z_unmounted) {
1461 1535 /*
1462 1536 * XXX we could probably try again, since the unmounting
1463 1537 * thread should be just about to disassociate the
1464 1538 * objset from the zfsvfs.
1465 1539 */
1466 1540 rrm_exit(&(*zfvp)->z_teardown_lock, tag);
1467 1541 return (SET_ERROR(EBUSY));
1468 1542 }
1469 1543 }
1470 1544 return (error);
1471 1545 }
1472 1546
1473 1547 static void
1474 1548 zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
1475 1549 {
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
1476 1550 rrm_exit(&zfsvfs->z_teardown_lock, tag);
1477 1551
1478 1552 if (zfsvfs->z_vfs) {
1479 1553 VFS_RELE(zfsvfs->z_vfs);
1480 1554 } else {
1481 1555 dmu_objset_disown(zfsvfs->z_os, zfsvfs);
1482 1556 zfsvfs_free(zfsvfs);
1483 1557 }
1484 1558 }
1485 1559
1560 +
1561 +/*
1562 + * Publish events using GPEC subsystem
1563 + */
1564 +
1565 +static evchan_t *zfs_channel = NULL;
1566 +
1567 +void
1568 +zfs_event_post(const char *subclass, const char *operation, nvlist_t *ev_data)
1569 +{
1570 +
1571 + if (zfs_channel == NULL)
1572 + goto out;
1573 +
1574 + fnvlist_add_string(ev_data, "operation", operation);
1575 +
1576 + (void) sysevent_evc_publish(zfs_channel, subclass, operation,
1577 + "com.nexenta", "zfs-kernel", ev_data, EVCH_NOSLEEP);
1578 +
1579 +out:
1580 + fnvlist_free(ev_data);
1581 +}
1582 +
1486 1583 static int
1487 1584 zfs_ioc_pool_create(zfs_cmd_t *zc)
1488 1585 {
1489 1586 int error;
1490 1587 nvlist_t *config, *props = NULL;
1491 1588 nvlist_t *rootprops = NULL;
1492 1589 nvlist_t *zplprops = NULL;
1590 + nvlist_t *event;
1493 1591
1494 1592 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1495 1593 zc->zc_iflags, &config))
1496 1594 return (error);
1497 1595
1498 1596 if (zc->zc_nvlist_src_size != 0 && (error =
1499 1597 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1500 1598 zc->zc_iflags, &props))) {
1501 1599 nvlist_free(config);
1502 1600 return (error);
1503 1601 }
1504 1602
1505 1603 if (props) {
1506 1604 nvlist_t *nvl = NULL;
1507 1605 uint64_t version = SPA_VERSION;
1508 1606
1509 1607 (void) nvlist_lookup_uint64(props,
1510 1608 zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
1511 1609 if (!SPA_VERSION_IS_SUPPORTED(version)) {
1512 1610 error = SET_ERROR(EINVAL);
1513 1611 goto pool_props_bad;
1514 1612 }
1515 1613 (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
1516 1614 if (nvl) {
1517 1615 error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
1518 1616 if (error != 0) {
1519 1617 nvlist_free(config);
1520 1618 nvlist_free(props);
1521 1619 return (error);
1522 1620 }
1523 1621 (void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
1524 1622 }
1525 1623 VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
1526 1624 error = zfs_fill_zplprops_root(version, rootprops,
1527 1625 zplprops, NULL);
1528 1626 if (error != 0)
1529 1627 goto pool_props_bad;
1530 1628 }
|
↓ open down ↓ |
28 lines elided |
↑ open up ↑ |
1531 1629
1532 1630 error = spa_create(zc->zc_name, config, props, zplprops);
1533 1631
1534 1632 /*
1535 1633 * Set the remaining root properties
1536 1634 */
1537 1635 if (!error && (error = zfs_set_prop_nvlist(zc->zc_name,
1538 1636 ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
1539 1637 (void) spa_destroy(zc->zc_name);
1540 1638
1639 + if (error == 0) {
1640 + event = fnvlist_alloc();
1641 + fnvlist_add_string(event, "name", zc->zc_name);
1642 + fnvlist_add_nvlist(event, "config", config);
1643 + if (props != NULL)
1644 + fnvlist_add_nvlist(event, "props", props);
1645 + zfs_event_post(ZPOOL_EC_STATUS, "create", event);
1646 + }
1647 +
1541 1648 pool_props_bad:
1542 1649 nvlist_free(rootprops);
1543 1650 nvlist_free(zplprops);
1544 1651 nvlist_free(config);
1545 1652 nvlist_free(props);
1546 1653
1547 1654 return (error);
1548 1655 }
1549 1656
1550 1657 static int
1551 1658 zfs_ioc_pool_destroy(zfs_cmd_t *zc)
1552 1659 {
1553 1660 int error;
1661 + nvlist_t *event;
1554 1662 zfs_log_history(zc);
1555 1663 error = spa_destroy(zc->zc_name);
1556 - if (error == 0)
1664 + if (error == 0) {
1557 1665 zvol_remove_minors(zc->zc_name);
1666 + event = fnvlist_alloc();
1667 + fnvlist_add_string(event, "pool", zc->zc_name);
1668 + zfs_event_post(ZPOOL_EC_STATUS, "destroy", event);
1669 + }
1558 1670 return (error);
1559 1671 }
1560 1672
1561 1673 static int
1562 1674 zfs_ioc_pool_import(zfs_cmd_t *zc)
1563 1675 {
1564 1676 nvlist_t *config, *props = NULL;
1565 1677 uint64_t guid;
1566 1678 int error;
1679 + nvlist_t *event;
1567 1680
1568 1681 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1569 1682 zc->zc_iflags, &config)) != 0)
1570 1683 return (error);
1571 1684
1572 1685 if (zc->zc_nvlist_src_size != 0 && (error =
1573 1686 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
1574 1687 zc->zc_iflags, &props))) {
1575 1688 nvlist_free(config);
1576 1689 return (error);
1577 1690 }
1578 1691
1579 1692 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
1580 1693 guid != zc->zc_guid)
1581 1694 error = SET_ERROR(EINVAL);
1582 1695 else
1583 1696 error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
1584 1697
1698 + if (error == 0) {
1699 + event = fnvlist_alloc();
1700 + fnvlist_add_string(event, "pool", zc->zc_name);
1701 + fnvlist_add_uint64(event, "guid", zc->zc_guid);
1702 + fnvlist_add_nvlist(event, "config", config);
1703 + if (props != NULL)
1704 + fnvlist_add_nvlist(event, "props", props);
1705 + zfs_event_post(ZPOOL_EC_STATUS, "import", event);
1706 + }
1707 +
1585 1708 if (zc->zc_nvlist_dst != 0) {
1586 1709 int err;
1587 1710
1588 1711 if ((err = put_nvlist(zc, config)) != 0)
1589 1712 error = err;
1590 1713 }
1591 1714
1592 1715 nvlist_free(config);
1593 1716
1594 1717 nvlist_free(props);
1595 1718
1596 1719 return (error);
1597 1720 }
1598 1721
1599 1722 static int
1600 1723 zfs_ioc_pool_export(zfs_cmd_t *zc)
1601 1724 {
1602 1725 int error;
1603 1726 boolean_t force = (boolean_t)zc->zc_cookie;
1604 1727 boolean_t hardforce = (boolean_t)zc->zc_guid;
1728 + boolean_t saveconfig = (boolean_t)zc->zc_obj;
1729 + nvlist_t *event;
1605 1730
1606 1731 zfs_log_history(zc);
1607 - error = spa_export(zc->zc_name, NULL, force, hardforce);
1608 - if (error == 0)
1732 + error = spa_export(zc->zc_name, NULL, force, hardforce, saveconfig);
1733 + if (error == 0) {
1609 1734 zvol_remove_minors(zc->zc_name);
1735 + event = fnvlist_alloc();
1736 + fnvlist_add_string(event, "pool", zc->zc_name);
1737 + zfs_event_post(ZPOOL_EC_STATUS, "export", event);
1738 + }
1610 1739 return (error);
1611 1740 }
1612 1741
1613 1742 static int
1614 1743 zfs_ioc_pool_configs(zfs_cmd_t *zc)
1615 1744 {
1616 1745 nvlist_t *configs;
1617 1746 int error;
1618 1747
1619 1748 if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
1620 1749 return (SET_ERROR(EEXIST));
1621 1750
1622 1751 error = put_nvlist(zc, configs);
1623 1752
1624 1753 nvlist_free(configs);
1625 1754
1626 1755 return (error);
1627 1756 }
1628 1757
1629 1758 /*
1630 1759 * inputs:
1631 1760 * zc_name name of the pool
1632 1761 *
1633 1762 * outputs:
1634 1763 * zc_cookie real errno
1635 1764 * zc_nvlist_dst config nvlist
1636 1765 * zc_nvlist_dst_size size of config nvlist
1637 1766 */
1638 1767 static int
1639 1768 zfs_ioc_pool_stats(zfs_cmd_t *zc)
1640 1769 {
1641 1770 nvlist_t *config;
1642 1771 int error;
1643 1772 int ret = 0;
1644 1773
1645 1774 error = spa_get_stats(zc->zc_name, &config, zc->zc_value,
1646 1775 sizeof (zc->zc_value));
1647 1776
1648 1777 if (config != NULL) {
1649 1778 ret = put_nvlist(zc, config);
1650 1779 nvlist_free(config);
1651 1780
1652 1781 /*
1653 1782 * The config may be present even if 'error' is non-zero.
1654 1783 * In this case we return success, and preserve the real errno
1655 1784 * in 'zc_cookie'.
1656 1785 */
1657 1786 zc->zc_cookie = error;
1658 1787 } else {
1659 1788 ret = error;
1660 1789 }
1661 1790
1662 1791 return (ret);
1663 1792 }
1664 1793
1665 1794 /*
1666 1795 * Try to import the given pool, returning pool stats as appropriate so that
1667 1796 * user land knows which devices are available and overall pool health.
1668 1797 */
1669 1798 static int
1670 1799 zfs_ioc_pool_tryimport(zfs_cmd_t *zc)
1671 1800 {
1672 1801 nvlist_t *tryconfig, *config;
1673 1802 int error;
1674 1803
1675 1804 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1676 1805 zc->zc_iflags, &tryconfig)) != 0)
1677 1806 return (error);
1678 1807
1679 1808 config = spa_tryimport(tryconfig);
1680 1809
1681 1810 nvlist_free(tryconfig);
1682 1811
1683 1812 if (config == NULL)
1684 1813 return (SET_ERROR(EINVAL));
1685 1814
1686 1815 error = put_nvlist(zc, config);
1687 1816 nvlist_free(config);
1688 1817
1689 1818 return (error);
1690 1819 }
1691 1820
1692 1821 /*
1693 1822 * inputs:
1694 1823 * zc_name name of the pool
1695 1824 * zc_cookie scan func (pool_scan_func_t)
1696 1825 * zc_flags scrub pause/resume flag (pool_scrub_cmd_t)
1697 1826 */
1698 1827 static int
1699 1828 zfs_ioc_pool_scan(zfs_cmd_t *zc)
1700 1829 {
1701 1830 spa_t *spa;
1702 1831 int error;
1703 1832
1704 1833 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1705 1834 return (error);
1706 1835
1707 1836 if (zc->zc_flags >= POOL_SCRUB_FLAGS_END)
1708 1837 return (SET_ERROR(EINVAL));
1709 1838
1710 1839 if (zc->zc_flags == POOL_SCRUB_PAUSE)
1711 1840 error = spa_scrub_pause_resume(spa, POOL_SCRUB_PAUSE);
|
↓ open down ↓ |
92 lines elided |
↑ open up ↑ |
1712 1841 else if (zc->zc_cookie == POOL_SCAN_NONE)
1713 1842 error = spa_scan_stop(spa);
1714 1843 else
1715 1844 error = spa_scan(spa, zc->zc_cookie);
1716 1845
1717 1846 spa_close(spa, FTAG);
1718 1847
1719 1848 return (error);
1720 1849 }
1721 1850
1851 +/*
1852 + * inputs:
1853 + * zc_name name of the pool
1854 + * zc_cookie trim_cmd_info_t
1855 + */
1722 1856 static int
1857 +zfs_ioc_pool_trim(zfs_cmd_t *zc)
1858 +{
1859 + spa_t *spa;
1860 + int error;
1861 + trim_cmd_info_t tci;
1862 +
1863 + if (ddi_copyin((void *)(uintptr_t)zc->zc_cookie, &tci,
1864 + sizeof (tci), 0) == -1)
1865 + return (EFAULT);
1866 +
1867 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1868 + return (error);
1869 +
1870 + if (tci.tci_start) {
1871 + spa_man_trim(spa, tci.tci_rate);
1872 + } else {
1873 + spa_man_trim_stop(spa);
1874 + }
1875 +
1876 + spa_close(spa, FTAG);
1877 +
1878 + return (error);
1879 +}
1880 +
1881 +static int
1723 1882 zfs_ioc_pool_freeze(zfs_cmd_t *zc)
1724 1883 {
1725 1884 spa_t *spa;
1726 1885 int error;
1727 1886
1728 1887 error = spa_open(zc->zc_name, &spa, FTAG);
1729 1888 if (error == 0) {
1730 1889 spa_freeze(spa);
1731 1890 spa_close(spa, FTAG);
1732 1891 }
1733 1892 return (error);
1734 1893 }
1735 1894
1736 1895 static int
1737 1896 zfs_ioc_pool_upgrade(zfs_cmd_t *zc)
1738 1897 {
1739 1898 spa_t *spa;
1740 1899 int error;
1741 1900
1742 1901 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1743 1902 return (error);
1744 1903
1745 1904 if (zc->zc_cookie < spa_version(spa) ||
1746 1905 !SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
1747 1906 spa_close(spa, FTAG);
1748 1907 return (SET_ERROR(EINVAL));
1749 1908 }
1750 1909
1751 1910 spa_upgrade(spa, zc->zc_cookie);
1752 1911 spa_close(spa, FTAG);
1753 1912
1754 1913 return (error);
1755 1914 }
1756 1915
1757 1916 static int
1758 1917 zfs_ioc_pool_get_history(zfs_cmd_t *zc)
1759 1918 {
1760 1919 spa_t *spa;
1761 1920 char *hist_buf;
1762 1921 uint64_t size;
1763 1922 int error;
1764 1923
1765 1924 if ((size = zc->zc_history_len) == 0)
1766 1925 return (SET_ERROR(EINVAL));
1767 1926
1768 1927 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1769 1928 return (error);
1770 1929
1771 1930 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
1772 1931 spa_close(spa, FTAG);
1773 1932 return (SET_ERROR(ENOTSUP));
1774 1933 }
1775 1934
1776 1935 hist_buf = kmem_alloc(size, KM_SLEEP);
1777 1936 if ((error = spa_history_get(spa, &zc->zc_history_offset,
1778 1937 &zc->zc_history_len, hist_buf)) == 0) {
1779 1938 error = ddi_copyout(hist_buf,
1780 1939 (void *)(uintptr_t)zc->zc_history,
1781 1940 zc->zc_history_len, zc->zc_iflags);
1782 1941 }
1783 1942
1784 1943 spa_close(spa, FTAG);
1785 1944 kmem_free(hist_buf, size);
1786 1945 return (error);
1787 1946 }
1788 1947
1789 1948 static int
1790 1949 zfs_ioc_pool_reguid(zfs_cmd_t *zc)
1791 1950 {
1792 1951 spa_t *spa;
1793 1952 int error;
1794 1953
1795 1954 error = spa_open(zc->zc_name, &spa, FTAG);
1796 1955 if (error == 0) {
1797 1956 error = spa_change_guid(spa);
1798 1957 spa_close(spa, FTAG);
1799 1958 }
1800 1959 return (error);
1801 1960 }
1802 1961
1803 1962 static int
1804 1963 zfs_ioc_dsobj_to_dsname(zfs_cmd_t *zc)
1805 1964 {
1806 1965 return (dsl_dsobj_to_dsname(zc->zc_name, zc->zc_obj, zc->zc_value));
1807 1966 }
1808 1967
1809 1968 /*
1810 1969 * inputs:
1811 1970 * zc_name name of filesystem
1812 1971 * zc_obj object to find
1813 1972 *
1814 1973 * outputs:
1815 1974 * zc_value name of object
1816 1975 */
1817 1976 static int
1818 1977 zfs_ioc_obj_to_path(zfs_cmd_t *zc)
1819 1978 {
1820 1979 objset_t *os;
1821 1980 int error;
1822 1981
1823 1982 /* XXX reading from objset not owned */
1824 1983 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
1825 1984 return (error);
1826 1985 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1827 1986 dmu_objset_rele(os, FTAG);
1828 1987 return (SET_ERROR(EINVAL));
1829 1988 }
1830 1989 error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
1831 1990 sizeof (zc->zc_value));
1832 1991 dmu_objset_rele(os, FTAG);
1833 1992
1834 1993 return (error);
1835 1994 }
1836 1995
1837 1996 /*
1838 1997 * inputs:
1839 1998 * zc_name name of filesystem
1840 1999 * zc_obj object to find
1841 2000 *
1842 2001 * outputs:
1843 2002 * zc_stat stats on object
1844 2003 * zc_value path to object
1845 2004 */
1846 2005 static int
1847 2006 zfs_ioc_obj_to_stats(zfs_cmd_t *zc)
1848 2007 {
1849 2008 objset_t *os;
1850 2009 int error;
1851 2010
1852 2011 /* XXX reading from objset not owned */
1853 2012 if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os)) != 0)
1854 2013 return (error);
1855 2014 if (dmu_objset_type(os) != DMU_OST_ZFS) {
1856 2015 dmu_objset_rele(os, FTAG);
1857 2016 return (SET_ERROR(EINVAL));
1858 2017 }
1859 2018 error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
1860 2019 sizeof (zc->zc_value));
1861 2020 dmu_objset_rele(os, FTAG);
1862 2021
|
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
1863 2022 return (error);
1864 2023 }
1865 2024
1866 2025 static int
1867 2026 zfs_ioc_vdev_add(zfs_cmd_t *zc)
1868 2027 {
1869 2028 spa_t *spa;
1870 2029 int error;
1871 2030 nvlist_t *config, **l2cache, **spares;
1872 2031 uint_t nl2cache = 0, nspares = 0;
2032 + nvlist_t *event;
1873 2033
1874 2034 error = spa_open(zc->zc_name, &spa, FTAG);
1875 2035 if (error != 0)
1876 2036 return (error);
1877 2037
1878 2038 error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1879 2039 zc->zc_iflags, &config);
1880 2040 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
1881 2041 &l2cache, &nl2cache);
1882 2042
1883 2043 (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES,
1884 2044 &spares, &nspares);
1885 2045
1886 2046 /*
1887 2047 * A root pool with concatenated devices is not supported.
1888 2048 * Thus, can not add a device to a root pool.
1889 2049 *
1890 2050 * Intent log device can not be added to a rootpool because
1891 2051 * during mountroot, zil is replayed, a seperated log device
1892 2052 * can not be accessed during the mountroot time.
1893 2053 *
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
1894 2054 * l2cache and spare devices are ok to be added to a rootpool.
1895 2055 */
1896 2056 if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) {
1897 2057 nvlist_free(config);
1898 2058 spa_close(spa, FTAG);
1899 2059 return (SET_ERROR(EDOM));
1900 2060 }
1901 2061
1902 2062 if (error == 0) {
1903 2063 error = spa_vdev_add(spa, config);
2064 + if (error == 0) {
2065 + event = fnvlist_alloc();
2066 + fnvlist_add_string(event, "pool", zc->zc_name);
2067 + fnvlist_add_nvlist(event, "config", config);
2068 + zfs_event_post(ZPOOL_EC_STATUS, "add", event);
2069 +
2070 + }
1904 2071 nvlist_free(config);
1905 2072 }
1906 2073 spa_close(spa, FTAG);
1907 2074 return (error);
1908 2075 }
1909 2076
1910 2077 /*
1911 2078 * inputs:
1912 2079 * zc_name name of the pool
1913 - * zc_guid guid of vdev to remove
1914 - * zc_cookie cancel removal
2080 + * zc_nvlist_conf nvlist of devices to remove
2081 + * zc_cookie to stop the remove?
1915 2082 */
1916 2083 static int
1917 2084 zfs_ioc_vdev_remove(zfs_cmd_t *zc)
1918 2085 {
1919 2086 spa_t *spa;
1920 2087 int error;
2088 + nvlist_t *event;
1921 2089
1922 2090 error = spa_open(zc->zc_name, &spa, FTAG);
1923 2091 if (error != 0)
1924 2092 return (error);
1925 - if (zc->zc_cookie != 0) {
1926 - error = spa_vdev_remove_cancel(spa);
1927 - } else {
1928 - error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
2093 + error = spa_vdev_remove(spa, zc->zc_guid, B_FALSE);
2094 + if (error == 0) {
2095 + event = fnvlist_alloc();
2096 + fnvlist_add_string(event, "pool", zc->zc_name);
2097 + fnvlist_add_uint64(event, "guid", zc->zc_guid);
2098 + zfs_event_post(ZPOOL_EC_STATUS, "remove", event);
1929 2099 }
2100 +
1930 2101 spa_close(spa, FTAG);
1931 2102 return (error);
1932 2103 }
1933 2104
1934 2105 static int
1935 2106 zfs_ioc_vdev_set_state(zfs_cmd_t *zc)
1936 2107 {
1937 2108 spa_t *spa;
1938 2109 int error;
1939 2110 vdev_state_t newstate = VDEV_STATE_UNKNOWN;
1940 2111
1941 2112 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1942 2113 return (error);
1943 2114 switch (zc->zc_cookie) {
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
1944 2115 case VDEV_STATE_ONLINE:
1945 2116 error = vdev_online(spa, zc->zc_guid, zc->zc_obj, &newstate);
1946 2117 break;
1947 2118
1948 2119 case VDEV_STATE_OFFLINE:
1949 2120 error = vdev_offline(spa, zc->zc_guid, zc->zc_obj);
1950 2121 break;
1951 2122
1952 2123 case VDEV_STATE_FAULTED:
1953 2124 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
1954 - zc->zc_obj != VDEV_AUX_EXTERNAL)
2125 + zc->zc_obj != VDEV_AUX_EXTERNAL &&
2126 + zc->zc_obj != VDEV_AUX_OPEN_FAILED)
1955 2127 zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
1956 2128
1957 2129 error = vdev_fault(spa, zc->zc_guid, zc->zc_obj);
1958 2130 break;
1959 2131
1960 2132 case VDEV_STATE_DEGRADED:
1961 2133 if (zc->zc_obj != VDEV_AUX_ERR_EXCEEDED &&
1962 2134 zc->zc_obj != VDEV_AUX_EXTERNAL)
1963 2135 zc->zc_obj = VDEV_AUX_ERR_EXCEEDED;
1964 2136
1965 2137 error = vdev_degrade(spa, zc->zc_guid, zc->zc_obj);
1966 2138 break;
1967 2139
1968 2140 default:
1969 2141 error = SET_ERROR(EINVAL);
1970 2142 }
1971 2143 zc->zc_cookie = newstate;
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
1972 2144 spa_close(spa, FTAG);
1973 2145 return (error);
1974 2146 }
1975 2147
1976 2148 static int
1977 2149 zfs_ioc_vdev_attach(zfs_cmd_t *zc)
1978 2150 {
1979 2151 spa_t *spa;
1980 2152 int replacing = zc->zc_cookie;
1981 2153 nvlist_t *config;
2154 + nvlist_t *event;
1982 2155 int error;
1983 2156
1984 2157 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
1985 2158 return (error);
1986 2159
1987 2160 if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
1988 2161 zc->zc_iflags, &config)) == 0) {
1989 2162 error = spa_vdev_attach(spa, zc->zc_guid, config, replacing);
2163 + if (error == 0) {
2164 + event = fnvlist_alloc();
2165 + fnvlist_add_string(event, "pool", zc->zc_name);
2166 + fnvlist_add_nvlist(event, "config", config);
2167 + fnvlist_add_int32(event, "replacing", replacing);
2168 + zfs_event_post(ZPOOL_EC_STATUS, "attach", event);
2169 + }
1990 2170 nvlist_free(config);
1991 2171 }
1992 2172
1993 2173 spa_close(spa, FTAG);
1994 2174 return (error);
1995 2175 }
1996 2176
1997 2177 static int
1998 2178 zfs_ioc_vdev_detach(zfs_cmd_t *zc)
1999 2179 {
2000 2180 spa_t *spa;
2001 2181 int error;
2182 + nvlist_t *event;
2002 2183
2003 2184 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
2004 2185 return (error);
2005 2186
2006 2187 error = spa_vdev_detach(spa, zc->zc_guid, 0, B_FALSE);
2007 -
2188 + if (error == 0) {
2189 + event = fnvlist_alloc();
2190 + fnvlist_add_string(event, "pool", zc->zc_name);
2191 + fnvlist_add_uint64(event, "guid", zc->zc_guid);
2192 + zfs_event_post(ZPOOL_EC_STATUS, "detach", event);
2193 + }
2008 2194 spa_close(spa, FTAG);
2009 2195 return (error);
2010 2196 }
2011 2197
2012 2198 static int
2013 2199 zfs_ioc_vdev_split(zfs_cmd_t *zc)
2014 2200 {
2015 2201 spa_t *spa;
2016 2202 nvlist_t *config, *props = NULL;
2017 2203 int error;
2018 2204 boolean_t exp = !!(zc->zc_cookie & ZPOOL_EXPORT_AFTER_SPLIT);
2019 2205
2020 2206 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
2021 2207 return (error);
2022 2208
2023 2209 if (error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
2024 2210 zc->zc_iflags, &config)) {
2025 2211 spa_close(spa, FTAG);
2026 2212 return (error);
2027 2213 }
2028 2214
2029 2215 if (zc->zc_nvlist_src_size != 0 && (error =
2030 2216 get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2031 2217 zc->zc_iflags, &props))) {
2032 2218 spa_close(spa, FTAG);
2033 2219 nvlist_free(config);
2034 2220 return (error);
2035 2221 }
2036 2222
2037 2223 error = spa_vdev_split_mirror(spa, zc->zc_string, config, props, exp);
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
2038 2224
2039 2225 spa_close(spa, FTAG);
2040 2226
2041 2227 nvlist_free(config);
2042 2228 nvlist_free(props);
2043 2229
2044 2230 return (error);
2045 2231 }
2046 2232
2047 2233 static int
2234 +zfs_ioc_vdev_setl2adddt(zfs_cmd_t *zc)
2235 +{
2236 + spa_t *spa;
2237 + int error;
2238 + uint64_t guid = zc->zc_guid;
2239 + char *l2ad_ddt = zc->zc_value;
2240 +
2241 + error = spa_open(zc->zc_name, &spa, FTAG);
2242 + if (error != 0)
2243 + return (error);
2244 +
2245 + error = spa_vdev_setl2adddt(spa, guid, l2ad_ddt);
2246 + spa_close(spa, FTAG);
2247 + return (error);
2248 +}
2249 +
2250 +
2251 +static int
2048 2252 zfs_ioc_vdev_setpath(zfs_cmd_t *zc)
2049 2253 {
2050 2254 spa_t *spa;
2051 2255 char *path = zc->zc_value;
2052 2256 uint64_t guid = zc->zc_guid;
2053 2257 int error;
2054 2258
2055 2259 error = spa_open(zc->zc_name, &spa, FTAG);
2056 2260 if (error != 0)
2057 2261 return (error);
2058 2262
2059 2263 error = spa_vdev_setpath(spa, guid, path);
2060 2264 spa_close(spa, FTAG);
2061 2265 return (error);
2062 2266 }
2063 2267
2064 2268 static int
2065 2269 zfs_ioc_vdev_setfru(zfs_cmd_t *zc)
2066 2270 {
2067 2271 spa_t *spa;
2068 2272 char *fru = zc->zc_value;
2069 2273 uint64_t guid = zc->zc_guid;
2070 2274 int error;
2071 2275
2072 2276 error = spa_open(zc->zc_name, &spa, FTAG);
2073 2277 if (error != 0)
2074 2278 return (error);
2075 2279
2076 2280 error = spa_vdev_setfru(spa, guid, fru);
2077 2281 spa_close(spa, FTAG);
2078 2282 return (error);
2079 2283 }
2080 2284
2081 2285 static int
2082 2286 zfs_ioc_objset_stats_impl(zfs_cmd_t *zc, objset_t *os)
2083 2287 {
2084 2288 int error = 0;
2085 2289 nvlist_t *nv;
2086 2290
2087 2291 dmu_objset_fast_stat(os, &zc->zc_objset_stats);
2088 2292
2089 2293 if (zc->zc_nvlist_dst != 0 &&
2090 2294 (error = dsl_prop_get_all(os, &nv)) == 0) {
2091 2295 dmu_objset_stats(os, nv);
2092 2296 /*
2093 2297 * NB: zvol_get_stats() will read the objset contents,
2094 2298 * which we aren't supposed to do with a
2095 2299 * DS_MODE_USER hold, because it could be
2096 2300 * inconsistent. So this is a bit of a workaround...
2097 2301 * XXX reading with out owning
2098 2302 */
2099 2303 if (!zc->zc_objset_stats.dds_inconsistent &&
2100 2304 dmu_objset_type(os) == DMU_OST_ZVOL) {
2101 2305 error = zvol_get_stats(os, nv);
2102 2306 if (error == EIO)
2103 2307 return (error);
2104 2308 VERIFY0(error);
2105 2309 }
2106 2310 error = put_nvlist(zc, nv);
2107 2311 nvlist_free(nv);
2108 2312 }
2109 2313
2110 2314 return (error);
2111 2315 }
2112 2316
2113 2317 /*
2114 2318 * inputs:
2115 2319 * zc_name name of filesystem
|
↓ open down ↓ |
58 lines elided |
↑ open up ↑ |
2116 2320 * zc_nvlist_dst_size size of buffer for property nvlist
2117 2321 *
2118 2322 * outputs:
2119 2323 * zc_objset_stats stats
2120 2324 * zc_nvlist_dst property nvlist
2121 2325 * zc_nvlist_dst_size size of property nvlist
2122 2326 */
2123 2327 static int
2124 2328 zfs_ioc_objset_stats(zfs_cmd_t *zc)
2125 2329 {
2126 - objset_t *os;
2330 + objset_t *os = NULL;
2127 2331 int error;
2128 2332
2129 2333 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
2130 2334 if (error == 0) {
2131 2335 error = zfs_ioc_objset_stats_impl(zc, os);
2132 2336 dmu_objset_rele(os, FTAG);
2133 2337 }
2134 2338
2135 2339 return (error);
2136 2340 }
2137 2341
2138 2342 /*
2139 2343 * inputs:
2140 2344 * zc_name name of filesystem
2141 2345 * zc_nvlist_dst_size size of buffer for property nvlist
2142 2346 *
2143 2347 * outputs:
2144 2348 * zc_nvlist_dst received property nvlist
2145 2349 * zc_nvlist_dst_size size of received property nvlist
2146 2350 *
2147 2351 * Gets received properties (distinct from local properties on or after
2148 2352 * SPA_VERSION_RECVD_PROPS) for callers who want to differentiate received from
2149 2353 * local property values.
2150 2354 */
2151 2355 static int
2152 2356 zfs_ioc_objset_recvd_props(zfs_cmd_t *zc)
2153 2357 {
2154 2358 int error = 0;
2155 2359 nvlist_t *nv;
2156 2360
2157 2361 /*
2158 2362 * Without this check, we would return local property values if the
2159 2363 * caller has not already received properties on or after
2160 2364 * SPA_VERSION_RECVD_PROPS.
2161 2365 */
2162 2366 if (!dsl_prop_get_hasrecvd(zc->zc_name))
2163 2367 return (SET_ERROR(ENOTSUP));
2164 2368
2165 2369 if (zc->zc_nvlist_dst != 0 &&
2166 2370 (error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) {
2167 2371 error = put_nvlist(zc, nv);
2168 2372 nvlist_free(nv);
2169 2373 }
2170 2374
2171 2375 return (error);
2172 2376 }
2173 2377
2174 2378 static int
2175 2379 nvl_add_zplprop(objset_t *os, nvlist_t *props, zfs_prop_t prop)
2176 2380 {
2177 2381 uint64_t value;
2178 2382 int error;
2179 2383
2180 2384 /*
2181 2385 * zfs_get_zplprop() will either find a value or give us
2182 2386 * the default value (if there is one).
2183 2387 */
2184 2388 if ((error = zfs_get_zplprop(os, prop, &value)) != 0)
2185 2389 return (error);
2186 2390 VERIFY(nvlist_add_uint64(props, zfs_prop_to_name(prop), value) == 0);
2187 2391 return (0);
2188 2392 }
2189 2393
2190 2394 /*
2191 2395 * inputs:
2192 2396 * zc_name name of filesystem
2193 2397 * zc_nvlist_dst_size size of buffer for zpl property nvlist
2194 2398 *
2195 2399 * outputs:
2196 2400 * zc_nvlist_dst zpl property nvlist
2197 2401 * zc_nvlist_dst_size size of zpl property nvlist
2198 2402 */
2199 2403 static int
2200 2404 zfs_ioc_objset_zplprops(zfs_cmd_t *zc)
2201 2405 {
2202 2406 objset_t *os;
2203 2407 int err;
2204 2408
2205 2409 /* XXX reading without owning */
2206 2410 if (err = dmu_objset_hold(zc->zc_name, FTAG, &os))
2207 2411 return (err);
2208 2412
2209 2413 dmu_objset_fast_stat(os, &zc->zc_objset_stats);
2210 2414
2211 2415 /*
2212 2416 * NB: nvl_add_zplprop() will read the objset contents,
2213 2417 * which we aren't supposed to do with a DS_MODE_USER
2214 2418 * hold, because it could be inconsistent.
2215 2419 */
2216 2420 if (zc->zc_nvlist_dst != NULL &&
2217 2421 !zc->zc_objset_stats.dds_inconsistent &&
2218 2422 dmu_objset_type(os) == DMU_OST_ZFS) {
2219 2423 nvlist_t *nv;
2220 2424
2221 2425 VERIFY(nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2222 2426 if ((err = nvl_add_zplprop(os, nv, ZFS_PROP_VERSION)) == 0 &&
2223 2427 (err = nvl_add_zplprop(os, nv, ZFS_PROP_NORMALIZE)) == 0 &&
2224 2428 (err = nvl_add_zplprop(os, nv, ZFS_PROP_UTF8ONLY)) == 0 &&
|
↓ open down ↓ |
88 lines elided |
↑ open up ↑ |
2225 2429 (err = nvl_add_zplprop(os, nv, ZFS_PROP_CASE)) == 0)
2226 2430 err = put_nvlist(zc, nv);
2227 2431 nvlist_free(nv);
2228 2432 } else {
2229 2433 err = SET_ERROR(ENOENT);
2230 2434 }
2231 2435 dmu_objset_rele(os, FTAG);
2232 2436 return (err);
2233 2437 }
2234 2438
2235 -static boolean_t
2236 -dataset_name_hidden(const char *name)
2237 -{
2238 - /*
2239 - * Skip over datasets that are not visible in this zone,
2240 - * internal datasets (which have a $ in their name), and
2241 - * temporary datasets (which have a % in their name).
2242 - */
2243 - if (strchr(name, '$') != NULL)
2244 - return (B_TRUE);
2245 - if (strchr(name, '%') != NULL)
2246 - return (B_TRUE);
2247 - if (!INGLOBALZONE(curproc) && !zone_dataset_visible(name, NULL))
2248 - return (B_TRUE);
2249 - return (B_FALSE);
2250 -}
2251 -
2252 2439 /*
2253 2440 * inputs:
2254 2441 * zc_name name of filesystem
2255 2442 * zc_cookie zap cursor
2256 2443 * zc_nvlist_dst_size size of buffer for property nvlist
2257 2444 *
2258 2445 * outputs:
2259 2446 * zc_name name of next filesystem
2260 2447 * zc_cookie zap cursor
2261 2448 * zc_objset_stats stats
2262 2449 * zc_nvlist_dst property nvlist
2263 2450 * zc_nvlist_dst_size size of property nvlist
2264 2451 */
2265 2452 static int
2266 2453 zfs_ioc_dataset_list_next(zfs_cmd_t *zc)
2267 2454 {
2268 2455 objset_t *os;
2269 2456 int error;
2270 2457 char *p;
2271 2458 size_t orig_len = strlen(zc->zc_name);
2272 2459
2273 2460 top:
2274 2461 if (error = dmu_objset_hold(zc->zc_name, FTAG, &os)) {
2275 2462 if (error == ENOENT)
2276 2463 error = SET_ERROR(ESRCH);
2277 2464 return (error);
2278 2465 }
2279 2466
2280 2467 p = strrchr(zc->zc_name, '/');
2281 2468 if (p == NULL || p[1] != '\0')
2282 2469 (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
2283 2470 p = zc->zc_name + strlen(zc->zc_name);
2284 2471
2285 2472 do {
2286 2473 error = dmu_dir_list_next(os,
2287 2474 sizeof (zc->zc_name) - (p - zc->zc_name), p,
2288 2475 NULL, &zc->zc_cookie);
2289 2476 if (error == ENOENT)
2290 2477 error = SET_ERROR(ESRCH);
2291 2478 } while (error == 0 && dataset_name_hidden(zc->zc_name));
2292 2479 dmu_objset_rele(os, FTAG);
2293 2480
2294 2481 /*
2295 2482 * If it's an internal dataset (ie. with a '$' in its name),
2296 2483 * don't try to get stats for it, otherwise we'll return ENOENT.
2297 2484 */
2298 2485 if (error == 0 && strchr(zc->zc_name, '$') == NULL) {
2299 2486 error = zfs_ioc_objset_stats(zc); /* fill in the stats */
2300 2487 if (error == ENOENT) {
2301 2488 /* We lost a race with destroy, get the next one. */
2302 2489 zc->zc_name[orig_len] = '\0';
2303 2490 goto top;
2304 2491 }
2305 2492 }
2306 2493 return (error);
2307 2494 }
2308 2495
2309 2496 /*
2310 2497 * inputs:
2311 2498 * zc_name name of filesystem
2312 2499 * zc_cookie zap cursor
2313 2500 * zc_nvlist_dst_size size of buffer for property nvlist
2314 2501 * zc_simple when set, only name is requested
2315 2502 *
2316 2503 * outputs:
2317 2504 * zc_name name of next snapshot
2318 2505 * zc_objset_stats stats
2319 2506 * zc_nvlist_dst property nvlist
2320 2507 * zc_nvlist_dst_size size of property nvlist
2321 2508 */
2322 2509 static int
2323 2510 zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
2324 2511 {
2325 2512 objset_t *os;
2326 2513 int error;
2327 2514
2328 2515 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
2329 2516 if (error != 0) {
2330 2517 return (error == ENOENT ? ESRCH : error);
2331 2518 }
2332 2519
2333 2520 /*
2334 2521 * A dataset name of maximum length cannot have any snapshots,
2335 2522 * so exit immediately.
2336 2523 */
2337 2524 if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >=
2338 2525 ZFS_MAX_DATASET_NAME_LEN) {
2339 2526 dmu_objset_rele(os, FTAG);
2340 2527 return (SET_ERROR(ESRCH));
2341 2528 }
2342 2529
2343 2530 error = dmu_snapshot_list_next(os,
2344 2531 sizeof (zc->zc_name) - strlen(zc->zc_name),
2345 2532 zc->zc_name + strlen(zc->zc_name), &zc->zc_obj, &zc->zc_cookie,
2346 2533 NULL);
2347 2534
2348 2535 if (error == 0 && !zc->zc_simple) {
2349 2536 dsl_dataset_t *ds;
2350 2537 dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
2351 2538
2352 2539 error = dsl_dataset_hold_obj(dp, zc->zc_obj, FTAG, &ds);
2353 2540 if (error == 0) {
2354 2541 objset_t *ossnap;
2355 2542
2356 2543 error = dmu_objset_from_ds(ds, &ossnap);
2357 2544 if (error == 0)
2358 2545 error = zfs_ioc_objset_stats_impl(zc, ossnap);
2359 2546 dsl_dataset_rele(ds, FTAG);
2360 2547 }
2361 2548 } else if (error == ENOENT) {
2362 2549 error = SET_ERROR(ESRCH);
2363 2550 }
2364 2551
2365 2552 dmu_objset_rele(os, FTAG);
2366 2553 /* if we failed, undo the @ that we tacked on to zc_name */
2367 2554 if (error != 0)
2368 2555 *strchr(zc->zc_name, '@') = '\0';
2369 2556 return (error);
2370 2557 }
2371 2558
2372 2559 static int
2373 2560 zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
2374 2561 {
2375 2562 const char *propname = nvpair_name(pair);
2376 2563 uint64_t *valary;
2377 2564 unsigned int vallen;
2378 2565 const char *domain;
2379 2566 char *dash;
2380 2567 zfs_userquota_prop_t type;
2381 2568 uint64_t rid;
2382 2569 uint64_t quota;
2383 2570 zfsvfs_t *zfsvfs;
2384 2571 int err;
2385 2572
2386 2573 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2387 2574 nvlist_t *attrs;
2388 2575 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2389 2576 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2390 2577 &pair) != 0)
2391 2578 return (SET_ERROR(EINVAL));
2392 2579 }
2393 2580
2394 2581 /*
2395 2582 * A correctly constructed propname is encoded as
2396 2583 * userquota@<rid>-<domain>.
2397 2584 */
2398 2585 if ((dash = strchr(propname, '-')) == NULL ||
2399 2586 nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
2400 2587 vallen != 3)
2401 2588 return (SET_ERROR(EINVAL));
2402 2589
2403 2590 domain = dash + 1;
2404 2591 type = valary[0];
2405 2592 rid = valary[1];
2406 2593 quota = valary[2];
2407 2594
2408 2595 err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
2409 2596 if (err == 0) {
2410 2597 err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
2411 2598 zfsvfs_rele(zfsvfs, FTAG);
2412 2599 }
2413 2600
2414 2601 return (err);
2415 2602 }
2416 2603
2417 2604 /*
2418 2605 * If the named property is one that has a special function to set its value,
2419 2606 * return 0 on success and a positive error code on failure; otherwise if it is
2420 2607 * not one of the special properties handled by this function, return -1.
2421 2608 *
2422 2609 * XXX: It would be better for callers of the property interface if we handled
2423 2610 * these special cases in dsl_prop.c (in the dsl layer).
2424 2611 */
2425 2612 static int
2426 2613 zfs_prop_set_special(const char *dsname, zprop_source_t source,
2427 2614 nvpair_t *pair)
2428 2615 {
2429 2616 const char *propname = nvpair_name(pair);
2430 2617 zfs_prop_t prop = zfs_name_to_prop(propname);
2431 2618 uint64_t intval;
2432 2619 int err = -1;
2433 2620
2434 2621 if (prop == ZPROP_INVAL) {
2435 2622 if (zfs_prop_userquota(propname))
2436 2623 return (zfs_prop_set_userquota(dsname, pair));
2437 2624 return (-1);
2438 2625 }
2439 2626
2440 2627 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2441 2628 nvlist_t *attrs;
2442 2629 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
2443 2630 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2444 2631 &pair) == 0);
2445 2632 }
2446 2633
2447 2634 if (zfs_prop_get_type(prop) == PROP_TYPE_STRING)
2448 2635 return (-1);
2449 2636
2450 2637 VERIFY(0 == nvpair_value_uint64(pair, &intval));
2451 2638
2452 2639 switch (prop) {
2453 2640 case ZFS_PROP_QUOTA:
2454 2641 err = dsl_dir_set_quota(dsname, source, intval);
2455 2642 break;
2456 2643 case ZFS_PROP_REFQUOTA:
2457 2644 err = dsl_dataset_set_refquota(dsname, source, intval);
2458 2645 break;
2459 2646 case ZFS_PROP_FILESYSTEM_LIMIT:
2460 2647 case ZFS_PROP_SNAPSHOT_LIMIT:
2461 2648 if (intval == UINT64_MAX) {
2462 2649 /* clearing the limit, just do it */
2463 2650 err = 0;
2464 2651 } else {
2465 2652 err = dsl_dir_activate_fs_ss_limit(dsname);
2466 2653 }
2467 2654 /*
2468 2655 * Set err to -1 to force the zfs_set_prop_nvlist code down the
2469 2656 * default path to set the value in the nvlist.
2470 2657 */
2471 2658 if (err == 0)
2472 2659 err = -1;
2473 2660 break;
2474 2661 case ZFS_PROP_RESERVATION:
2475 2662 err = dsl_dir_set_reservation(dsname, source, intval);
2476 2663 break;
2477 2664 case ZFS_PROP_REFRESERVATION:
2478 2665 err = dsl_dataset_set_refreservation(dsname, source, intval);
2479 2666 break;
2480 2667 case ZFS_PROP_VOLSIZE:
2481 2668 err = zvol_set_volsize(dsname, intval);
2482 2669 break;
2483 2670 case ZFS_PROP_VERSION:
2484 2671 {
2485 2672 zfsvfs_t *zfsvfs;
2486 2673
2487 2674 if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0)
2488 2675 break;
2489 2676
2490 2677 err = zfs_set_version(zfsvfs, intval);
2491 2678 zfsvfs_rele(zfsvfs, FTAG);
2492 2679
2493 2680 if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
2494 2681 zfs_cmd_t *zc;
2495 2682
2496 2683 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
2497 2684 (void) strcpy(zc->zc_name, dsname);
2498 2685 (void) zfs_ioc_userspace_upgrade(zc);
2499 2686 kmem_free(zc, sizeof (zfs_cmd_t));
2500 2687 }
2501 2688 break;
2502 2689 }
2503 2690 default:
2504 2691 err = -1;
2505 2692 }
2506 2693
2507 2694 return (err);
2508 2695 }
2509 2696
2510 2697 /*
2511 2698 * This function is best effort. If it fails to set any of the given properties,
2512 2699 * it continues to set as many as it can and returns the last error
2513 2700 * encountered. If the caller provides a non-NULL errlist, it will be filled in
|
↓ open down ↓ |
252 lines elided |
↑ open up ↑ |
2514 2701 * with the list of names of all the properties that failed along with the
2515 2702 * corresponding error numbers.
2516 2703 *
2517 2704 * If every property is set successfully, zero is returned and errlist is not
2518 2705 * modified.
2519 2706 */
2520 2707 int
2521 2708 zfs_set_prop_nvlist(const char *dsname, zprop_source_t source, nvlist_t *nvl,
2522 2709 nvlist_t *errlist)
2523 2710 {
2711 + spa_t *spa = NULL;
2524 2712 nvpair_t *pair;
2525 2713 nvpair_t *propval;
2526 2714 int rv = 0;
2527 2715 uint64_t intval;
2528 2716 char *strval;
2529 2717 nvlist_t *genericnvl = fnvlist_alloc();
2530 2718 nvlist_t *retrynvl = fnvlist_alloc();
2719 + zfsvfs_t *zfsvfs;
2720 + boolean_t set_worm = B_FALSE;
2721 + boolean_t set_wbc_mode = B_FALSE;
2722 + boolean_t wbc_walk_locked = B_FALSE;
2723 + boolean_t set_dedup = B_FALSE;
2531 2724
2725 + if ((rv = spa_open(dsname, &spa, FTAG)) != 0)
2726 + return (rv);
2727 +
2532 2728 retry:
2533 2729 pair = NULL;
2534 2730 while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
2535 2731 const char *propname = nvpair_name(pair);
2536 2732 zfs_prop_t prop = zfs_name_to_prop(propname);
2537 2733 int err = 0;
2538 2734
2735 + if (!set_worm && (strcmp(propname, "nms:worm") == 0)) {
2736 + set_worm = B_TRUE;
2737 + }
2738 +
2739 + /*
2740 + * If 'wbc_mode' is going to be changed, then we need to
2741 + * do some actions before 'set'
2742 + */
2743 + if (prop == ZFS_PROP_WBC_MODE)
2744 + set_wbc_mode = B_TRUE;
2745 +
2746 + /*
2747 + *
2748 + */
2749 + if (prop == ZFS_PROP_DEDUP)
2750 + set_dedup = B_TRUE;
2751 +
2539 2752 /* decode the property value */
2540 2753 propval = pair;
2541 2754 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2542 2755 nvlist_t *attrs;
2543 2756 attrs = fnvpair_value_nvlist(pair);
2544 2757 if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
2545 2758 &propval) != 0)
2546 2759 err = SET_ERROR(EINVAL);
2547 2760 }
2548 2761
2549 2762 /* Validate value type */
2550 2763 if (err == 0 && prop == ZPROP_INVAL) {
2551 2764 if (zfs_prop_user(propname)) {
2552 2765 if (nvpair_type(propval) != DATA_TYPE_STRING)
2553 2766 err = SET_ERROR(EINVAL);
2554 2767 } else if (zfs_prop_userquota(propname)) {
2555 2768 if (nvpair_type(propval) !=
2556 2769 DATA_TYPE_UINT64_ARRAY)
2557 2770 err = SET_ERROR(EINVAL);
2558 2771 } else {
2559 2772 err = SET_ERROR(EINVAL);
2560 2773 }
2561 2774 } else if (err == 0) {
2562 2775 if (nvpair_type(propval) == DATA_TYPE_STRING) {
2563 2776 if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
2564 2777 err = SET_ERROR(EINVAL);
2565 2778 } else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
2566 2779 const char *unused;
2567 2780
2568 2781 intval = fnvpair_value_uint64(propval);
2569 2782
2570 2783 switch (zfs_prop_get_type(prop)) {
2571 2784 case PROP_TYPE_NUMBER:
2572 2785 break;
2573 2786 case PROP_TYPE_STRING:
2574 2787 err = SET_ERROR(EINVAL);
2575 2788 break;
2576 2789 case PROP_TYPE_INDEX:
2577 2790 if (zfs_prop_index_to_string(prop,
2578 2791 intval, &unused) != 0)
2579 2792 err = SET_ERROR(EINVAL);
2580 2793 break;
2581 2794 default:
2582 2795 cmn_err(CE_PANIC,
2583 2796 "unknown property type");
2584 2797 }
2585 2798 } else {
2586 2799 err = SET_ERROR(EINVAL);
2587 2800 }
2588 2801 }
2589 2802
2590 2803 /* Validate permissions */
2591 2804 if (err == 0)
2592 2805 err = zfs_check_settable(dsname, pair, CRED());
2593 2806
2594 2807 if (err == 0) {
2595 2808 err = zfs_prop_set_special(dsname, source, pair);
2596 2809 if (err == -1) {
2597 2810 /*
2598 2811 * For better performance we build up a list of
2599 2812 * properties to set in a single transaction.
2600 2813 */
2601 2814 err = nvlist_add_nvpair(genericnvl, pair);
2602 2815 } else if (err != 0 && nvl != retrynvl) {
2603 2816 /*
2604 2817 * This may be a spurious error caused by
2605 2818 * receiving quota and reservation out of order.
2606 2819 * Try again in a second pass.
2607 2820 */
2608 2821 err = nvlist_add_nvpair(retrynvl, pair);
2609 2822 }
2610 2823 }
2611 2824
2612 2825 if (err != 0) {
2613 2826 if (errlist != NULL)
|
↓ open down ↓ |
65 lines elided |
↑ open up ↑ |
2614 2827 fnvlist_add_int32(errlist, propname, err);
2615 2828 rv = err;
2616 2829 }
2617 2830 }
2618 2831
2619 2832 if (nvl != retrynvl && !nvlist_empty(retrynvl)) {
2620 2833 nvl = retrynvl;
2621 2834 goto retry;
2622 2835 }
2623 2836
2837 + /*
2838 + * Deduplication and WBC cannot be used together
2839 + * This code returns error also for case when
2840 + * WBC is ON, DEDUP is off and a user tries
2841 + * to do DEDUP=off, because in this case the code
2842 + * will be more complex, but benefit is too small
2843 + */
2844 + if (set_wbc_mode && set_dedup) {
2845 + nvlist_free(genericnvl);
2846 + nvlist_free(retrynvl);
2847 + spa_close(spa, FTAG);
2848 +
2849 + return (SET_ERROR(EKZFS_WBCCONFLICT));
2850 + }
2851 +
2852 + /*
2853 + * Additional actions before set wbc_mode:
2854 + * - first need to try to lock WBC-walking, to stop migration and
2855 + * avoid the openning of new migration window
2856 + * - second step (from sync-context): if migration window
2857 + * is active it will be purged, to correctly add/remove WBC-instance
2858 + */
2859 + if (set_wbc_mode && wbc_walk_lock(spa) == 0)
2860 + wbc_walk_locked = B_TRUE;
2861 +
2624 2862 if (!nvlist_empty(genericnvl) &&
2625 2863 dsl_props_set(dsname, source, genericnvl) != 0) {
2626 2864 /*
2627 2865 * If this fails, we still want to set as many properties as we
2628 2866 * can, so try setting them individually.
2629 2867 */
2630 2868 pair = NULL;
2631 2869 while ((pair = nvlist_next_nvpair(genericnvl, pair)) != NULL) {
2632 2870 const char *propname = nvpair_name(pair);
2633 2871 int err = 0;
2634 2872
2635 2873 propval = pair;
2636 2874 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
2637 2875 nvlist_t *attrs;
2638 2876 attrs = fnvpair_value_nvlist(pair);
2639 2877 propval = fnvlist_lookup_nvpair(attrs,
2640 2878 ZPROP_VALUE);
2641 2879 }
2642 2880
2643 2881 if (nvpair_type(propval) == DATA_TYPE_STRING) {
2644 2882 strval = fnvpair_value_string(propval);
2645 2883 err = dsl_prop_set_string(dsname, propname,
2646 2884 source, strval);
2647 2885 } else {
2648 2886 intval = fnvpair_value_uint64(propval);
2649 2887 err = dsl_prop_set_int(dsname, propname, source,
2650 2888 intval);
2651 2889 }
2652 2890
2653 2891 if (err != 0) {
2654 2892 if (errlist != NULL) {
|
↓ open down ↓ |
21 lines elided |
↑ open up ↑ |
2655 2893 fnvlist_add_int32(errlist, propname,
2656 2894 err);
2657 2895 }
2658 2896 rv = err;
2659 2897 }
2660 2898 }
2661 2899 }
2662 2900 nvlist_free(genericnvl);
2663 2901 nvlist_free(retrynvl);
2664 2902
2903 + if (wbc_walk_locked)
2904 + wbc_walk_unlock(spa);
2905 +
2906 + if (set_worm && getzfsvfs(dsname, &zfsvfs) == 0) {
2907 + if (zfs_is_wormed(dsname)) {
2908 + zfsvfs->z_isworm = B_TRUE;
2909 + } else {
2910 + zfsvfs->z_isworm = B_FALSE;
2911 + }
2912 + VFS_RELE(zfsvfs->z_vfs);
2913 + }
2914 +
2915 + if (rv == 0)
2916 + autosnap_force_snap_by_name(dsname, NULL, B_FALSE);
2917 +
2918 + spa_close(spa, FTAG);
2919 +
2665 2920 return (rv);
2666 2921 }
2667 2922
2668 2923 /*
2669 2924 * Check that all the properties are valid user properties.
2670 2925 */
2671 2926 static int
2672 2927 zfs_check_userprops(const char *fsname, nvlist_t *nvl)
2673 2928 {
2674 2929 nvpair_t *pair = NULL;
2675 2930 int error = 0;
2676 2931
2677 2932 while ((pair = nvlist_next_nvpair(nvl, pair)) != NULL) {
2678 2933 const char *propname = nvpair_name(pair);
2679 2934
2680 2935 if (!zfs_prop_user(propname) ||
2681 2936 nvpair_type(pair) != DATA_TYPE_STRING)
|
↓ open down ↓ |
7 lines elided |
↑ open up ↑ |
2682 2937 return (SET_ERROR(EINVAL));
2683 2938
2684 2939 if (error = zfs_secpolicy_write_perms(fsname,
2685 2940 ZFS_DELEG_PERM_USERPROP, CRED()))
2686 2941 return (error);
2687 2942
2688 2943 if (strlen(propname) >= ZAP_MAXNAMELEN)
2689 2944 return (SET_ERROR(ENAMETOOLONG));
2690 2945
2691 2946 if (strlen(fnvpair_value_string(pair)) >= ZAP_MAXVALUELEN)
2692 - return (E2BIG);
2947 + return (SET_ERROR(E2BIG));
2693 2948 }
2694 2949 return (0);
2695 2950 }
2696 2951
2697 2952 static void
2698 2953 props_skip(nvlist_t *props, nvlist_t *skipped, nvlist_t **newprops)
2699 2954 {
2700 2955 nvpair_t *pair;
2701 2956
2702 2957 VERIFY(nvlist_alloc(newprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2703 2958
2704 2959 pair = NULL;
2705 2960 while ((pair = nvlist_next_nvpair(props, pair)) != NULL) {
2706 2961 if (nvlist_exists(skipped, nvpair_name(pair)))
2707 2962 continue;
2708 2963
2709 2964 VERIFY(nvlist_add_nvpair(*newprops, pair) == 0);
2710 2965 }
2711 2966 }
2712 2967
2713 2968 static int
2714 2969 clear_received_props(const char *dsname, nvlist_t *props,
2715 2970 nvlist_t *skipped)
2716 2971 {
2717 2972 int err = 0;
2718 2973 nvlist_t *cleared_props = NULL;
2719 2974 props_skip(props, skipped, &cleared_props);
2720 2975 if (!nvlist_empty(cleared_props)) {
2721 2976 /*
2722 2977 * Acts on local properties until the dataset has received
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
2723 2978 * properties at least once on or after SPA_VERSION_RECVD_PROPS.
2724 2979 */
2725 2980 zprop_source_t flags = (ZPROP_SRC_NONE |
2726 2981 (dsl_prop_get_hasrecvd(dsname) ? ZPROP_SRC_RECEIVED : 0));
2727 2982 err = zfs_set_prop_nvlist(dsname, flags, cleared_props, NULL);
2728 2983 }
2729 2984 nvlist_free(cleared_props);
2730 2985 return (err);
2731 2986 }
2732 2987
2988 +int
2989 +zfs_ioc_set_prop_impl(char *name, nvlist_t *props,
2990 + boolean_t received, nvlist_t **out_errors)
2991 +{
2992 + int error = 0;
2993 + nvlist_t *errors, *event;
2994 + zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
2995 + ZPROP_SRC_LOCAL);
2996 +
2997 + ASSERT(props != NULL);
2998 +
2999 + if (received) {
3000 + nvlist_t *origprops;
3001 +
3002 + if (dsl_prop_get_received(name, &origprops) == 0) {
3003 + (void) clear_received_props(name, origprops, props);
3004 + nvlist_free(origprops);
3005 + }
3006 +
3007 + error = dsl_prop_set_hasrecvd(name);
3008 + }
3009 +
3010 + errors = fnvlist_alloc();
3011 + if (error == 0)
3012 + error = zfs_set_prop_nvlist(name, source, props, errors);
3013 +
3014 + event = fnvlist_alloc();
3015 + fnvlist_add_string(event, "fsname", name);
3016 + fnvlist_add_nvlist(event, "properties", props);
3017 + fnvlist_add_nvlist(event, "errors", errors);
3018 + zfs_event_post(ZFS_EC_STATUS, "set", event);
3019 +
3020 + if (out_errors != NULL)
3021 + *out_errors = fnvlist_dup(errors);
3022 +
3023 + fnvlist_free(errors);
3024 +
3025 + return (error);
3026 +}
3027 +
2733 3028 /*
3029 + * XXX This functionality will be removed after integration of
3030 + * functionality, that does the same via zfs-channel programm.
3031 + * The zfs-channel programm implementation is being developed
3032 + * by Delphix.
3033 + *
3034 + * This functions sets provided props for provided datasets
3035 + * in one sync-round. There are some requirements:
3036 + * - all datasets should belong to the same pool
3037 + * - only user-properties
3038 + *
3039 + * This function does all or nothing.
3040 + *
2734 3041 * inputs:
3042 + * zc_nvlist_src{_size} nvlist of datasets and properties to apply
3043 + *
3044 + * outputs:
3045 + * zc_nvlist_dst{_size} error for each unapplied property
3046 + */
3047 +/* ARGSUSED */
3048 +static int
3049 +zfs_ioc_set_prop_mds(const char *pool_name, nvlist_t *dss_props,
3050 + nvlist_t *outnvl)
3051 +{
3052 + int error = 0;
3053 + spa_t *spa = NULL;
3054 + nvpair_t *pair = NULL;
3055 + size_t pool_name_len;
3056 + size_t total_num_props = 0;
3057 +
3058 + ASSERT(dss_props != NULL);
3059 +
3060 + if (nvlist_empty(dss_props))
3061 + return (SET_ERROR(ENODATA));
3062 +
3063 + pool_name_len = strlen(pool_name);
3064 + while ((pair = nvlist_next_nvpair(dss_props, pair)) != NULL) {
3065 + nvlist_t *props;
3066 + nvpair_t *prop_nvp = NULL;
3067 + const char *ds_name;
3068 +
3069 + ds_name = nvpair_name(pair);
3070 + if (strncmp(pool_name, ds_name, pool_name_len) == 0) {
3071 + char c = ds_name[pool_name_len];
3072 + if (c != '\0' && c != '/' && c != '@')
3073 + return (SET_ERROR(EXDEV));
3074 + }
3075 +
3076 + if (nvpair_type(pair) != DATA_TYPE_NVLIST)
3077 + return (SET_ERROR(EINVAL));
3078 +
3079 + props = fnvpair_value_nvlist(pair);
3080 + while ((prop_nvp = nvlist_next_nvpair(props,
3081 + prop_nvp)) != NULL) {
3082 + const char *propname = nvpair_name(prop_nvp);
3083 + /* Only user-props */
3084 + if (!zfs_prop_user(propname) ||
3085 + nvpair_type(prop_nvp) != DATA_TYPE_STRING)
3086 + return (SET_ERROR(EINVAL));
3087 +
3088 + /*
3089 + * We count the number to use it
3090 + * later to check for ENOSPC
3091 + */
3092 + total_num_props++;
3093 + }
3094 + }
3095 +
3096 + if ((error = spa_open(pool_name, &spa, FTAG)) != 0)
3097 + return (error);
3098 +
3099 + error = dsl_props_set_mds(pool_name, dss_props, total_num_props);
3100 + spa_close(spa, FTAG);
3101 + if (error == 0) {
3102 + nvlist_t *event = fnvlist_alloc();
3103 + fnvlist_add_nvlist(event, "properties", dss_props);
3104 + zfs_event_post(ZFS_EC_STATUS, "set-mds", event);
3105 + }
3106 +
3107 + return (error);
3108 +}
3109 +
3110 +/*
3111 + * inputs:
2735 3112 * zc_name name of filesystem
2736 3113 * zc_value name of property to set
2737 3114 * zc_nvlist_src{_size} nvlist of properties to apply
2738 3115 * zc_cookie received properties flag
2739 3116 *
2740 3117 * outputs:
2741 3118 * zc_nvlist_dst{_size} error for each unapplied received property
2742 3119 */
2743 3120 static int
2744 3121 zfs_ioc_set_prop(zfs_cmd_t *zc)
2745 3122 {
2746 3123 nvlist_t *nvl;
2747 3124 boolean_t received = zc->zc_cookie;
2748 - zprop_source_t source = (received ? ZPROP_SRC_RECEIVED :
2749 - ZPROP_SRC_LOCAL);
2750 - nvlist_t *errors;
3125 + nvlist_t *errors = NULL;
2751 3126 int error;
2752 3127
2753 3128 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2754 3129 zc->zc_iflags, &nvl)) != 0)
2755 3130 return (error);
2756 3131
2757 - if (received) {
2758 - nvlist_t *origprops;
3132 + error = zfs_ioc_set_prop_impl(zc->zc_name, nvl, received, &errors);
2759 3133
2760 - if (dsl_prop_get_received(zc->zc_name, &origprops) == 0) {
2761 - (void) clear_received_props(zc->zc_name,
2762 - origprops, nvl);
2763 - nvlist_free(origprops);
2764 - }
2765 -
2766 - error = dsl_prop_set_hasrecvd(zc->zc_name);
2767 - }
2768 -
2769 - errors = fnvlist_alloc();
2770 - if (error == 0)
2771 - error = zfs_set_prop_nvlist(zc->zc_name, source, nvl, errors);
2772 -
2773 3134 if (zc->zc_nvlist_dst != NULL && errors != NULL) {
2774 3135 (void) put_nvlist(zc, errors);
2775 3136 }
2776 3137
2777 3138 nvlist_free(errors);
2778 3139 nvlist_free(nvl);
2779 3140 return (error);
2780 3141 }
2781 3142
2782 3143 /*
2783 3144 * inputs:
2784 3145 * zc_name name of filesystem
2785 3146 * zc_value name of property to inherit
2786 3147 * zc_cookie revert to received value if TRUE
2787 3148 *
2788 3149 * outputs: none
2789 3150 */
2790 3151 static int
2791 3152 zfs_ioc_inherit_prop(zfs_cmd_t *zc)
2792 3153 {
2793 3154 const char *propname = zc->zc_value;
2794 3155 zfs_prop_t prop = zfs_name_to_prop(propname);
2795 3156 boolean_t received = zc->zc_cookie;
2796 3157 zprop_source_t source = (received
2797 3158 ? ZPROP_SRC_NONE /* revert to received value, if any */
2798 3159 : ZPROP_SRC_INHERITED); /* explicitly inherit */
2799 3160
2800 3161 if (received) {
2801 3162 nvlist_t *dummy;
2802 3163 nvpair_t *pair;
2803 3164 zprop_type_t type;
2804 3165 int err;
2805 3166
2806 3167 /*
2807 3168 * zfs_prop_set_special() expects properties in the form of an
2808 3169 * nvpair with type info.
2809 3170 */
2810 3171 if (prop == ZPROP_INVAL) {
2811 3172 if (!zfs_prop_user(propname))
2812 3173 return (SET_ERROR(EINVAL));
2813 3174
2814 3175 type = PROP_TYPE_STRING;
2815 3176 } else if (prop == ZFS_PROP_VOLSIZE ||
2816 3177 prop == ZFS_PROP_VERSION) {
2817 3178 return (SET_ERROR(EINVAL));
2818 3179 } else {
2819 3180 type = zfs_prop_get_type(prop);
2820 3181 }
2821 3182
2822 3183 VERIFY(nvlist_alloc(&dummy, NV_UNIQUE_NAME, KM_SLEEP) == 0);
2823 3184
2824 3185 switch (type) {
2825 3186 case PROP_TYPE_STRING:
2826 3187 VERIFY(0 == nvlist_add_string(dummy, propname, ""));
2827 3188 break;
2828 3189 case PROP_TYPE_NUMBER:
2829 3190 case PROP_TYPE_INDEX:
2830 3191 VERIFY(0 == nvlist_add_uint64(dummy, propname, 0));
2831 3192 break;
2832 3193 default:
2833 3194 nvlist_free(dummy);
2834 3195 return (SET_ERROR(EINVAL));
2835 3196 }
2836 3197
2837 3198 pair = nvlist_next_nvpair(dummy, NULL);
2838 3199 err = zfs_prop_set_special(zc->zc_name, source, pair);
2839 3200 nvlist_free(dummy);
2840 3201 if (err != -1)
2841 3202 return (err); /* special property already handled */
2842 3203 } else {
2843 3204 /*
2844 3205 * Only check this in the non-received case. We want to allow
2845 3206 * 'inherit -S' to revert non-inheritable properties like quota
2846 3207 * and reservation to the received or default values even though
2847 3208 * they are not considered inheritable.
2848 3209 */
2849 3210 if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
2850 3211 return (SET_ERROR(EINVAL));
2851 3212 }
2852 3213
2853 3214 /* property name has been validated by zfs_secpolicy_inherit_prop() */
|
↓ open down ↓ |
71 lines elided |
↑ open up ↑ |
2854 3215 return (dsl_prop_inherit(zc->zc_name, zc->zc_value, source));
2855 3216 }
2856 3217
2857 3218 static int
2858 3219 zfs_ioc_pool_set_props(zfs_cmd_t *zc)
2859 3220 {
2860 3221 nvlist_t *props;
2861 3222 spa_t *spa;
2862 3223 int error;
2863 3224 nvpair_t *pair;
2864 -
3225 + nvlist_t *event;
2865 3226 if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2866 3227 zc->zc_iflags, &props))
2867 3228 return (error);
2868 3229
2869 3230 /*
2870 3231 * If the only property is the configfile, then just do a spa_lookup()
2871 3232 * to handle the faulted case.
2872 3233 */
2873 3234 pair = nvlist_next_nvpair(props, NULL);
2874 3235 if (pair != NULL && strcmp(nvpair_name(pair),
2875 3236 zpool_prop_to_name(ZPOOL_PROP_CACHEFILE)) == 0 &&
2876 3237 nvlist_next_nvpair(props, pair) == NULL) {
2877 3238 mutex_enter(&spa_namespace_lock);
2878 3239 if ((spa = spa_lookup(zc->zc_name)) != NULL) {
2879 3240 spa_configfile_set(spa, props, B_FALSE);
2880 - spa_write_cachefile(spa, B_FALSE, B_TRUE);
3241 + spa_config_sync(spa, B_FALSE, B_TRUE);
2881 3242 }
2882 3243 mutex_exit(&spa_namespace_lock);
2883 3244 if (spa != NULL) {
2884 3245 nvlist_free(props);
2885 3246 return (0);
2886 3247 }
2887 3248 }
2888 3249
2889 3250 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
2890 3251 nvlist_free(props);
2891 3252 return (error);
2892 3253 }
2893 3254
2894 3255 error = spa_prop_set(spa, props);
2895 3256
3257 + if (error == 0) {
3258 + event = fnvlist_alloc();
3259 + fnvlist_add_string(event, "pool", zc->zc_name);
3260 + fnvlist_add_nvlist(event, "props", props);
3261 + zfs_event_post(ZPOOL_EC_STATUS, "set", event);
3262 + }
3263 +
2896 3264 nvlist_free(props);
2897 3265 spa_close(spa, FTAG);
2898 3266
2899 3267 return (error);
2900 3268 }
2901 3269
2902 3270 static int
2903 3271 zfs_ioc_pool_get_props(zfs_cmd_t *zc)
2904 3272 {
2905 3273 spa_t *spa;
2906 3274 int error;
2907 3275 nvlist_t *nvp = NULL;
2908 3276
2909 3277 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
2910 3278 /*
2911 3279 * If the pool is faulted, there may be properties we can still
2912 3280 * get (such as altroot and cachefile), so attempt to get them
2913 3281 * anyway.
2914 3282 */
2915 3283 mutex_enter(&spa_namespace_lock);
2916 3284 if ((spa = spa_lookup(zc->zc_name)) != NULL)
2917 3285 error = spa_prop_get(spa, &nvp);
2918 3286 mutex_exit(&spa_namespace_lock);
2919 3287 } else {
2920 3288 error = spa_prop_get(spa, &nvp);
2921 3289 spa_close(spa, FTAG);
2922 3290 }
2923 3291
2924 3292 if (error == 0 && zc->zc_nvlist_dst != NULL)
2925 3293 error = put_nvlist(zc, nvp);
2926 3294 else
2927 3295 error = SET_ERROR(EFAULT);
2928 3296
2929 3297 nvlist_free(nvp);
2930 3298 return (error);
2931 3299 }
2932 3300
2933 3301 /*
2934 3302 * inputs:
2935 3303 * zc_name name of filesystem
2936 3304 * zc_nvlist_src{_size} nvlist of delegated permissions
2937 3305 * zc_perm_action allow/unallow flag
2938 3306 *
2939 3307 * outputs: none
2940 3308 */
2941 3309 static int
2942 3310 zfs_ioc_set_fsacl(zfs_cmd_t *zc)
2943 3311 {
2944 3312 int error;
2945 3313 nvlist_t *fsaclnv = NULL;
2946 3314
2947 3315 if ((error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
2948 3316 zc->zc_iflags, &fsaclnv)) != 0)
2949 3317 return (error);
2950 3318
2951 3319 /*
2952 3320 * Verify nvlist is constructed correctly
2953 3321 */
2954 3322 if ((error = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
2955 3323 nvlist_free(fsaclnv);
2956 3324 return (SET_ERROR(EINVAL));
2957 3325 }
2958 3326
2959 3327 /*
2960 3328 * If we don't have PRIV_SYS_MOUNT, then validate
2961 3329 * that user is allowed to hand out each permission in
2962 3330 * the nvlist(s)
2963 3331 */
2964 3332
2965 3333 error = secpolicy_zfs(CRED());
2966 3334 if (error != 0) {
2967 3335 if (zc->zc_perm_action == B_FALSE) {
2968 3336 error = dsl_deleg_can_allow(zc->zc_name,
2969 3337 fsaclnv, CRED());
2970 3338 } else {
2971 3339 error = dsl_deleg_can_unallow(zc->zc_name,
2972 3340 fsaclnv, CRED());
2973 3341 }
2974 3342 }
2975 3343
2976 3344 if (error == 0)
2977 3345 error = dsl_deleg_set(zc->zc_name, fsaclnv, zc->zc_perm_action);
2978 3346
2979 3347 nvlist_free(fsaclnv);
2980 3348 return (error);
2981 3349 }
2982 3350
2983 3351 /*
2984 3352 * inputs:
2985 3353 * zc_name name of filesystem
2986 3354 *
2987 3355 * outputs:
2988 3356 * zc_nvlist_src{_size} nvlist of delegated permissions
2989 3357 */
2990 3358 static int
2991 3359 zfs_ioc_get_fsacl(zfs_cmd_t *zc)
2992 3360 {
2993 3361 nvlist_t *nvp;
2994 3362 int error;
2995 3363
2996 3364 if ((error = dsl_deleg_get(zc->zc_name, &nvp)) == 0) {
2997 3365 error = put_nvlist(zc, nvp);
2998 3366 nvlist_free(nvp);
2999 3367 }
3000 3368
3001 3369 return (error);
3002 3370 }
3003 3371
3004 3372 /* ARGSUSED */
3005 3373 static void
3006 3374 zfs_create_cb(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx)
|
↓ open down ↓ |
101 lines elided |
↑ open up ↑ |
3007 3375 {
3008 3376 zfs_creat_t *zct = arg;
3009 3377
3010 3378 zfs_create_fs(os, cr, zct->zct_zplprops, tx);
3011 3379 }
3012 3380
3013 3381 #define ZFS_PROP_UNDEFINED ((uint64_t)-1)
3014 3382
3015 3383 /*
3016 3384 * inputs:
3385 + * createprops list of properties requested by creator
3386 + * default_zplver zpl version to use if unspecified in createprops
3387 + * fuids_ok fuids allowed in this version of the spa?
3017 3388 * os parent objset pointer (NULL if root fs)
3018 3389 * fuids_ok fuids allowed in this version of the spa?
3019 3390 * sa_ok SAs allowed in this version of the spa?
3020 3391 * createprops list of properties requested by creator
3021 3392 *
3022 3393 * outputs:
3023 3394 * zplprops values for the zplprops we attach to the master node object
3024 3395 * is_ci true if requested file system will be purely case-insensitive
3025 3396 *
3026 3397 * Determine the settings for utf8only, normalization and
3027 3398 * casesensitivity. Specific values may have been requested by the
3028 3399 * creator and/or we can inherit values from the parent dataset. If
3029 3400 * the file system is of too early a vintage, a creator can not
3030 3401 * request settings for these properties, even if the requested
3031 3402 * setting is the default value. We don't actually want to create dsl
3032 3403 * properties for these, so remove them from the source nvlist after
3033 3404 * processing.
3034 3405 */
3035 3406 static int
3036 3407 zfs_fill_zplprops_impl(objset_t *os, uint64_t zplver,
3037 3408 boolean_t fuids_ok, boolean_t sa_ok, nvlist_t *createprops,
3038 3409 nvlist_t *zplprops, boolean_t *is_ci)
3039 3410 {
3040 3411 uint64_t sense = ZFS_PROP_UNDEFINED;
3041 3412 uint64_t norm = ZFS_PROP_UNDEFINED;
3042 3413 uint64_t u8 = ZFS_PROP_UNDEFINED;
3043 3414
3044 3415 ASSERT(zplprops != NULL);
3045 3416
3046 3417 if (os != NULL && os->os_phys->os_type != DMU_OST_ZFS)
3047 3418 return (SET_ERROR(EINVAL));
3048 3419
3049 3420 /*
3050 3421 * Pull out creator prop choices, if any.
3051 3422 */
3052 3423 if (createprops) {
3053 3424 (void) nvlist_lookup_uint64(createprops,
3054 3425 zfs_prop_to_name(ZFS_PROP_VERSION), &zplver);
3055 3426 (void) nvlist_lookup_uint64(createprops,
3056 3427 zfs_prop_to_name(ZFS_PROP_NORMALIZE), &norm);
3057 3428 (void) nvlist_remove_all(createprops,
3058 3429 zfs_prop_to_name(ZFS_PROP_NORMALIZE));
3059 3430 (void) nvlist_lookup_uint64(createprops,
3060 3431 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), &u8);
3061 3432 (void) nvlist_remove_all(createprops,
3062 3433 zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
3063 3434 (void) nvlist_lookup_uint64(createprops,
3064 3435 zfs_prop_to_name(ZFS_PROP_CASE), &sense);
3065 3436 (void) nvlist_remove_all(createprops,
3066 3437 zfs_prop_to_name(ZFS_PROP_CASE));
3067 3438 }
3068 3439
3069 3440 /*
3070 3441 * If the zpl version requested is whacky or the file system
3071 3442 * or pool is version is too "young" to support normalization
3072 3443 * and the creator tried to set a value for one of the props,
3073 3444 * error out.
3074 3445 */
3075 3446 if ((zplver < ZPL_VERSION_INITIAL || zplver > ZPL_VERSION) ||
3076 3447 (zplver >= ZPL_VERSION_FUID && !fuids_ok) ||
3077 3448 (zplver >= ZPL_VERSION_SA && !sa_ok) ||
3078 3449 (zplver < ZPL_VERSION_NORMALIZATION &&
3079 3450 (norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
3080 3451 sense != ZFS_PROP_UNDEFINED)))
3081 3452 return (SET_ERROR(ENOTSUP));
3082 3453
3083 3454 /*
|
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
3084 3455 * Put the version in the zplprops
3085 3456 */
3086 3457 VERIFY(nvlist_add_uint64(zplprops,
3087 3458 zfs_prop_to_name(ZFS_PROP_VERSION), zplver) == 0);
3088 3459
3089 3460 if (norm == ZFS_PROP_UNDEFINED)
3090 3461 VERIFY(zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &norm) == 0);
3091 3462 VERIFY(nvlist_add_uint64(zplprops,
3092 3463 zfs_prop_to_name(ZFS_PROP_NORMALIZE), norm) == 0);
3093 3464
3465 + if (os) {
3466 + if (zfs_is_wormed_ds(dmu_objset_ds(os)))
3467 + return (SET_ERROR(EPERM));
3468 + }
3469 +
3094 3470 /*
3095 3471 * If we're normalizing, names must always be valid UTF-8 strings.
3096 3472 */
3097 3473 if (norm)
3098 3474 u8 = 1;
3099 3475 if (u8 == ZFS_PROP_UNDEFINED)
3100 3476 VERIFY(zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &u8) == 0);
3101 3477 VERIFY(nvlist_add_uint64(zplprops,
3102 3478 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), u8) == 0);
3103 3479
3104 3480 if (sense == ZFS_PROP_UNDEFINED)
3105 3481 VERIFY(zfs_get_zplprop(os, ZFS_PROP_CASE, &sense) == 0);
3106 3482 VERIFY(nvlist_add_uint64(zplprops,
3107 3483 zfs_prop_to_name(ZFS_PROP_CASE), sense) == 0);
3108 3484
3109 3485 if (is_ci)
3110 3486 *is_ci = (sense == ZFS_CASE_INSENSITIVE);
3111 3487
3112 3488 return (0);
3113 3489 }
3114 3490
3115 3491 static int
3116 3492 zfs_fill_zplprops(const char *dataset, nvlist_t *createprops,
3117 3493 nvlist_t *zplprops, boolean_t *is_ci)
3118 3494 {
3119 3495 boolean_t fuids_ok, sa_ok;
3120 3496 uint64_t zplver = ZPL_VERSION;
3121 3497 objset_t *os = NULL;
3122 3498 char parentname[ZFS_MAX_DATASET_NAME_LEN];
3123 3499 char *cp;
3124 3500 spa_t *spa;
3125 3501 uint64_t spa_vers;
3126 3502 int error;
3127 3503
3128 3504 (void) strlcpy(parentname, dataset, sizeof (parentname));
3129 3505 cp = strrchr(parentname, '/');
3130 3506 ASSERT(cp != NULL);
3131 3507 cp[0] = '\0';
3132 3508
3133 3509 if ((error = spa_open(dataset, &spa, FTAG)) != 0)
3134 3510 return (error);
3135 3511
3136 3512 spa_vers = spa_version(spa);
3137 3513 spa_close(spa, FTAG);
3138 3514
3139 3515 zplver = zfs_zpl_version_map(spa_vers);
3140 3516 fuids_ok = (zplver >= ZPL_VERSION_FUID);
3141 3517 sa_ok = (zplver >= ZPL_VERSION_SA);
3142 3518
3143 3519 /*
3144 3520 * Open parent object set so we can inherit zplprop values.
3145 3521 */
3146 3522 if ((error = dmu_objset_hold(parentname, FTAG, &os)) != 0)
3147 3523 return (error);
3148 3524
3149 3525 error = zfs_fill_zplprops_impl(os, zplver, fuids_ok, sa_ok, createprops,
3150 3526 zplprops, is_ci);
3151 3527 dmu_objset_rele(os, FTAG);
3152 3528 return (error);
3153 3529 }
3154 3530
3155 3531 static int
3156 3532 zfs_fill_zplprops_root(uint64_t spa_vers, nvlist_t *createprops,
3157 3533 nvlist_t *zplprops, boolean_t *is_ci)
3158 3534 {
3159 3535 boolean_t fuids_ok;
3160 3536 boolean_t sa_ok;
3161 3537 uint64_t zplver = ZPL_VERSION;
3162 3538 int error;
3163 3539
3164 3540 zplver = zfs_zpl_version_map(spa_vers);
3165 3541 fuids_ok = (zplver >= ZPL_VERSION_FUID);
3166 3542 sa_ok = (zplver >= ZPL_VERSION_SA);
3167 3543
3168 3544 error = zfs_fill_zplprops_impl(NULL, zplver, fuids_ok, sa_ok,
3169 3545 createprops, zplprops, is_ci);
3170 3546 return (error);
3171 3547 }
3172 3548
3173 3549 /*
3174 3550 * innvl: {
3175 3551 * "type" -> dmu_objset_type_t (int32)
3176 3552 * (optional) "props" -> { prop -> value }
3177 3553 * }
3178 3554 *
3179 3555 * outnvl: propname -> error code (int32)
3180 3556 */
|
↓ open down ↓ |
77 lines elided |
↑ open up ↑ |
3181 3557 static int
3182 3558 zfs_ioc_create(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3183 3559 {
3184 3560 int error = 0;
3185 3561 zfs_creat_t zct = { 0 };
3186 3562 nvlist_t *nvprops = NULL;
3187 3563 void (*cbfunc)(objset_t *os, void *arg, cred_t *cr, dmu_tx_t *tx);
3188 3564 int32_t type32;
3189 3565 dmu_objset_type_t type;
3190 3566 boolean_t is_insensitive = B_FALSE;
3567 + char parent[MAXNAMELEN];
3568 + nvlist_t *event;
3191 3569
3192 3570 if (nvlist_lookup_int32(innvl, "type", &type32) != 0)
3193 3571 return (SET_ERROR(EINVAL));
3194 3572 type = type32;
3195 3573 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
3196 3574
3197 3575 switch (type) {
3198 3576 case DMU_OST_ZFS:
3199 3577 cbfunc = zfs_create_cb;
3200 3578 break;
3201 3579
3202 3580 case DMU_OST_ZVOL:
3203 3581 cbfunc = zvol_create_cb;
3204 3582 break;
3205 3583
3206 3584 default:
3207 3585 cbfunc = NULL;
3208 3586 break;
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
3209 3587 }
3210 3588 if (strchr(fsname, '@') ||
3211 3589 strchr(fsname, '%'))
3212 3590 return (SET_ERROR(EINVAL));
3213 3591
3214 3592 zct.zct_props = nvprops;
3215 3593
3216 3594 if (cbfunc == NULL)
3217 3595 return (SET_ERROR(EINVAL));
3218 3596
3597 + if (zfs_get_parent(fsname, parent, MAXNAMELEN) == 0 &&
3598 + zfs_is_wormed(parent)) {
3599 + return (SET_ERROR(EPERM));
3600 + }
3601 +
3219 3602 if (type == DMU_OST_ZVOL) {
3220 3603 uint64_t volsize, volblocksize;
3221 3604
3222 3605 if (nvprops == NULL)
3223 3606 return (SET_ERROR(EINVAL));
3224 3607 if (nvlist_lookup_uint64(nvprops,
3225 3608 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
3226 3609 return (SET_ERROR(EINVAL));
3227 3610
3228 3611 if ((error = nvlist_lookup_uint64(nvprops,
3229 3612 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3230 3613 &volblocksize)) != 0 && error != ENOENT)
3231 3614 return (SET_ERROR(EINVAL));
3232 3615
|
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
3233 3616 if (error != 0)
3234 3617 volblocksize = zfs_prop_default_numeric(
3235 3618 ZFS_PROP_VOLBLOCKSIZE);
3236 3619
3237 3620 if ((error = zvol_check_volblocksize(
3238 3621 volblocksize)) != 0 ||
3239 3622 (error = zvol_check_volsize(volsize,
3240 3623 volblocksize)) != 0)
3241 3624 return (error);
3242 3625 } else if (type == DMU_OST_ZFS) {
3243 - int error;
3244 -
3245 3626 /*
3246 3627 * We have to have normalization and
3247 3628 * case-folding flags correct when we do the
3248 3629 * file system creation, so go figure them out
3249 3630 * now.
3250 3631 */
3251 3632 VERIFY(nvlist_alloc(&zct.zct_zplprops,
3252 3633 NV_UNIQUE_NAME, KM_SLEEP) == 0);
3253 3634 error = zfs_fill_zplprops(fsname, nvprops,
3254 3635 zct.zct_zplprops, &is_insensitive);
3255 3636 if (error != 0) {
3256 3637 nvlist_free(zct.zct_zplprops);
3257 3638 return (error);
3258 3639 }
3259 3640 }
3260 3641
3261 3642 error = dmu_objset_create(fsname, type,
3262 3643 is_insensitive ? DS_FLAG_CI_DATASET : 0, cbfunc, &zct);
3263 3644 nvlist_free(zct.zct_zplprops);
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
3264 3645
3265 3646 /*
3266 3647 * It would be nice to do this atomically.
3267 3648 */
3268 3649 if (error == 0) {
3269 3650 error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
3270 3651 nvprops, outnvl);
3271 3652 if (error != 0)
3272 3653 (void) dsl_destroy_head(fsname);
3273 3654 }
3655 +
3656 + if (error == 0) {
3657 + event = fnvlist_alloc();
3658 + fnvlist_add_string(event, "fsname", fsname);
3659 + fnvlist_add_int32(event, "type", type);
3660 + if (nvprops != NULL)
3661 + fnvlist_add_nvlist(event, "properties", nvprops);
3662 + zfs_event_post(ZFS_EC_STATUS, "create", event);
3663 + }
3664 +
3274 3665 return (error);
3275 3666 }
3276 3667
3277 3668 /*
3278 3669 * innvl: {
3279 3670 * "origin" -> name of origin snapshot
3280 3671 * (optional) "props" -> { prop -> value }
3281 3672 * }
3282 3673 *
3283 3674 * outnvl: propname -> error code (int32)
3284 3675 */
3285 3676 static int
3286 3677 zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3287 3678 {
3288 3679 int error = 0;
3289 3680 nvlist_t *nvprops = NULL;
3290 - char *origin_name;
3681 + char *origin_name, *origin_snap;
3682 + nvlist_t *event;
3291 3683
3292 3684 if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0)
3293 3685 return (SET_ERROR(EINVAL));
3686 +
3687 + origin_snap = strchr(origin_name, '@');
3688 + if (!origin_snap)
3689 + return (SET_ERROR(EINVAL));
3690 +
3691 + if (autosnap_check_name(origin_snap))
3692 + return (SET_ERROR(EPERM));
3693 +
3294 3694 (void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
3295 3695
3296 3696 if (strchr(fsname, '@') ||
3297 3697 strchr(fsname, '%'))
3298 3698 return (SET_ERROR(EINVAL));
3299 3699
3300 3700 if (dataset_namecheck(origin_name, NULL, NULL) != 0)
3301 3701 return (SET_ERROR(EINVAL));
3702 +
3302 3703 error = dmu_objset_clone(fsname, origin_name);
3303 3704 if (error != 0)
3304 3705 return (error);
3305 3706
3306 3707 /*
3307 3708 * It would be nice to do this atomically.
3308 3709 */
3309 3710 if (error == 0) {
3310 3711 error = zfs_set_prop_nvlist(fsname, ZPROP_SRC_LOCAL,
3311 3712 nvprops, outnvl);
3312 3713 if (error != 0)
3313 3714 (void) dsl_destroy_head(fsname);
3314 3715 }
3315 - return (error);
3316 -}
3317 3716
3318 -/* ARGSUSED */
3319 -static int
3320 -zfs_ioc_remap(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3321 -{
3322 - if (strchr(fsname, '@') ||
3323 - strchr(fsname, '%'))
3324 - return (SET_ERROR(EINVAL));
3717 + if (error == 0) {
3718 + event = fnvlist_alloc();
3719 + fnvlist_add_string(event, "origin", origin_name);
3720 + fnvlist_add_string(event, "fsname", fsname);
3721 + if (nvprops != NULL)
3722 + fnvlist_add_nvlist(event, "properties", nvprops);
3723 + zfs_event_post(ZFS_EC_STATUS, "clone", event);
3724 + }
3325 3725
3326 - return (dmu_objset_remap_indirects(fsname));
3726 + return (error);
3327 3727 }
3328 3728
3329 3729 /*
3330 3730 * innvl: {
3331 3731 * "snaps" -> { snapshot1, snapshot2 }
3332 3732 * (optional) "props" -> { prop -> value (string) }
3333 3733 * }
3334 3734 *
3335 3735 * outnvl: snapshot -> error code (int32)
3336 3736 */
3337 3737 static int
3338 3738 zfs_ioc_snapshot(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
3339 3739 {
3340 3740 nvlist_t *snaps;
3341 3741 nvlist_t *props = NULL;
3342 3742 int error, poollen;
3343 3743 nvpair_t *pair;
3744 + nvlist_t *event;
3344 3745
3345 3746 (void) nvlist_lookup_nvlist(innvl, "props", &props);
3346 3747 if ((error = zfs_check_userprops(poolname, props)) != 0)
3347 3748 return (error);
3348 3749
3349 3750 if (!nvlist_empty(props) &&
3350 3751 zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
3351 3752 return (SET_ERROR(ENOTSUP));
3352 3753
3353 3754 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
3354 3755 return (SET_ERROR(EINVAL));
3355 3756 poollen = strlen(poolname);
3356 3757 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
3357 3758 pair = nvlist_next_nvpair(snaps, pair)) {
3358 3759 const char *name = nvpair_name(pair);
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
3359 3760 const char *cp = strchr(name, '@');
3360 3761
3361 3762 /*
3362 3763 * The snap name must contain an @, and the part after it must
3363 3764 * contain only valid characters.
3364 3765 */
3365 3766 if (cp == NULL ||
3366 3767 zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
3367 3768 return (SET_ERROR(EINVAL));
3368 3769
3770 + if (autosnap_check_name(cp))
3771 + return (EINVAL);
3772 +
3369 3773 /*
3370 3774 * The snap must be in the specified pool.
3371 3775 */
3372 3776 if (strncmp(name, poolname, poollen) != 0 ||
3373 3777 (name[poollen] != '/' && name[poollen] != '@'))
3374 3778 return (SET_ERROR(EXDEV));
3375 3779
3376 3780 /* This must be the only snap of this fs. */
3377 3781 for (nvpair_t *pair2 = nvlist_next_nvpair(snaps, pair);
3378 3782 pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
3379 3783 if (strncmp(name, nvpair_name(pair2), cp - name + 1)
3380 3784 == 0) {
3381 3785 return (SET_ERROR(EXDEV));
3382 3786 }
3383 3787 }
3384 3788 }
3385 3789
3386 3790 error = dsl_dataset_snapshot(snaps, props, outnvl);
3791 +
3792 + event = fnvlist_alloc();
3793 + fnvlist_add_nvlist(event, "snaps", snaps);
3794 + fnvlist_add_nvlist(event, "errors", outnvl);
3795 + fnvlist_add_string(event, "pool", poolname);
3796 + zfs_event_post(ZFS_EC_STATUS, "snapshot", event);
3797 +
3387 3798 return (error);
3388 3799 }
3389 3800
3390 3801 /*
3391 3802 * innvl: "message" -> string
3392 3803 */
3393 3804 /* ARGSUSED */
3394 3805 static int
3395 3806 zfs_ioc_log_history(const char *unused, nvlist_t *innvl, nvlist_t *outnvl)
3396 3807 {
3397 3808 char *message;
3398 3809 spa_t *spa;
3399 3810 int error;
3400 3811 char *poolname;
3401 3812
3402 3813 /*
3403 3814 * The poolname in the ioctl is not set, we get it from the TSD,
3404 3815 * which was set at the end of the last successful ioctl that allows
3405 3816 * logging. The secpolicy func already checked that it is set.
3406 3817 * Only one log ioctl is allowed after each successful ioctl, so
3407 3818 * we clear the TSD here.
3408 3819 */
3409 3820 poolname = tsd_get(zfs_allow_log_key);
3410 3821 (void) tsd_set(zfs_allow_log_key, NULL);
3411 3822 error = spa_open(poolname, &spa, FTAG);
3412 3823 strfree(poolname);
3413 3824 if (error != 0)
3414 3825 return (error);
3415 3826
3416 3827 if (nvlist_lookup_string(innvl, "message", &message) != 0) {
3417 3828 spa_close(spa, FTAG);
3418 3829 return (SET_ERROR(EINVAL));
3419 3830 }
3420 3831
3421 3832 if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
3422 3833 spa_close(spa, FTAG);
3423 3834 return (SET_ERROR(ENOTSUP));
3424 3835 }
3425 3836
3426 3837 error = spa_history_log(spa, message);
3427 3838 spa_close(spa, FTAG);
3428 3839 return (error);
3429 3840 }
3430 3841
3431 3842 /*
3432 3843 * The dp_config_rwlock must not be held when calling this, because the
3433 3844 * unmount may need to write out data.
3434 3845 *
3435 3846 * This function is best-effort. Callers must deal gracefully if it
3436 3847 * remains mounted (or is remounted after this call).
3437 3848 *
3438 3849 * Returns 0 if the argument is not a snapshot, or it is not currently a
3439 3850 * filesystem, or we were able to unmount it. Returns error code otherwise.
3440 3851 */
3441 3852 void
3442 3853 zfs_unmount_snap(const char *snapname)
3443 3854 {
3444 3855 vfs_t *vfsp = NULL;
3445 3856 zfsvfs_t *zfsvfs = NULL;
3446 3857
3447 3858 if (strchr(snapname, '@') == NULL)
3448 3859 return;
3449 3860
3450 3861 int err = getzfsvfs(snapname, &zfsvfs);
3451 3862 if (err != 0) {
3452 3863 ASSERT3P(zfsvfs, ==, NULL);
3453 3864 return;
3454 3865 }
3455 3866 vfsp = zfsvfs->z_vfs;
3456 3867
3457 3868 ASSERT(!dsl_pool_config_held(dmu_objset_pool(zfsvfs->z_os)));
3458 3869
3459 3870 err = vn_vfswlock(vfsp->vfs_vnodecovered);
3460 3871 VFS_RELE(vfsp);
3461 3872 if (err != 0)
3462 3873 return;
3463 3874
3464 3875 /*
3465 3876 * Always force the unmount for snapshots.
3466 3877 */
3467 3878 (void) dounmount(vfsp, MS_FORCE, kcred);
3468 3879 }
3469 3880
3470 3881 /* ARGSUSED */
3471 3882 static int
3472 3883 zfs_unmount_snap_cb(const char *snapname, void *arg)
3473 3884 {
3474 3885 zfs_unmount_snap(snapname);
3475 3886 return (0);
3476 3887 }
3477 3888
3478 3889 /*
3479 3890 * When a clone is destroyed, its origin may also need to be destroyed,
3480 3891 * in which case it must be unmounted. This routine will do that unmount
3481 3892 * if necessary.
3482 3893 */
3483 3894 void
3484 3895 zfs_destroy_unmount_origin(const char *fsname)
3485 3896 {
3486 3897 int error;
3487 3898 objset_t *os;
3488 3899 dsl_dataset_t *ds;
3489 3900
3490 3901 error = dmu_objset_hold(fsname, FTAG, &os);
3491 3902 if (error != 0)
3492 3903 return;
3493 3904 ds = dmu_objset_ds(os);
|
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
3494 3905 if (dsl_dir_is_clone(ds->ds_dir) && DS_IS_DEFER_DESTROY(ds->ds_prev)) {
3495 3906 char originname[ZFS_MAX_DATASET_NAME_LEN];
3496 3907 dsl_dataset_name(ds->ds_prev, originname);
3497 3908 dmu_objset_rele(os, FTAG);
3498 3909 zfs_unmount_snap(originname);
3499 3910 } else {
3500 3911 dmu_objset_rele(os, FTAG);
3501 3912 }
3502 3913 }
3503 3914
3915 +static int
3916 +zfs_destroy_check_autosnap(spa_t *spa, const char *name)
3917 +{
3918 + const char *snap = strchr(name, '@');
3919 +
3920 + if (snap == NULL)
3921 + return (EINVAL);
3922 +
3923 + if (autosnap_check_name(snap)) {
3924 + int err = autosnap_check_for_destroy(
3925 + spa_get_autosnap(spa), name);
3926 +
3927 + if (err != 0)
3928 + return (EBUSY);
3929 + }
3930 +
3931 + return (0);
3932 +}
3933 +
3504 3934 /*
3505 3935 * innvl: {
3506 3936 * "snaps" -> { snapshot1, snapshot2 }
3507 3937 * (optional boolean) "defer"
3508 3938 * }
3509 3939 *
3510 3940 * outnvl: snapshot -> error code (int32)
3511 3941 *
3512 3942 */
3513 3943 /* ARGSUSED */
3514 3944 static int
3515 3945 zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
3516 3946 {
3517 3947 nvlist_t *snaps;
3518 3948 nvpair_t *pair;
3519 3949 boolean_t defer;
3950 + int error = 0;
3951 + nvlist_t *event;
3952 + spa_t *spa;
3520 3953
3954 + if (zfs_is_wormed(poolname))
3955 + return (SET_ERROR(EPERM));
3956 +
3521 3957 if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
3522 3958 return (SET_ERROR(EINVAL));
3523 3959 defer = nvlist_exists(innvl, "defer");
3524 3960
3961 + error = spa_open(poolname, &spa, FTAG);
3962 + if (spa == NULL)
3963 + return (error);
3964 +
3965 + for (pair = nvlist_next_nvpair(snaps, NULL);
3966 + pair != NULL; pair = nvlist_next_nvpair(snaps, pair)) {
3967 + error = zfs_destroy_check_autosnap(spa, nvpair_name(pair));
3968 + if (error)
3969 + fnvlist_add_int32(outnvl, nvpair_name(pair), error);
3970 + }
3971 +
3972 + spa_close(spa, FTAG);
3973 +
3974 + if (error)
3975 + return (error);
3976 +
3525 3977 for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
3526 3978 pair = nvlist_next_nvpair(snaps, pair)) {
3527 3979 zfs_unmount_snap(nvpair_name(pair));
3528 3980 }
3529 3981
3530 - return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl));
3982 + error = dsl_destroy_snapshots_nvl(snaps, defer, outnvl);
3983 +
3984 + if (error == 0) {
3985 + event = fnvlist_alloc();
3986 + fnvlist_add_nvlist(event, "snaps", snaps);
3987 + fnvlist_add_nvlist(event, "errors", outnvl);
3988 + zfs_event_post(ZFS_EC_STATUS, "destroy_snaps", event);
3989 + }
3990 +
3991 + return (error);
3531 3992 }
3532 3993
3533 3994 /*
3534 3995 * Create bookmarks. Bookmark names are of the form <fs>#<bmark>.
3535 3996 * All bookmarks must be in the same pool.
3536 3997 *
3537 3998 * innvl: {
3538 3999 * bookmark1 -> snapshot1, bookmark2 -> snapshot2
3539 4000 * }
3540 4001 *
3541 4002 * outnvl: bookmark -> error code (int32)
3542 4003 *
3543 4004 */
3544 4005 /* ARGSUSED */
3545 4006 static int
3546 4007 zfs_ioc_bookmark(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
3547 4008 {
3548 4009 for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
3549 4010 pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
3550 4011 char *snap_name;
3551 4012
3552 4013 /*
3553 4014 * Verify the snapshot argument.
3554 4015 */
3555 4016 if (nvpair_value_string(pair, &snap_name) != 0)
3556 4017 return (SET_ERROR(EINVAL));
3557 4018
3558 4019
3559 4020 /* Verify that the keys (bookmarks) are unique */
3560 4021 for (nvpair_t *pair2 = nvlist_next_nvpair(innvl, pair);
3561 4022 pair2 != NULL; pair2 = nvlist_next_nvpair(innvl, pair2)) {
3562 4023 if (strcmp(nvpair_name(pair), nvpair_name(pair2)) == 0)
3563 4024 return (SET_ERROR(EINVAL));
3564 4025 }
3565 4026 }
3566 4027
3567 4028 return (dsl_bookmark_create(innvl, outnvl));
3568 4029 }
3569 4030
3570 4031 /*
3571 4032 * innvl: {
3572 4033 * property 1, property 2, ...
3573 4034 * }
3574 4035 *
3575 4036 * outnvl: {
3576 4037 * bookmark name 1 -> { property 1, property 2, ... },
3577 4038 * bookmark name 2 -> { property 1, property 2, ... }
3578 4039 * }
3579 4040 *
3580 4041 */
3581 4042 static int
3582 4043 zfs_ioc_get_bookmarks(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3583 4044 {
3584 4045 return (dsl_get_bookmarks(fsname, innvl, outnvl));
3585 4046 }
3586 4047
3587 4048 /*
3588 4049 * innvl: {
3589 4050 * bookmark name 1, bookmark name 2
3590 4051 * }
3591 4052 *
3592 4053 * outnvl: bookmark -> error code (int32)
3593 4054 *
3594 4055 */
3595 4056 static int
3596 4057 zfs_ioc_destroy_bookmarks(const char *poolname, nvlist_t *innvl,
3597 4058 nvlist_t *outnvl)
3598 4059 {
3599 4060 int error, poollen;
3600 4061
3601 4062 poollen = strlen(poolname);
3602 4063 for (nvpair_t *pair = nvlist_next_nvpair(innvl, NULL);
3603 4064 pair != NULL; pair = nvlist_next_nvpair(innvl, pair)) {
3604 4065 const char *name = nvpair_name(pair);
3605 4066 const char *cp = strchr(name, '#');
3606 4067
3607 4068 /*
3608 4069 * The bookmark name must contain an #, and the part after it
3609 4070 * must contain only valid characters.
3610 4071 */
3611 4072 if (cp == NULL ||
3612 4073 zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
3613 4074 return (SET_ERROR(EINVAL));
3614 4075
3615 4076 /*
3616 4077 * The bookmark must be in the specified pool.
3617 4078 */
3618 4079 if (strncmp(name, poolname, poollen) != 0 ||
3619 4080 (name[poollen] != '/' && name[poollen] != '#'))
3620 4081 return (SET_ERROR(EXDEV));
3621 4082 }
3622 4083
3623 4084 error = dsl_bookmark_destroy(innvl, outnvl);
3624 4085 return (error);
3625 4086 }
3626 4087
3627 4088 static int
3628 4089 zfs_ioc_channel_program(const char *poolname, nvlist_t *innvl,
3629 4090 nvlist_t *outnvl)
3630 4091 {
3631 4092 char *program;
3632 4093 uint64_t instrlimit, memlimit;
3633 4094 boolean_t sync_flag;
3634 4095 nvpair_t *nvarg = NULL;
3635 4096
3636 4097 if (0 != nvlist_lookup_string(innvl, ZCP_ARG_PROGRAM, &program)) {
3637 4098 return (EINVAL);
3638 4099 }
3639 4100 if (0 != nvlist_lookup_boolean_value(innvl, ZCP_ARG_SYNC, &sync_flag)) {
3640 4101 sync_flag = B_TRUE;
3641 4102 }
3642 4103 if (0 != nvlist_lookup_uint64(innvl, ZCP_ARG_INSTRLIMIT, &instrlimit)) {
3643 4104 instrlimit = ZCP_DEFAULT_INSTRLIMIT;
3644 4105 }
3645 4106 if (0 != nvlist_lookup_uint64(innvl, ZCP_ARG_MEMLIMIT, &memlimit)) {
3646 4107 memlimit = ZCP_DEFAULT_MEMLIMIT;
3647 4108 }
3648 4109 if (0 != nvlist_lookup_nvpair(innvl, ZCP_ARG_ARGLIST, &nvarg)) {
3649 4110 return (EINVAL);
3650 4111 }
3651 4112
3652 4113 if (instrlimit == 0 || instrlimit > zfs_lua_max_instrlimit)
3653 4114 return (EINVAL);
3654 4115 if (memlimit == 0 || memlimit > zfs_lua_max_memlimit)
3655 4116 return (EINVAL);
|
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
3656 4117
3657 4118 return (zcp_eval(poolname, program, sync_flag, instrlimit, memlimit,
3658 4119 nvarg, outnvl));
3659 4120 }
3660 4121
3661 4122 /*
3662 4123 * inputs:
3663 4124 * zc_name name of dataset to destroy
3664 4125 * zc_objset_type type of objset
3665 4126 * zc_defer_destroy mark for deferred destroy
4127 + * zc_guid if set, do atomical recursive destroy
3666 4128 *
3667 4129 * outputs: none
3668 4130 */
3669 4131 static int
3670 4132 zfs_ioc_destroy(zfs_cmd_t *zc)
3671 4133 {
3672 4134 int err;
4135 + nvlist_t *event;
3673 4136
4137 + if (zfs_is_wormed(zc->zc_name))
4138 + return (SET_ERROR(EPERM));
4139 +
3674 4140 if (zc->zc_objset_type == DMU_OST_ZFS)
3675 4141 zfs_unmount_snap(zc->zc_name);
3676 4142
3677 - if (strchr(zc->zc_name, '@'))
3678 - err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
3679 - else
3680 - err = dsl_destroy_head(zc->zc_name);
4143 + if (zc->zc_guid) {
4144 + spa_t *spa;
4145 +
4146 + if ((err = spa_open(zc->zc_name, &spa, FTAG)) != 0)
4147 + return (err);
4148 +
4149 + err = autosnap_lock(spa, RW_WRITER);
4150 + if (err == 0) {
4151 + err = wbc_walk_lock(spa);
4152 + if (err != 0)
4153 + autosnap_unlock(spa);
4154 + }
4155 +
4156 + if (err == 0) {
4157 + err = dsl_destroy_atomically(zc->zc_name,
4158 + zc->zc_defer_destroy);
4159 + wbc_walk_unlock(spa);
4160 + autosnap_unlock(spa);
4161 + }
4162 +
4163 + spa_close(spa, FTAG);
4164 + } else {
4165 + if (strchr(zc->zc_name, '@')) {
4166 + spa_t *spa = NULL;
4167 +
4168 + err = spa_open(zc->zc_name, &spa, FTAG);
4169 + if (err != 0)
4170 + return (err);
4171 +
4172 + err = zfs_destroy_check_autosnap(spa, zc->zc_name);
4173 + if (err == 0) {
4174 + err = dsl_destroy_snapshot(zc->zc_name,
4175 + zc->zc_defer_destroy);
4176 + }
4177 +
4178 + spa_close(spa, FTAG);
4179 + } else {
4180 + err = dsl_destroy_head(zc->zc_name);
4181 + if (err == EEXIST) {
4182 + /*
4183 + * It is possible that the given DS may have
4184 + * hidden child (%recv) datasets - "leftovers"
4185 + * resulting from the previously interrupted
4186 + * 'zfs receive'.
4187 + */
4188 + char namebuf[ZFS_MAX_DATASET_NAME_LEN];
4189 +
4190 + if (snprintf(namebuf, sizeof (namebuf),
4191 + "%s/%%recv", zc->zc_name) >=
4192 + sizeof (namebuf))
4193 + return (err);
4194 +
4195 + /* Try to remove the hidden child (%recv) */
4196 + err = dsl_destroy_head(namebuf);
4197 + if (err == 0) {
4198 + /*
4199 + * Now the given DS should not have
4200 + * children, so we can try to remove
4201 + * it again
4202 + */
4203 + err = dsl_destroy_head(zc->zc_name);
4204 + } else if (err == ENOENT) {
4205 + /*
4206 + * The hidden child (%recv) does not
4207 + * exist, so need to restore original
4208 + * error
4209 + */
4210 + err = EEXIST;
4211 + }
4212 +
4213 + }
4214 + }
4215 + }
3681 4216 if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0)
3682 4217 (void) zvol_remove_minor(zc->zc_name);
4218 +
4219 + if (err == 0) {
4220 + event = fnvlist_alloc();
4221 + fnvlist_add_string(event, "fsname", zc->zc_name);
4222 + fnvlist_add_int32(event, "type", zc->zc_objset_type);
4223 + zfs_event_post(ZFS_EC_STATUS, "destroy", event);
4224 + }
4225 +
3683 4226 return (err);
3684 4227 }
3685 4228
3686 4229 /*
3687 4230 * fsname is name of dataset to rollback (to most recent snapshot)
3688 4231 *
3689 4232 * innvl may contain name of expected target snapshot
3690 4233 *
3691 4234 * outnvl: "target" -> name of most recent snapshot
3692 4235 * }
3693 4236 */
3694 4237 /* ARGSUSED */
3695 4238 static int
3696 4239 zfs_ioc_rollback(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
3697 4240 {
3698 4241 zfsvfs_t *zfsvfs;
3699 4242 char *target = NULL;
3700 4243 int error;
4244 + nvlist_t *event;
4245 + int resume_err = 0;
3701 4246
4247 + if (zfs_is_wormed(fsname))
4248 + return (SET_ERROR(EPERM));
4249 +
3702 4250 (void) nvlist_lookup_string(innvl, "target", &target);
3703 4251 if (target != NULL) {
3704 4252 const char *cp = strchr(target, '@');
3705 4253
3706 4254 /*
3707 4255 * The snap name must contain an @, and the part after it must
3708 4256 * contain only valid characters.
3709 4257 */
3710 4258 if (cp == NULL ||
3711 4259 zfs_component_namecheck(cp + 1, NULL, NULL) != 0)
3712 4260 return (SET_ERROR(EINVAL));
3713 4261 }
3714 4262
3715 4263 if (getzfsvfs(fsname, &zfsvfs) == 0) {
3716 4264 dsl_dataset_t *ds;
3717 4265
3718 4266 ds = dmu_objset_ds(zfsvfs->z_os);
3719 4267 error = zfs_suspend_fs(zfsvfs);
3720 4268 if (error == 0) {
3721 - int resume_err;
3722 -
3723 4269 error = dsl_dataset_rollback(fsname, target, zfsvfs,
3724 4270 outnvl);
3725 4271 resume_err = zfs_resume_fs(zfsvfs, ds);
3726 - error = error ? error : resume_err;
3727 4272 }
3728 4273 VFS_RELE(zfsvfs->z_vfs);
3729 4274 } else {
3730 4275 error = dsl_dataset_rollback(fsname, target, NULL, outnvl);
3731 4276 }
4277 +
4278 + if (error == 0) {
4279 + event = fnvlist_alloc();
4280 + fnvlist_add_string(event, "target", (target != NULL) ? target : "");
4281 + fnvlist_add_string(event, "fsname", fsname);
4282 + fnvlist_add_int32(event, "resume_err", resume_err);
4283 + zfs_event_post(ZFS_EC_STATUS, "rollback", event);
4284 + }
4285 +
4286 + error = (error != 0) ? error : resume_err;
3732 4287 return (error);
3733 4288 }
3734 4289
3735 4290 static int
3736 4291 recursive_unmount(const char *fsname, void *arg)
3737 4292 {
3738 4293 const char *snapname = arg;
3739 4294 char fullname[ZFS_MAX_DATASET_NAME_LEN];
3740 4295
3741 4296 (void) snprintf(fullname, sizeof (fullname), "%s@%s", fsname, snapname);
3742 4297 zfs_unmount_snap(fullname);
3743 4298
3744 4299 return (0);
3745 4300 }
3746 4301
3747 4302 /*
3748 4303 * inputs:
3749 4304 * zc_name old name of dataset
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
3750 4305 * zc_value new name of dataset
3751 4306 * zc_cookie recursive flag (only valid for snapshots)
3752 4307 *
3753 4308 * outputs: none
3754 4309 */
3755 4310 static int
3756 4311 zfs_ioc_rename(zfs_cmd_t *zc)
3757 4312 {
3758 4313 boolean_t recursive = zc->zc_cookie & 1;
3759 4314 char *at;
4315 + nvlist_t *event;
4316 + int error;
3760 4317
3761 - /* "zfs rename" from and to ...%recv datasets should both fail */
3762 - zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
4318 + if (zfs_is_wormed(zc->zc_name))
4319 + return (SET_ERROR(EPERM));
4320 +
3763 4321 zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
3764 - if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0 ||
3765 - dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
3766 - strchr(zc->zc_name, '%') || strchr(zc->zc_value, '%'))
4322 + if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
4323 + strchr(zc->zc_value, '%'))
3767 4324 return (SET_ERROR(EINVAL));
3768 4325
3769 4326 at = strchr(zc->zc_name, '@');
3770 4327 if (at != NULL) {
3771 4328 /* snaps must be in same fs */
3772 - int error;
3773 4329
3774 4330 if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
3775 4331 return (SET_ERROR(EXDEV));
3776 4332 *at = '\0';
3777 4333 if (zc->zc_objset_type == DMU_OST_ZFS) {
3778 4334 error = dmu_objset_find(zc->zc_name,
3779 4335 recursive_unmount, at + 1,
3780 4336 recursive ? DS_FIND_CHILDREN : 0);
3781 4337 if (error != 0) {
3782 4338 *at = '@';
3783 4339 return (error);
3784 4340 }
3785 4341 }
3786 4342 error = dsl_dataset_rename_snapshot(zc->zc_name,
3787 4343 at + 1, strchr(zc->zc_value, '@') + 1, recursive);
3788 4344 *at = '@';
3789 4345
3790 - return (error);
3791 4346 } else {
3792 4347 if (zc->zc_objset_type == DMU_OST_ZVOL)
3793 4348 (void) zvol_remove_minor(zc->zc_name);
3794 - return (dsl_dir_rename(zc->zc_name, zc->zc_value));
4349 + error = dsl_dir_rename(zc->zc_name, zc->zc_value);
3795 4350 }
4351 +
4352 + if (error == 0) {
4353 + event = fnvlist_alloc();
4354 + fnvlist_add_string(event, "origin", zc->zc_name);
4355 + fnvlist_add_string(event, "fsname", zc->zc_value);
4356 + fnvlist_add_int32(event, "type", zc->zc_objset_type);
4357 + zfs_event_post(ZFS_EC_STATUS, "rename", event);
4358 + }
4359 +
4360 + return (error);
3796 4361 }
3797 4362
3798 4363 static int
3799 4364 zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
3800 4365 {
3801 4366 const char *propname = nvpair_name(pair);
3802 4367 boolean_t issnap = (strchr(dsname, '@') != NULL);
3803 4368 zfs_prop_t prop = zfs_name_to_prop(propname);
3804 4369 uint64_t intval;
3805 4370 int err;
3806 4371
3807 4372 if (prop == ZPROP_INVAL) {
3808 4373 if (zfs_prop_user(propname)) {
3809 4374 if (err = zfs_secpolicy_write_perms(dsname,
3810 4375 ZFS_DELEG_PERM_USERPROP, cr))
3811 4376 return (err);
3812 4377 return (0);
3813 4378 }
3814 4379
3815 4380 if (!issnap && zfs_prop_userquota(propname)) {
3816 4381 const char *perm = NULL;
3817 4382 const char *uq_prefix =
3818 4383 zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
3819 4384 const char *gq_prefix =
3820 4385 zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
3821 4386
3822 4387 if (strncmp(propname, uq_prefix,
3823 4388 strlen(uq_prefix)) == 0) {
3824 4389 perm = ZFS_DELEG_PERM_USERQUOTA;
3825 4390 } else if (strncmp(propname, gq_prefix,
3826 4391 strlen(gq_prefix)) == 0) {
3827 4392 perm = ZFS_DELEG_PERM_GROUPQUOTA;
3828 4393 } else {
3829 4394 /* USERUSED and GROUPUSED are read-only */
3830 4395 return (SET_ERROR(EINVAL));
3831 4396 }
3832 4397
3833 4398 if (err = zfs_secpolicy_write_perms(dsname, perm, cr))
3834 4399 return (err);
3835 4400 return (0);
3836 4401 }
3837 4402
3838 4403 return (SET_ERROR(EINVAL));
3839 4404 }
3840 4405
3841 4406 if (issnap)
3842 4407 return (SET_ERROR(EINVAL));
3843 4408
3844 4409 if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
3845 4410 /*
3846 4411 * dsl_prop_get_all_impl() returns properties in this
3847 4412 * format.
3848 4413 */
3849 4414 nvlist_t *attrs;
3850 4415 VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
3851 4416 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
3852 4417 &pair) == 0);
3853 4418 }
3854 4419
3855 4420 /*
3856 4421 * Check that this value is valid for this pool version
3857 4422 */
3858 4423 switch (prop) {
3859 4424 case ZFS_PROP_COMPRESSION:
3860 4425 /*
3861 4426 * If the user specified gzip compression, make sure
3862 4427 * the SPA supports it. We ignore any errors here since
3863 4428 * we'll catch them later.
3864 4429 */
3865 4430 if (nvpair_value_uint64(pair, &intval) == 0) {
3866 4431 if (intval >= ZIO_COMPRESS_GZIP_1 &&
3867 4432 intval <= ZIO_COMPRESS_GZIP_9 &&
3868 4433 zfs_earlier_version(dsname,
3869 4434 SPA_VERSION_GZIP_COMPRESSION)) {
3870 4435 return (SET_ERROR(ENOTSUP));
3871 4436 }
3872 4437
3873 4438 if (intval == ZIO_COMPRESS_ZLE &&
3874 4439 zfs_earlier_version(dsname,
3875 4440 SPA_VERSION_ZLE_COMPRESSION))
3876 4441 return (SET_ERROR(ENOTSUP));
3877 4442
3878 4443 if (intval == ZIO_COMPRESS_LZ4) {
3879 4444 spa_t *spa;
3880 4445
3881 4446 if ((err = spa_open(dsname, &spa, FTAG)) != 0)
3882 4447 return (err);
3883 4448
3884 4449 if (!spa_feature_is_enabled(spa,
3885 4450 SPA_FEATURE_LZ4_COMPRESS)) {
3886 4451 spa_close(spa, FTAG);
3887 4452 return (SET_ERROR(ENOTSUP));
3888 4453 }
3889 4454 spa_close(spa, FTAG);
3890 4455 }
3891 4456
3892 4457 /*
3893 4458 * If this is a bootable dataset then
3894 4459 * verify that the compression algorithm
3895 4460 * is supported for booting. We must return
3896 4461 * something other than ENOTSUP since it
3897 4462 * implies a downrev pool version.
3898 4463 */
3899 4464 if (zfs_is_bootfs(dsname) &&
3900 4465 !BOOTFS_COMPRESS_VALID(intval)) {
3901 4466 return (SET_ERROR(ERANGE));
3902 4467 }
3903 4468 }
3904 4469 break;
3905 4470
3906 4471 case ZFS_PROP_COPIES:
3907 4472 if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
3908 4473 return (SET_ERROR(ENOTSUP));
3909 4474 break;
3910 4475
3911 4476 case ZFS_PROP_RECORDSIZE:
3912 4477 /* Record sizes above 128k need the feature to be enabled */
3913 4478 if (nvpair_value_uint64(pair, &intval) == 0 &&
3914 4479 intval > SPA_OLD_MAXBLOCKSIZE) {
3915 4480 spa_t *spa;
3916 4481
3917 4482 /*
3918 4483 * We don't allow setting the property above 1MB,
3919 4484 * unless the tunable has been changed.
3920 4485 */
3921 4486 if (intval > zfs_max_recordsize ||
3922 4487 intval > SPA_MAXBLOCKSIZE)
3923 4488 return (SET_ERROR(ERANGE));
3924 4489
3925 4490 if ((err = spa_open(dsname, &spa, FTAG)) != 0)
3926 4491 return (err);
3927 4492
3928 4493 if (!spa_feature_is_enabled(spa,
3929 4494 SPA_FEATURE_LARGE_BLOCKS)) {
3930 4495 spa_close(spa, FTAG);
3931 4496 return (SET_ERROR(ENOTSUP));
3932 4497 }
3933 4498 spa_close(spa, FTAG);
3934 4499 }
3935 4500 break;
3936 4501
3937 4502 case ZFS_PROP_SHARESMB:
3938 4503 if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
3939 4504 return (SET_ERROR(ENOTSUP));
3940 4505 break;
3941 4506
|
↓ open down ↓ |
136 lines elided |
↑ open up ↑ |
3942 4507 case ZFS_PROP_ACLINHERIT:
3943 4508 if (nvpair_type(pair) == DATA_TYPE_UINT64 &&
3944 4509 nvpair_value_uint64(pair, &intval) == 0) {
3945 4510 if (intval == ZFS_ACL_PASSTHROUGH_X &&
3946 4511 zfs_earlier_version(dsname,
3947 4512 SPA_VERSION_PASSTHROUGH_X))
3948 4513 return (SET_ERROR(ENOTSUP));
3949 4514 }
3950 4515 break;
3951 4516
4517 + case ZFS_PROP_WBC_MODE:
4518 + {
4519 + spa_t *spa;
4520 + boolean_t wbc_feature_enabled;
4521 +
4522 + if ((err = spa_open(dsname, &spa, FTAG)) != 0)
4523 + return (err);
4524 +
4525 + wbc_feature_enabled =
4526 + spa_feature_is_enabled(spa, SPA_FEATURE_WBC);
4527 + spa_close(spa, FTAG);
4528 +
4529 + /* WBC cannot be used without special-vdev */
4530 + if (!wbc_feature_enabled || !spa_has_special(spa))
4531 + return (SET_ERROR(EKZFS_WBCNOTSUP));
4532 +
4533 + /*
4534 + * We do not want to have races, because on
4535 + * import or after reboot WBC does registration
4536 + * asynchronously.
4537 + */
4538 + if (!spa->spa_wbc.wbc_ready_to_use)
4539 + return (SET_ERROR(EBUSY));
4540 + }
4541 + break;
4542 +
3952 4543 case ZFS_PROP_CHECKSUM:
3953 4544 case ZFS_PROP_DEDUP:
3954 4545 {
3955 4546 spa_feature_t feature;
3956 4547 spa_t *spa;
3957 4548
3958 4549 /* dedup feature version checks */
3959 4550 if (prop == ZFS_PROP_DEDUP &&
3960 4551 zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
3961 4552 return (SET_ERROR(ENOTSUP));
3962 4553
3963 4554 if (nvpair_value_uint64(pair, &intval) != 0)
3964 4555 return (SET_ERROR(EINVAL));
3965 4556
3966 4557 /* check prop value is enabled in features */
3967 4558 feature = zio_checksum_to_feature(intval & ZIO_CHECKSUM_MASK);
3968 4559 if (feature == SPA_FEATURE_NONE)
3969 4560 break;
3970 4561
3971 4562 if ((err = spa_open(dsname, &spa, FTAG)) != 0)
3972 4563 return (err);
3973 4564 /*
3974 4565 * Salted checksums are not supported on root pools.
3975 4566 */
3976 4567 if (spa_bootfs(spa) != 0 &&
3977 4568 intval < ZIO_CHECKSUM_FUNCTIONS &&
3978 4569 (zio_checksum_table[intval].ci_flags &
3979 4570 ZCHECKSUM_FLAG_SALTED)) {
3980 4571 spa_close(spa, FTAG);
3981 4572 return (SET_ERROR(ERANGE));
3982 4573 }
3983 4574 if (!spa_feature_is_enabled(spa, feature)) {
3984 4575 spa_close(spa, FTAG);
3985 4576 return (SET_ERROR(ENOTSUP));
3986 4577 }
3987 4578 spa_close(spa, FTAG);
3988 4579 break;
3989 4580 }
3990 4581 }
3991 4582
3992 4583 return (zfs_secpolicy_setprop(dsname, prop, pair, CRED()));
3993 4584 }
3994 4585
3995 4586 /*
3996 4587 * Checks for a race condition to make sure we don't increment a feature flag
3997 4588 * multiple times.
3998 4589 */
3999 4590 static int
4000 4591 zfs_prop_activate_feature_check(void *arg, dmu_tx_t *tx)
4001 4592 {
4002 4593 spa_t *spa = dmu_tx_pool(tx)->dp_spa;
4003 4594 spa_feature_t *featurep = arg;
4004 4595
4005 4596 if (!spa_feature_is_active(spa, *featurep))
4006 4597 return (0);
4007 4598 else
4008 4599 return (SET_ERROR(EBUSY));
4009 4600 }
4010 4601
4011 4602 /*
4012 4603 * The callback invoked on feature activation in the sync task caused by
4013 4604 * zfs_prop_activate_feature.
4014 4605 */
4015 4606 static void
4016 4607 zfs_prop_activate_feature_sync(void *arg, dmu_tx_t *tx)
4017 4608 {
4018 4609 spa_t *spa = dmu_tx_pool(tx)->dp_spa;
4019 4610 spa_feature_t *featurep = arg;
4020 4611
4021 4612 spa_feature_incr(spa, *featurep, tx);
4022 4613 }
4023 4614
4024 4615 /*
4025 4616 * Activates a feature on a pool in response to a property setting. This
4026 4617 * creates a new sync task which modifies the pool to reflect the feature
4027 4618 * as being active.
4028 4619 */
4029 4620 static int
4030 4621 zfs_prop_activate_feature(spa_t *spa, spa_feature_t feature)
4031 4622 {
4032 4623 int err;
4033 4624
4034 4625 /* EBUSY here indicates that the feature is already active */
4035 4626 err = dsl_sync_task(spa_name(spa),
4036 4627 zfs_prop_activate_feature_check, zfs_prop_activate_feature_sync,
4037 4628 &feature, 2, ZFS_SPACE_CHECK_RESERVED);
4038 4629
4039 4630 if (err != 0 && err != EBUSY)
4040 4631 return (err);
4041 4632 else
4042 4633 return (0);
4043 4634 }
4044 4635
4045 4636 /*
4046 4637 * Removes properties from the given props list that fail permission checks
4047 4638 * needed to clear them and to restore them in case of a receive error. For each
4048 4639 * property, make sure we have both set and inherit permissions.
4049 4640 *
4050 4641 * Returns the first error encountered if any permission checks fail. If the
4051 4642 * caller provides a non-NULL errlist, it also gives the complete list of names
4052 4643 * of all the properties that failed a permission check along with the
4053 4644 * corresponding error numbers. The caller is responsible for freeing the
4054 4645 * returned errlist.
4055 4646 *
4056 4647 * If every property checks out successfully, zero is returned and the list
4057 4648 * pointed at by errlist is NULL.
4058 4649 */
4059 4650 static int
4060 4651 zfs_check_clearable(char *dataset, nvlist_t *props, nvlist_t **errlist)
4061 4652 {
4062 4653 zfs_cmd_t *zc;
4063 4654 nvpair_t *pair, *next_pair;
4064 4655 nvlist_t *errors;
4065 4656 int err, rv = 0;
4066 4657
4067 4658 if (props == NULL)
4068 4659 return (0);
4069 4660
4070 4661 VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
4071 4662
4072 4663 zc = kmem_alloc(sizeof (zfs_cmd_t), KM_SLEEP);
4073 4664 (void) strcpy(zc->zc_name, dataset);
4074 4665 pair = nvlist_next_nvpair(props, NULL);
4075 4666 while (pair != NULL) {
4076 4667 next_pair = nvlist_next_nvpair(props, pair);
4077 4668
4078 4669 (void) strcpy(zc->zc_value, nvpair_name(pair));
4079 4670 if ((err = zfs_check_settable(dataset, pair, CRED())) != 0 ||
4080 4671 (err = zfs_secpolicy_inherit_prop(zc, NULL, CRED())) != 0) {
4081 4672 VERIFY(nvlist_remove_nvpair(props, pair) == 0);
4082 4673 VERIFY(nvlist_add_int32(errors,
4083 4674 zc->zc_value, err) == 0);
4084 4675 }
4085 4676 pair = next_pair;
4086 4677 }
4087 4678 kmem_free(zc, sizeof (zfs_cmd_t));
4088 4679
4089 4680 if ((pair = nvlist_next_nvpair(errors, NULL)) == NULL) {
4090 4681 nvlist_free(errors);
4091 4682 errors = NULL;
4092 4683 } else {
4093 4684 VERIFY(nvpair_value_int32(pair, &rv) == 0);
4094 4685 }
4095 4686
4096 4687 if (errlist == NULL)
4097 4688 nvlist_free(errors);
4098 4689 else
4099 4690 *errlist = errors;
4100 4691
4101 4692 return (rv);
4102 4693 }
4103 4694
4104 4695 static boolean_t
4105 4696 propval_equals(nvpair_t *p1, nvpair_t *p2)
4106 4697 {
4107 4698 if (nvpair_type(p1) == DATA_TYPE_NVLIST) {
4108 4699 /* dsl_prop_get_all_impl() format */
4109 4700 nvlist_t *attrs;
4110 4701 VERIFY(nvpair_value_nvlist(p1, &attrs) == 0);
4111 4702 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
4112 4703 &p1) == 0);
4113 4704 }
4114 4705
4115 4706 if (nvpair_type(p2) == DATA_TYPE_NVLIST) {
4116 4707 nvlist_t *attrs;
4117 4708 VERIFY(nvpair_value_nvlist(p2, &attrs) == 0);
4118 4709 VERIFY(nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
4119 4710 &p2) == 0);
4120 4711 }
4121 4712
4122 4713 if (nvpair_type(p1) != nvpair_type(p2))
4123 4714 return (B_FALSE);
4124 4715
4125 4716 if (nvpair_type(p1) == DATA_TYPE_STRING) {
4126 4717 char *valstr1, *valstr2;
4127 4718
4128 4719 VERIFY(nvpair_value_string(p1, (char **)&valstr1) == 0);
4129 4720 VERIFY(nvpair_value_string(p2, (char **)&valstr2) == 0);
4130 4721 return (strcmp(valstr1, valstr2) == 0);
4131 4722 } else {
4132 4723 uint64_t intval1, intval2;
4133 4724
4134 4725 VERIFY(nvpair_value_uint64(p1, &intval1) == 0);
4135 4726 VERIFY(nvpair_value_uint64(p2, &intval2) == 0);
4136 4727 return (intval1 == intval2);
4137 4728 }
4138 4729 }
4139 4730
4140 4731 /*
4141 4732 * Remove properties from props if they are not going to change (as determined
4142 4733 * by comparison with origprops). Remove them from origprops as well, since we
4143 4734 * do not need to clear or restore properties that won't change.
4144 4735 */
4145 4736 static void
4146 4737 props_reduce(nvlist_t *props, nvlist_t *origprops)
4147 4738 {
4148 4739 nvpair_t *pair, *next_pair;
4149 4740
4150 4741 if (origprops == NULL)
4151 4742 return; /* all props need to be received */
4152 4743
4153 4744 pair = nvlist_next_nvpair(props, NULL);
4154 4745 while (pair != NULL) {
4155 4746 const char *propname = nvpair_name(pair);
4156 4747 nvpair_t *match;
4157 4748
4158 4749 next_pair = nvlist_next_nvpair(props, pair);
4159 4750
4160 4751 if ((nvlist_lookup_nvpair(origprops, propname,
4161 4752 &match) != 0) || !propval_equals(pair, match))
4162 4753 goto next; /* need to set received value */
4163 4754
4164 4755 /* don't clear the existing received value */
4165 4756 (void) nvlist_remove_nvpair(origprops, match);
4166 4757 /* don't bother receiving the property */
4167 4758 (void) nvlist_remove_nvpair(props, pair);
4168 4759 next:
4169 4760 pair = next_pair;
4170 4761 }
4171 4762 }
4172 4763
4173 4764 /*
4174 4765 * Extract properties that cannot be set PRIOR to the receipt of a dataset.
4175 4766 * For example, refquota cannot be set until after the receipt of a dataset,
4176 4767 * because in replication streams, an older/earlier snapshot may exceed the
4177 4768 * refquota. We want to receive the older/earlier snapshot, but setting
4178 4769 * refquota pre-receipt will set the dsl's ACTUAL quota, which will prevent
4179 4770 * the older/earlier snapshot from being received (with EDQUOT).
4180 4771 *
4181 4772 * The ZFS test "zfs_receive_011_pos" demonstrates such a scenario.
4182 4773 *
4183 4774 * libzfs will need to be judicious handling errors encountered by props
4184 4775 * extracted by this function.
4185 4776 */
4186 4777 static nvlist_t *
4187 4778 extract_delay_props(nvlist_t *props)
4188 4779 {
4189 4780 nvlist_t *delayprops;
4190 4781 nvpair_t *nvp, *tmp;
4191 4782 static const zfs_prop_t delayable[] = { ZFS_PROP_REFQUOTA, 0 };
4192 4783 int i;
4193 4784
4194 4785 VERIFY(nvlist_alloc(&delayprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
4195 4786
4196 4787 for (nvp = nvlist_next_nvpair(props, NULL); nvp != NULL;
4197 4788 nvp = nvlist_next_nvpair(props, nvp)) {
4198 4789 /*
4199 4790 * strcmp() is safe because zfs_prop_to_name() always returns
4200 4791 * a bounded string.
4201 4792 */
4202 4793 for (i = 0; delayable[i] != 0; i++) {
4203 4794 if (strcmp(zfs_prop_to_name(delayable[i]),
4204 4795 nvpair_name(nvp)) == 0) {
4205 4796 break;
4206 4797 }
4207 4798 }
4208 4799 if (delayable[i] != 0) {
4209 4800 tmp = nvlist_prev_nvpair(props, nvp);
4210 4801 VERIFY(nvlist_add_nvpair(delayprops, nvp) == 0);
4211 4802 VERIFY(nvlist_remove_nvpair(props, nvp) == 0);
4212 4803 nvp = tmp;
4213 4804 }
4214 4805 }
4215 4806
4216 4807 if (nvlist_empty(delayprops)) {
|
↓ open down ↓ |
255 lines elided |
↑ open up ↑ |
4217 4808 nvlist_free(delayprops);
4218 4809 delayprops = NULL;
4219 4810 }
4220 4811 return (delayprops);
4221 4812 }
4222 4813
4223 4814 #ifdef DEBUG
4224 4815 static boolean_t zfs_ioc_recv_inject_err;
4225 4816 #endif
4226 4817
4227 -/*
4228 - * inputs:
4229 - * zc_name name of containing filesystem
4230 - * zc_nvlist_src{_size} nvlist of properties to apply
4231 - * zc_value name of snapshot to create
4232 - * zc_string name of clone origin (if DRR_FLAG_CLONE)
4233 - * zc_cookie file descriptor to recv from
4234 - * zc_begin_record the BEGIN record of the stream (not byteswapped)
4235 - * zc_guid force flag
4236 - * zc_cleanup_fd cleanup-on-exit file descriptor
4237 - * zc_action_handle handle for this guid/ds mapping (or zero on first call)
4238 - * zc_resumable if data is incomplete assume sender will resume
4239 - *
4240 - * outputs:
4241 - * zc_cookie number of bytes read
4242 - * zc_nvlist_dst{_size} error for each unapplied received property
4243 - * zc_obj zprop_errflags_t
4244 - * zc_action_handle handle for this guid/ds mapping
4245 - */
4246 -static int
4247 -zfs_ioc_recv(zfs_cmd_t *zc)
4818 +int
4819 +dmu_recv_impl(int fd, char *tofs, char *tosnap, char *origin,
4820 + dmu_replay_record_t *drr_begin, boolean_t is_resumable, nvlist_t *props,
4821 + nvlist_t *errors, uint64_t *errf, int cfd, uint64_t *ahdl, uint64_t *sz,
4822 + boolean_t force, dmu_krrp_task_t *krrp_task)
4248 4823 {
4249 - file_t *fp;
4824 + file_t *fp = getf(fd);
4250 4825 dmu_recv_cookie_t drc;
4251 - boolean_t force = (boolean_t)zc->zc_guid;
4252 - int fd;
4253 4826 int error = 0;
4254 4827 int props_error = 0;
4255 - nvlist_t *errors;
4256 4828 offset_t off;
4257 - nvlist_t *props = NULL; /* sent properties */
4258 4829 nvlist_t *origprops = NULL; /* existing properties */
4259 4830 nvlist_t *delayprops = NULL; /* sent properties applied post-receive */
4260 - char *origin = NULL;
4261 - char *tosnap;
4262 - char tofs[ZFS_MAX_DATASET_NAME_LEN];
4263 4831 boolean_t first_recvd_props = B_FALSE;
4832 + nvlist_t *event;
4833 + boolean_t force_cksum =
4834 + !krrp_task || krrp_task->buffer_args.force_cksum;
4264 4835
4265 - if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
4266 - strchr(zc->zc_value, '@') == NULL ||
4267 - strchr(zc->zc_value, '%'))
4268 - return (SET_ERROR(EINVAL));
4836 + ASSERT(fp || krrp_task);
4269 4837
4270 - (void) strcpy(tofs, zc->zc_value);
4271 - tosnap = strchr(tofs, '@');
4272 - *tosnap++ = '\0';
4273 -
4274 - if (zc->zc_nvlist_src != NULL &&
4275 - (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
4276 - zc->zc_iflags, &props)) != 0)
4277 - return (error);
4278 -
4279 - fd = zc->zc_cookie;
4280 - fp = getf(fd);
4281 - if (fp == NULL) {
4282 - nvlist_free(props);
4283 - return (SET_ERROR(EBADF));
4284 - }
4285 -
4286 - errors = fnvlist_alloc();
4287 -
4288 - if (zc->zc_string[0])
4289 - origin = zc->zc_string;
4290 -
4291 4838 error = dmu_recv_begin(tofs, tosnap,
4292 - &zc->zc_begin_record, force, zc->zc_resumable, origin, &drc);
4839 + drr_begin, force, is_resumable, force_cksum, origin, &drc);
4840 +
4293 4841 if (error != 0)
4294 4842 goto out;
4295 4843
4844 + drc.drc_krrp_task = krrp_task;
4296 4845 /*
4297 4846 * Set properties before we receive the stream so that they are applied
4298 4847 * to the new data. Note that we must call dmu_recv_stream() if
4299 4848 * dmu_recv_begin() succeeds.
4300 4849 */
4301 4850 if (props != NULL && !drc.drc_newfs) {
4302 4851 if (spa_version(dsl_dataset_get_spa(drc.drc_ds)) >=
4303 4852 SPA_VERSION_RECVD_PROPS &&
4304 4853 !dsl_prop_get_hasrecvd(tofs))
4305 4854 first_recvd_props = B_TRUE;
4306 4855
4307 4856 /*
4308 4857 * If new received properties are supplied, they are to
4309 4858 * completely replace the existing received properties, so stash
4310 4859 * away the existing ones.
4311 4860 */
4312 4861 if (dsl_prop_get_received(tofs, &origprops) == 0) {
4313 4862 nvlist_t *errlist = NULL;
4314 4863 /*
4315 4864 * Don't bother writing a property if its value won't
4316 4865 * change (and avoid the unnecessary security checks).
4317 4866 *
4318 4867 * The first receive after SPA_VERSION_RECVD_PROPS is a
4319 4868 * special case where we blow away all local properties
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
4320 4869 * regardless.
4321 4870 */
4322 4871 if (!first_recvd_props)
4323 4872 props_reduce(props, origprops);
4324 4873 if (zfs_check_clearable(tofs, origprops, &errlist) != 0)
4325 4874 (void) nvlist_merge(errors, errlist, 0);
4326 4875 nvlist_free(errlist);
4327 4876
4328 4877 if (clear_received_props(tofs, origprops,
4329 4878 first_recvd_props ? NULL : props) != 0)
4330 - zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4879 + *errf |= ZPROP_ERR_NOCLEAR;
4331 4880 } else {
4332 - zc->zc_obj |= ZPROP_ERR_NOCLEAR;
4881 + *errf |= ZPROP_ERR_NOCLEAR;
4333 4882 }
4334 4883 }
4335 4884
4336 4885 if (props != NULL) {
4337 4886 props_error = dsl_prop_set_hasrecvd(tofs);
4338 4887
4339 4888 if (props_error == 0) {
4340 4889 delayprops = extract_delay_props(props);
4341 4890 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4342 4891 props, errors);
4343 4892 }
4344 4893 }
4345 4894
4346 - off = fp->f_offset;
4347 - error = dmu_recv_stream(&drc, fp->f_vnode, &off, zc->zc_cleanup_fd,
4348 - &zc->zc_action_handle);
4895 + if (fp) {
4896 + off = fp->f_offset;
4897 + } else {
4898 + off = 0;
4899 + }
4900 + error = dmu_recv_stream(&drc, fp ? fp->f_vnode : NULL,
4901 + &off, cfd, ahdl, krrp_task);
4349 4902
4350 4903 if (error == 0) {
4351 4904 zfsvfs_t *zfsvfs = NULL;
4352 4905
4353 - if (getzfsvfs(tofs, &zfsvfs) == 0) {
4906 + error = getzfsvfs(tofs, &zfsvfs);
4907 + if (error == 0) {
4354 4908 /* online recv */
4355 4909 dsl_dataset_t *ds;
4356 4910 int end_err;
4357 4911
4358 4912 ds = dmu_objset_ds(zfsvfs->z_os);
4359 4913 error = zfs_suspend_fs(zfsvfs);
4360 4914 /*
4361 4915 * If the suspend fails, then the recv_end will
4362 4916 * likely also fail, and clean up after itself.
4363 4917 */
4364 4918 end_err = dmu_recv_end(&drc, zfsvfs);
4365 4919 if (error == 0)
4366 4920 error = zfs_resume_fs(zfsvfs, ds);
4367 4921 error = error ? error : end_err;
4368 4922 VFS_RELE(zfsvfs->z_vfs);
4369 4923 } else {
4370 4924 error = dmu_recv_end(&drc, NULL);
4371 4925 }
4372 4926
4373 4927 /* Set delayed properties now, after we're done receiving. */
4374 4928 if (delayprops != NULL && error == 0) {
4375 4929 (void) zfs_set_prop_nvlist(tofs, ZPROP_SRC_RECEIVED,
4376 4930 delayprops, errors);
4377 4931 }
4378 4932 }
4379 4933
4380 4934 if (delayprops != NULL) {
4381 4935 /*
4382 4936 * Merge delayed props back in with initial props, in case
4383 4937 * we're DEBUG and zfs_ioc_recv_inject_err is set (which means
|
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
4384 4938 * we have to make sure clear_received_props() includes
4385 4939 * the delayed properties).
4386 4940 *
4387 4941 * Since zfs_ioc_recv_inject_err is only in DEBUG kernels,
4388 4942 * using ASSERT() will be just like a VERIFY.
4389 4943 */
4390 4944 ASSERT(nvlist_merge(props, delayprops, 0) == 0);
4391 4945 nvlist_free(delayprops);
4392 4946 }
4393 4947
4394 - /*
4395 - * Now that all props, initial and delayed, are set, report the prop
4396 - * errors to the caller.
4397 - */
4398 - if (zc->zc_nvlist_dst_size != 0 &&
4399 - (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
4400 - put_nvlist(zc, errors) != 0)) {
4401 - /*
4402 - * Caller made zc->zc_nvlist_dst less than the minimum expected
4403 - * size or supplied an invalid address.
4404 - */
4405 - props_error = SET_ERROR(EINVAL);
4948 + if (fp) {
4949 + *sz = off - fp->f_offset;
4950 + if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4951 + fp->f_offset = off;
4952 + } else {
4953 + *sz = off;
4406 4954 }
4955 + if (error == 0) {
4956 + char val[MAXNAMELEN];
4407 4957
4408 - zc->zc_cookie = off - fp->f_offset;
4409 - if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4410 - fp->f_offset = off;
4958 + (void) strcpy(val, tofs);
4959 + (void) strcat(val, "@");
4960 + (void) strcat(val, tosnap);
4411 4961
4962 + event = fnvlist_alloc();
4963 + if (props != NULL)
4964 + fnvlist_add_nvlist(event, "props", props);
4965 + fnvlist_add_string(event, "origin", tofs);
4966 + fnvlist_add_string(event, "tosnap", val);
4967 + fnvlist_add_uint64(event, "bytes", *sz);
4968 + fnvlist_add_boolean_value(event, "newds", drc.drc_newfs);
4969 + zfs_event_post(ZFS_EC_STATUS, "recv", event);
4970 + }
4971 +
4412 4972 #ifdef DEBUG
4413 4973 if (zfs_ioc_recv_inject_err) {
4414 4974 zfs_ioc_recv_inject_err = B_FALSE;
4415 4975 error = 1;
4416 4976 }
4417 4977 #endif
4418 4978 /*
4419 4979 * On error, restore the original props.
4420 4980 */
4421 4981 if (error != 0 && props != NULL && !drc.drc_newfs) {
4422 4982 if (clear_received_props(tofs, props, NULL) != 0) {
4423 4983 /*
4424 4984 * We failed to clear the received properties.
4425 4985 * Since we may have left a $recvd value on the
4426 4986 * system, we can't clear the $hasrecvd flag.
4427 4987 */
4428 - zc->zc_obj |= ZPROP_ERR_NORESTORE;
4988 + *errf |= ZPROP_ERR_NORESTORE;
4429 4989 } else if (first_recvd_props) {
4430 4990 dsl_prop_unset_hasrecvd(tofs);
4431 4991 }
4432 4992
4433 4993 if (origprops == NULL && !drc.drc_newfs) {
4434 4994 /* We failed to stash the original properties. */
4435 - zc->zc_obj |= ZPROP_ERR_NORESTORE;
4995 + *errf |= ZPROP_ERR_NORESTORE;
4436 4996 }
4437 4997
4438 4998 /*
4439 4999 * dsl_props_set() will not convert RECEIVED to LOCAL on or
4440 5000 * after SPA_VERSION_RECVD_PROPS, so we need to specify LOCAL
4441 5001 * explictly if we're restoring local properties cleared in the
4442 5002 * first new-style receive.
4443 5003 */
4444 5004 if (origprops != NULL &&
4445 5005 zfs_set_prop_nvlist(tofs, (first_recvd_props ?
4446 5006 ZPROP_SRC_LOCAL : ZPROP_SRC_RECEIVED),
4447 5007 origprops, NULL) != 0) {
4448 5008 /*
4449 5009 * We stashed the original properties but failed to
4450 5010 * restore them.
4451 5011 */
4452 - zc->zc_obj |= ZPROP_ERR_NORESTORE;
5012 + *errf |= ZPROP_ERR_NORESTORE;
4453 5013 }
4454 5014 }
4455 5015 out:
4456 - nvlist_free(props);
4457 5016 nvlist_free(origprops);
4458 - nvlist_free(errors);
4459 - releasef(fd);
5017 + if (fp)
5018 + releasef(fd);
4460 5019
4461 5020 if (error == 0)
4462 5021 error = props_error;
4463 5022
4464 5023 return (error);
4465 5024 }
4466 5025
4467 5026 /*
4468 5027 * inputs:
5028 + * zc_name name of containing filesystem
5029 + * zc_nvlist_src{_size} nvlist of properties to apply
5030 + * zc_value name of snapshot to create
5031 + * zc_string name of clone origin (if DRR_FLAG_CLONE)
5032 + * zc_cookie file descriptor to recv from
5033 + * zc_begin_record the BEGIN record of the stream (not byteswapped)
5034 + * zc_guid force flag
5035 + * zc_cleanup_fd cleanup-on-exit file descriptor
5036 + * zc_action_handle handle for this guid/ds mapping (or zero on first call)
5037 + * zc_resumable if data is incomplete assume sender will resume
5038 + *
5039 + * outputs:
5040 + * zc_cookie number of bytes read
5041 + * zc_nvlist_dst{_size} error for each unapplied received property
5042 + * zc_obj zprop_errflags_t
5043 + * zc_action_handle handle for this guid/ds mapping
5044 + */
5045 +static int
5046 +zfs_ioc_recv(zfs_cmd_t *zc)
5047 +{
5048 + int fd = zc->zc_cookie;
5049 + char tofs[ZFS_MAX_DATASET_NAME_LEN];
5050 + char *tosnap;
5051 + char *origin = NULL;
5052 + nvlist_t *errors;
5053 + nvlist_t *props = NULL; /* sent properties */
5054 + boolean_t force = (boolean_t)zc->zc_guid;
5055 + int err;
5056 +
5057 + if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
5058 + strchr(zc->zc_value, '@') == NULL ||
5059 + strchr(zc->zc_value, '%'))
5060 + return (SET_ERROR(EINVAL));
5061 +
5062 + (void) strcpy(tofs, zc->zc_value);
5063 + tosnap = strchr(tofs, '@');
5064 + *tosnap++ = '\0';
5065 +
5066 + if (zc->zc_string[0])
5067 + origin = zc->zc_string;
5068 +
5069 + if (zc->zc_nvlist_src != NULL &&
5070 + (err = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
5071 + zc->zc_iflags, &props)) != 0)
5072 + return (err);
5073 +
5074 + errors = fnvlist_alloc();
5075 +
5076 + err = dmu_recv_impl(fd, tofs, tosnap, origin,
5077 + &zc->zc_begin_record, zc->zc_resumable, props, errors, &zc->zc_obj,
5078 + zc->zc_cleanup_fd, &zc->zc_action_handle, &zc->zc_cookie,
5079 + force, NULL);
5080 +
5081 + /*
5082 + * Now that all props, initial and delayed, are set, report the prop
5083 + * errors to the caller.
5084 + */
5085 + if (zc->zc_nvlist_dst_size != 0 &&
5086 + (nvlist_smush(errors, zc->zc_nvlist_dst_size) != 0 ||
5087 + put_nvlist(zc, errors) != 0)) {
5088 + /*
5089 + * Caller made zc->zc_nvlist_dst less than the minimum expected
5090 + * size or supplied an invalid address.
5091 + */
5092 + err = SET_ERROR(EINVAL);
5093 + }
5094 +
5095 + nvlist_free(errors);
5096 + nvlist_free(props);
5097 + return (err);
5098 +
5099 +}
5100 +
5101 +/*
5102 + * inputs:
4469 5103 * zc_name name of snapshot to send
4470 5104 * zc_cookie file descriptor to send stream to
4471 5105 * zc_obj fromorigin flag (mutually exclusive with zc_fromobj)
4472 5106 * zc_sendobj objsetid of snapshot to send
4473 5107 * zc_fromobj objsetid of incremental fromsnap (may be zero)
4474 5108 * zc_guid if set, estimate size of stream only. zc_cookie is ignored.
4475 5109 * output size in zc_objset_type.
4476 5110 * zc_flags lzc_send_flags
4477 5111 *
4478 5112 * outputs:
4479 5113 * zc_objset_type estimated size, if zc_guid is set
4480 5114 */
4481 5115 static int
4482 5116 zfs_ioc_send(zfs_cmd_t *zc)
4483 5117 {
4484 5118 int error;
4485 5119 offset_t off;
4486 5120 boolean_t estimate = (zc->zc_guid != 0);
4487 5121 boolean_t embedok = (zc->zc_flags & 0x1);
4488 5122 boolean_t large_block_ok = (zc->zc_flags & 0x2);
4489 5123 boolean_t compressok = (zc->zc_flags & 0x4);
4490 5124
4491 5125 if (zc->zc_obj != 0) {
4492 5126 dsl_pool_t *dp;
4493 5127 dsl_dataset_t *tosnap;
4494 5128
4495 5129 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4496 5130 if (error != 0)
4497 5131 return (error);
4498 5132
4499 5133 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4500 5134 if (error != 0) {
4501 5135 dsl_pool_rele(dp, FTAG);
4502 5136 return (error);
4503 5137 }
4504 5138
4505 5139 if (dsl_dir_is_clone(tosnap->ds_dir))
4506 5140 zc->zc_fromobj =
4507 5141 dsl_dir_phys(tosnap->ds_dir)->dd_origin_obj;
4508 5142 dsl_dataset_rele(tosnap, FTAG);
4509 5143 dsl_pool_rele(dp, FTAG);
4510 5144 }
4511 5145
4512 5146 if (estimate) {
4513 5147 dsl_pool_t *dp;
4514 5148 dsl_dataset_t *tosnap;
4515 5149 dsl_dataset_t *fromsnap = NULL;
4516 5150
4517 5151 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4518 5152 if (error != 0)
4519 5153 return (error);
4520 5154
4521 5155 error = dsl_dataset_hold_obj(dp, zc->zc_sendobj, FTAG, &tosnap);
4522 5156 if (error != 0) {
4523 5157 dsl_pool_rele(dp, FTAG);
4524 5158 return (error);
4525 5159 }
4526 5160
4527 5161 if (zc->zc_fromobj != 0) {
4528 5162 error = dsl_dataset_hold_obj(dp, zc->zc_fromobj,
4529 5163 FTAG, &fromsnap);
4530 5164 if (error != 0) {
4531 5165 dsl_dataset_rele(tosnap, FTAG);
4532 5166 dsl_pool_rele(dp, FTAG);
4533 5167 return (error);
4534 5168 }
|
↓ open down ↓ |
56 lines elided |
↑ open up ↑ |
4535 5169 }
4536 5170
4537 5171 error = dmu_send_estimate(tosnap, fromsnap, compressok,
4538 5172 &zc->zc_objset_type);
4539 5173
4540 5174 if (fromsnap != NULL)
4541 5175 dsl_dataset_rele(fromsnap, FTAG);
4542 5176 dsl_dataset_rele(tosnap, FTAG);
4543 5177 dsl_pool_rele(dp, FTAG);
4544 5178 } else {
5179 + offset_t off_starting;
4545 5180 file_t *fp = getf(zc->zc_cookie);
4546 5181 if (fp == NULL)
4547 5182 return (SET_ERROR(EBADF));
4548 5183
4549 - off = fp->f_offset;
5184 + off_starting = off = fp->f_offset;
4550 5185 error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
4551 5186 zc->zc_fromobj, embedok, large_block_ok, compressok,
4552 - zc->zc_cookie, fp->f_vnode, &off);
5187 + zc->zc_cookie, fp->f_vnode, &off, zc->zc_sendsize);
4553 5188
5189 + zc->zc_sendcounter = off - off_starting;
4554 5190 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
4555 5191 fp->f_offset = off;
4556 5192 releasef(zc->zc_cookie);
4557 5193 }
4558 5194 return (error);
4559 5195 }
4560 5196
4561 5197 /*
4562 5198 * inputs:
4563 5199 * zc_name name of snapshot on which to report progress
4564 5200 * zc_cookie file descriptor of send stream
4565 5201 *
4566 5202 * outputs:
4567 5203 * zc_cookie number of bytes written in send stream thus far
4568 5204 */
4569 5205 static int
4570 5206 zfs_ioc_send_progress(zfs_cmd_t *zc)
4571 5207 {
4572 5208 dsl_pool_t *dp;
4573 5209 dsl_dataset_t *ds;
4574 5210 dmu_sendarg_t *dsp = NULL;
4575 5211 int error;
4576 5212
4577 5213 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4578 5214 if (error != 0)
4579 5215 return (error);
4580 5216
4581 5217 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
4582 5218 if (error != 0) {
4583 5219 dsl_pool_rele(dp, FTAG);
4584 5220 return (error);
4585 5221 }
4586 5222
4587 5223 mutex_enter(&ds->ds_sendstream_lock);
4588 5224
4589 5225 /*
4590 5226 * Iterate over all the send streams currently active on this dataset.
4591 5227 * If there's one which matches the specified file descriptor _and_ the
4592 5228 * stream was started by the current process, return the progress of
4593 5229 * that stream.
4594 5230 */
4595 5231 for (dsp = list_head(&ds->ds_sendstreams); dsp != NULL;
4596 5232 dsp = list_next(&ds->ds_sendstreams, dsp)) {
4597 5233 if (dsp->dsa_outfd == zc->zc_cookie &&
4598 5234 dsp->dsa_proc == curproc)
4599 5235 break;
4600 5236 }
4601 5237
4602 5238 if (dsp != NULL)
4603 5239 zc->zc_cookie = *(dsp->dsa_off);
4604 5240 else
4605 5241 error = SET_ERROR(ENOENT);
4606 5242
4607 5243 mutex_exit(&ds->ds_sendstream_lock);
4608 5244 dsl_dataset_rele(ds, FTAG);
4609 5245 dsl_pool_rele(dp, FTAG);
4610 5246 return (error);
4611 5247 }
4612 5248
4613 5249 static int
4614 5250 zfs_ioc_inject_fault(zfs_cmd_t *zc)
4615 5251 {
4616 5252 int id, error;
4617 5253
4618 5254 error = zio_inject_fault(zc->zc_name, (int)zc->zc_guid, &id,
4619 5255 &zc->zc_inject_record);
4620 5256
4621 5257 if (error == 0)
4622 5258 zc->zc_guid = (uint64_t)id;
4623 5259
4624 5260 return (error);
4625 5261 }
4626 5262
4627 5263 static int
4628 5264 zfs_ioc_clear_fault(zfs_cmd_t *zc)
4629 5265 {
4630 5266 return (zio_clear_fault((int)zc->zc_guid));
4631 5267 }
4632 5268
4633 5269 static int
4634 5270 zfs_ioc_inject_list_next(zfs_cmd_t *zc)
4635 5271 {
4636 5272 int id = (int)zc->zc_guid;
4637 5273 int error;
4638 5274
4639 5275 error = zio_inject_list_next(&id, zc->zc_name, sizeof (zc->zc_name),
4640 5276 &zc->zc_inject_record);
4641 5277
4642 5278 zc->zc_guid = id;
4643 5279
4644 5280 return (error);
4645 5281 }
4646 5282
4647 5283 static int
4648 5284 zfs_ioc_error_log(zfs_cmd_t *zc)
4649 5285 {
4650 5286 spa_t *spa;
4651 5287 int error;
4652 5288 size_t count = (size_t)zc->zc_nvlist_dst_size;
4653 5289
4654 5290 if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
4655 5291 return (error);
4656 5292
4657 5293 error = spa_get_errlog(spa, (void *)(uintptr_t)zc->zc_nvlist_dst,
4658 5294 &count);
4659 5295 if (error == 0)
4660 5296 zc->zc_nvlist_dst_size = count;
4661 5297 else
4662 5298 zc->zc_nvlist_dst_size = spa_get_errlog_size(spa);
4663 5299
4664 5300 spa_close(spa, FTAG);
4665 5301
4666 5302 return (error);
4667 5303 }
4668 5304
4669 5305 static int
4670 5306 zfs_ioc_clear(zfs_cmd_t *zc)
4671 5307 {
4672 5308 spa_t *spa;
4673 5309 vdev_t *vd;
4674 5310 int error;
4675 5311
4676 5312 /*
4677 5313 * On zpool clear we also fix up missing slogs
4678 5314 */
4679 5315 mutex_enter(&spa_namespace_lock);
4680 5316 spa = spa_lookup(zc->zc_name);
4681 5317 if (spa == NULL) {
4682 5318 mutex_exit(&spa_namespace_lock);
4683 5319 return (SET_ERROR(EIO));
4684 5320 }
4685 5321 if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
4686 5322 /* we need to let spa_open/spa_load clear the chains */
4687 5323 spa_set_log_state(spa, SPA_LOG_CLEAR);
4688 5324 }
4689 5325 spa->spa_last_open_failed = 0;
4690 5326 mutex_exit(&spa_namespace_lock);
4691 5327
4692 5328 if (zc->zc_cookie & ZPOOL_NO_REWIND) {
4693 5329 error = spa_open(zc->zc_name, &spa, FTAG);
4694 5330 } else {
4695 5331 nvlist_t *policy;
4696 5332 nvlist_t *config = NULL;
4697 5333
4698 5334 if (zc->zc_nvlist_src == NULL)
4699 5335 return (SET_ERROR(EINVAL));
4700 5336
4701 5337 if ((error = get_nvlist(zc->zc_nvlist_src,
4702 5338 zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
4703 5339 error = spa_open_rewind(zc->zc_name, &spa, FTAG,
4704 5340 policy, &config);
4705 5341 if (config != NULL) {
4706 5342 int err;
4707 5343
4708 5344 if ((err = put_nvlist(zc, config)) != 0)
4709 5345 error = err;
4710 5346 nvlist_free(config);
4711 5347 }
4712 5348 nvlist_free(policy);
4713 5349 }
4714 5350 }
4715 5351
4716 5352 if (error != 0)
4717 5353 return (error);
4718 5354
4719 5355 spa_vdev_state_enter(spa, SCL_NONE);
4720 5356
4721 5357 if (zc->zc_guid == 0) {
4722 5358 vd = NULL;
4723 5359 } else {
4724 5360 vd = spa_lookup_by_guid(spa, zc->zc_guid, B_TRUE);
4725 5361 if (vd == NULL) {
4726 5362 (void) spa_vdev_state_exit(spa, NULL, ENODEV);
4727 5363 spa_close(spa, FTAG);
4728 5364 return (SET_ERROR(ENODEV));
4729 5365 }
4730 5366 }
4731 5367
4732 5368 vdev_clear(spa, vd);
4733 5369
4734 5370 (void) spa_vdev_state_exit(spa, NULL, 0);
4735 5371
4736 5372 /*
4737 5373 * Resume any suspended I/Os.
4738 5374 */
4739 5375 if (zio_resume(spa) != 0)
4740 5376 error = SET_ERROR(EIO);
4741 5377
4742 5378 spa_close(spa, FTAG);
4743 5379
4744 5380 return (error);
4745 5381 }
4746 5382
4747 5383 static int
4748 5384 zfs_ioc_pool_reopen(zfs_cmd_t *zc)
4749 5385 {
4750 5386 spa_t *spa;
4751 5387 int error;
4752 5388
4753 5389 error = spa_open(zc->zc_name, &spa, FTAG);
4754 5390 if (error != 0)
4755 5391 return (error);
4756 5392
4757 5393 spa_vdev_state_enter(spa, SCL_NONE);
4758 5394
4759 5395 /*
4760 5396 * If a resilver is already in progress then set the
4761 5397 * spa_scrub_reopen flag to B_TRUE so that we don't restart
4762 5398 * the scan as a side effect of the reopen. Otherwise, let
4763 5399 * vdev_open() decided if a resilver is required.
4764 5400 */
4765 5401 spa->spa_scrub_reopen = dsl_scan_resilvering(spa->spa_dsl_pool);
4766 5402 vdev_reopen(spa->spa_root_vdev);
4767 5403 spa->spa_scrub_reopen = B_FALSE;
4768 5404
4769 5405 (void) spa_vdev_state_exit(spa, NULL, 0);
4770 5406 spa_close(spa, FTAG);
4771 5407 return (0);
4772 5408 }
4773 5409 /*
4774 5410 * inputs:
4775 5411 * zc_name name of filesystem
4776 5412 *
4777 5413 * outputs:
|
↓ open down ↓ |
214 lines elided |
↑ open up ↑ |
4778 5414 * zc_string name of conflicting snapshot, if there is one
4779 5415 */
4780 5416 static int
4781 5417 zfs_ioc_promote(zfs_cmd_t *zc)
4782 5418 {
4783 5419 dsl_pool_t *dp;
4784 5420 dsl_dataset_t *ds, *ods;
4785 5421 char origin[ZFS_MAX_DATASET_NAME_LEN];
4786 5422 char *cp;
4787 5423 int error;
5424 + nvlist_t *event;
4788 5425
4789 - zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
4790 - if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0 ||
4791 - strchr(zc->zc_name, '%'))
4792 - return (SET_ERROR(EINVAL));
4793 -
4794 5426 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
4795 5427 if (error != 0)
4796 5428 return (error);
4797 5429
4798 5430 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &ds);
4799 5431 if (error != 0) {
4800 5432 dsl_pool_rele(dp, FTAG);
4801 5433 return (error);
4802 5434 }
4803 5435
4804 5436 if (!dsl_dir_is_clone(ds->ds_dir)) {
4805 5437 dsl_dataset_rele(ds, FTAG);
4806 5438 dsl_pool_rele(dp, FTAG);
4807 5439 return (SET_ERROR(EINVAL));
4808 5440 }
4809 5441
4810 5442 error = dsl_dataset_hold_obj(dp,
4811 5443 dsl_dir_phys(ds->ds_dir)->dd_origin_obj, FTAG, &ods);
4812 5444 if (error != 0) {
4813 5445 dsl_dataset_rele(ds, FTAG);
4814 5446 dsl_pool_rele(dp, FTAG);
4815 5447 return (error);
4816 5448 }
4817 5449
4818 5450 dsl_dataset_name(ods, origin);
4819 5451 dsl_dataset_rele(ods, FTAG);
4820 5452 dsl_dataset_rele(ds, FTAG);
4821 5453 dsl_pool_rele(dp, FTAG);
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
4822 5454
4823 5455 /*
4824 5456 * We don't need to unmount *all* the origin fs's snapshots, but
4825 5457 * it's easier.
4826 5458 */
4827 5459 cp = strchr(origin, '@');
4828 5460 if (cp)
4829 5461 *cp = '\0';
4830 5462 (void) dmu_objset_find(origin,
4831 5463 zfs_unmount_snap_cb, NULL, DS_FIND_SNAPSHOTS);
4832 - return (dsl_dataset_promote(zc->zc_name, zc->zc_string));
5464 + error = dsl_dataset_promote(zc->zc_name, zc->zc_string);
5465 +
5466 + if (error == 0) {
5467 + event = fnvlist_alloc();
5468 + fnvlist_add_string(event, "fsname", zc->zc_name);
5469 + fnvlist_add_string(event, "origin", zc->zc_value);
5470 + zfs_event_post(ZFS_EC_STATUS, "promote", event);
5471 + }
5472 +
5473 + return (error);
4833 5474 }
4834 5475
4835 5476 /*
4836 5477 * Retrieve a single {user|group}{used|quota}@... property.
4837 5478 *
4838 5479 * inputs:
4839 5480 * zc_name name of filesystem
4840 5481 * zc_objset_type zfs_userquota_prop_t
4841 5482 * zc_value domain name (eg. "S-1-234-567-89")
4842 5483 * zc_guid RID/UID/GID
4843 5484 *
4844 5485 * outputs:
4845 5486 * zc_cookie property value
4846 5487 */
4847 5488 static int
4848 5489 zfs_ioc_userspace_one(zfs_cmd_t *zc)
4849 5490 {
4850 5491 zfsvfs_t *zfsvfs;
4851 5492 int error;
4852 5493
4853 5494 if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
4854 5495 return (SET_ERROR(EINVAL));
4855 5496
4856 5497 error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
4857 5498 if (error != 0)
4858 5499 return (error);
4859 5500
4860 5501 error = zfs_userspace_one(zfsvfs,
4861 5502 zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
4862 5503 zfsvfs_rele(zfsvfs, FTAG);
4863 5504
4864 5505 return (error);
4865 5506 }
4866 5507
4867 5508 /*
4868 5509 * inputs:
4869 5510 * zc_name name of filesystem
4870 5511 * zc_cookie zap cursor
4871 5512 * zc_objset_type zfs_userquota_prop_t
4872 5513 * zc_nvlist_dst[_size] buffer to fill (not really an nvlist)
4873 5514 *
4874 5515 * outputs:
4875 5516 * zc_nvlist_dst[_size] data buffer (array of zfs_useracct_t)
4876 5517 * zc_cookie zap cursor
4877 5518 */
4878 5519 static int
4879 5520 zfs_ioc_userspace_many(zfs_cmd_t *zc)
4880 5521 {
4881 5522 zfsvfs_t *zfsvfs;
4882 5523 int bufsize = zc->zc_nvlist_dst_size;
4883 5524
4884 5525 if (bufsize <= 0)
4885 5526 return (SET_ERROR(ENOMEM));
4886 5527
4887 5528 int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE);
4888 5529 if (error != 0)
4889 5530 return (error);
4890 5531
4891 5532 void *buf = kmem_alloc(bufsize, KM_SLEEP);
4892 5533
4893 5534 error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie,
4894 5535 buf, &zc->zc_nvlist_dst_size);
4895 5536
4896 5537 if (error == 0) {
4897 5538 error = xcopyout(buf,
4898 5539 (void *)(uintptr_t)zc->zc_nvlist_dst,
4899 5540 zc->zc_nvlist_dst_size);
4900 5541 }
4901 5542 kmem_free(buf, bufsize);
4902 5543 zfsvfs_rele(zfsvfs, FTAG);
4903 5544
4904 5545 return (error);
4905 5546 }
4906 5547
4907 5548 /*
4908 5549 * inputs:
4909 5550 * zc_name name of filesystem
4910 5551 *
4911 5552 * outputs:
4912 5553 * none
4913 5554 */
4914 5555 static int
4915 5556 zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
4916 5557 {
4917 5558 objset_t *os;
4918 5559 int error = 0;
4919 5560 zfsvfs_t *zfsvfs;
4920 5561
4921 5562 if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
4922 5563 if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
4923 5564 /*
4924 5565 * If userused is not enabled, it may be because the
4925 5566 * objset needs to be closed & reopened (to grow the
4926 5567 * objset_phys_t). Suspend/resume the fs will do that.
4927 5568 */
4928 5569 dsl_dataset_t *ds;
4929 5570
4930 5571 ds = dmu_objset_ds(zfsvfs->z_os);
4931 5572 error = zfs_suspend_fs(zfsvfs);
4932 5573 if (error == 0) {
4933 5574 dmu_objset_refresh_ownership(zfsvfs->z_os,
4934 5575 zfsvfs);
4935 5576 error = zfs_resume_fs(zfsvfs, ds);
4936 5577 }
4937 5578 }
4938 5579 if (error == 0)
4939 5580 error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
4940 5581 VFS_RELE(zfsvfs->z_vfs);
4941 5582 } else {
4942 5583 /* XXX kind of reading contents without owning */
4943 5584 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
4944 5585 if (error != 0)
4945 5586 return (error);
4946 5587
4947 5588 error = dmu_objset_userspace_upgrade(os);
4948 5589 dmu_objset_rele(os, FTAG);
4949 5590 }
4950 5591
4951 5592 return (error);
4952 5593 }
4953 5594
4954 5595 /*
4955 5596 * We don't want to have a hard dependency
4956 5597 * against some special symbols in sharefs
4957 5598 * nfs, and smbsrv. Determine them if needed when
4958 5599 * the first file system is shared.
4959 5600 * Neither sharefs, nfs or smbsrv are unloadable modules.
4960 5601 */
4961 5602 int (*znfsexport_fs)(void *arg);
4962 5603 int (*zshare_fs)(enum sharefs_sys_op, share_t *, uint32_t);
4963 5604 int (*zsmbexport_fs)(void *arg, boolean_t add_share);
4964 5605
4965 5606 int zfs_nfsshare_inited;
4966 5607 int zfs_smbshare_inited;
4967 5608
4968 5609 ddi_modhandle_t nfs_mod;
4969 5610 ddi_modhandle_t sharefs_mod;
4970 5611 ddi_modhandle_t smbsrv_mod;
4971 5612 kmutex_t zfs_share_lock;
4972 5613
4973 5614 static int
4974 5615 zfs_init_sharefs()
4975 5616 {
4976 5617 int error;
4977 5618
4978 5619 ASSERT(MUTEX_HELD(&zfs_share_lock));
4979 5620 /* Both NFS and SMB shares also require sharetab support. */
4980 5621 if (sharefs_mod == NULL && ((sharefs_mod =
4981 5622 ddi_modopen("fs/sharefs",
4982 5623 KRTLD_MODE_FIRST, &error)) == NULL)) {
4983 5624 return (SET_ERROR(ENOSYS));
4984 5625 }
4985 5626 if (zshare_fs == NULL && ((zshare_fs =
4986 5627 (int (*)(enum sharefs_sys_op, share_t *, uint32_t))
4987 5628 ddi_modsym(sharefs_mod, "sharefs_impl", &error)) == NULL)) {
4988 5629 return (SET_ERROR(ENOSYS));
4989 5630 }
4990 5631 return (0);
4991 5632 }
4992 5633
4993 5634 static int
4994 5635 zfs_ioc_share(zfs_cmd_t *zc)
4995 5636 {
4996 5637 int error;
4997 5638 int opcode;
4998 5639
4999 5640 switch (zc->zc_share.z_sharetype) {
5000 5641 case ZFS_SHARE_NFS:
5001 5642 case ZFS_UNSHARE_NFS:
5002 5643 if (zfs_nfsshare_inited == 0) {
5003 5644 mutex_enter(&zfs_share_lock);
5004 5645 if (nfs_mod == NULL && ((nfs_mod = ddi_modopen("fs/nfs",
5005 5646 KRTLD_MODE_FIRST, &error)) == NULL)) {
5006 5647 mutex_exit(&zfs_share_lock);
5007 5648 return (SET_ERROR(ENOSYS));
5008 5649 }
5009 5650 if (znfsexport_fs == NULL &&
5010 5651 ((znfsexport_fs = (int (*)(void *))
5011 5652 ddi_modsym(nfs_mod,
5012 5653 "nfs_export", &error)) == NULL)) {
5013 5654 mutex_exit(&zfs_share_lock);
5014 5655 return (SET_ERROR(ENOSYS));
5015 5656 }
5016 5657 error = zfs_init_sharefs();
5017 5658 if (error != 0) {
5018 5659 mutex_exit(&zfs_share_lock);
5019 5660 return (SET_ERROR(ENOSYS));
5020 5661 }
5021 5662 zfs_nfsshare_inited = 1;
5022 5663 mutex_exit(&zfs_share_lock);
5023 5664 }
5024 5665 break;
5025 5666 case ZFS_SHARE_SMB:
5026 5667 case ZFS_UNSHARE_SMB:
5027 5668 if (zfs_smbshare_inited == 0) {
5028 5669 mutex_enter(&zfs_share_lock);
5029 5670 if (smbsrv_mod == NULL && ((smbsrv_mod =
5030 5671 ddi_modopen("drv/smbsrv",
5031 5672 KRTLD_MODE_FIRST, &error)) == NULL)) {
5032 5673 mutex_exit(&zfs_share_lock);
5033 5674 return (SET_ERROR(ENOSYS));
5034 5675 }
5035 5676 if (zsmbexport_fs == NULL && ((zsmbexport_fs =
5036 5677 (int (*)(void *, boolean_t))ddi_modsym(smbsrv_mod,
5037 5678 "smb_server_share", &error)) == NULL)) {
5038 5679 mutex_exit(&zfs_share_lock);
5039 5680 return (SET_ERROR(ENOSYS));
5040 5681 }
5041 5682 error = zfs_init_sharefs();
5042 5683 if (error != 0) {
5043 5684 mutex_exit(&zfs_share_lock);
5044 5685 return (SET_ERROR(ENOSYS));
5045 5686 }
5046 5687 zfs_smbshare_inited = 1;
5047 5688 mutex_exit(&zfs_share_lock);
5048 5689 }
5049 5690 break;
5050 5691 default:
5051 5692 return (SET_ERROR(EINVAL));
5052 5693 }
5053 5694
5054 5695 switch (zc->zc_share.z_sharetype) {
5055 5696 case ZFS_SHARE_NFS:
5056 5697 case ZFS_UNSHARE_NFS:
5057 5698 if (error =
5058 5699 znfsexport_fs((void *)
5059 5700 (uintptr_t)zc->zc_share.z_exportdata))
5060 5701 return (error);
5061 5702 break;
5062 5703 case ZFS_SHARE_SMB:
5063 5704 case ZFS_UNSHARE_SMB:
5064 5705 if (error = zsmbexport_fs((void *)
5065 5706 (uintptr_t)zc->zc_share.z_exportdata,
5066 5707 zc->zc_share.z_sharetype == ZFS_SHARE_SMB ?
5067 5708 B_TRUE: B_FALSE)) {
5068 5709 return (error);
5069 5710 }
5070 5711 break;
5071 5712 }
5072 5713
5073 5714 opcode = (zc->zc_share.z_sharetype == ZFS_SHARE_NFS ||
5074 5715 zc->zc_share.z_sharetype == ZFS_SHARE_SMB) ?
5075 5716 SHAREFS_ADD : SHAREFS_REMOVE;
5076 5717
5077 5718 /*
5078 5719 * Add or remove share from sharetab
5079 5720 */
5080 5721 error = zshare_fs(opcode,
5081 5722 (void *)(uintptr_t)zc->zc_share.z_sharedata,
5082 5723 zc->zc_share.z_sharemax);
5083 5724
5084 5725 return (error);
5085 5726
5086 5727 }
5087 5728
5088 5729 ace_t full_access[] = {
5089 5730 {(uid_t)-1, ACE_ALL_PERMS, ACE_EVERYONE, 0}
5090 5731 };
5091 5732
5092 5733 /*
5093 5734 * inputs:
5094 5735 * zc_name name of containing filesystem
5095 5736 * zc_obj object # beyond which we want next in-use object #
5096 5737 *
5097 5738 * outputs:
5098 5739 * zc_obj next in-use object #
5099 5740 */
5100 5741 static int
5101 5742 zfs_ioc_next_obj(zfs_cmd_t *zc)
5102 5743 {
5103 5744 objset_t *os = NULL;
5104 5745 int error;
5105 5746
5106 5747 error = dmu_objset_hold(zc->zc_name, FTAG, &os);
5107 5748 if (error != 0)
5108 5749 return (error);
5109 5750
5110 5751 error = dmu_object_next(os, &zc->zc_obj, B_FALSE,
5111 5752 dsl_dataset_phys(os->os_dsl_dataset)->ds_prev_snap_txg);
5112 5753
5113 5754 dmu_objset_rele(os, FTAG);
5114 5755 return (error);
5115 5756 }
5116 5757
5117 5758 /*
5118 5759 * inputs:
5119 5760 * zc_name name of filesystem
5120 5761 * zc_value prefix name for snapshot
5121 5762 * zc_cleanup_fd cleanup-on-exit file descriptor for calling process
5122 5763 *
5123 5764 * outputs:
5124 5765 * zc_value short name of new snapshot
5125 5766 */
5126 5767 static int
5127 5768 zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
5128 5769 {
5129 5770 char *snap_name;
5130 5771 char *hold_name;
5131 5772 int error;
5132 5773 minor_t minor;
5133 5774
5134 5775 error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
5135 5776 if (error != 0)
5136 5777 return (error);
5137 5778
5138 5779 snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
5139 5780 (u_longlong_t)ddi_get_lbolt64());
5140 5781 hold_name = kmem_asprintf("%%%s", zc->zc_value);
5141 5782
5142 5783 error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
5143 5784 hold_name);
5144 5785 if (error == 0)
5145 5786 (void) strcpy(zc->zc_value, snap_name);
5146 5787 strfree(snap_name);
5147 5788 strfree(hold_name);
5148 5789 zfs_onexit_fd_rele(zc->zc_cleanup_fd);
5149 5790 return (error);
5150 5791 }
5151 5792
5152 5793 /*
5153 5794 * inputs:
5154 5795 * zc_name name of "to" snapshot
5155 5796 * zc_value name of "from" snapshot
5156 5797 * zc_cookie file descriptor to write diff data on
5157 5798 *
5158 5799 * outputs:
5159 5800 * dmu_diff_record_t's to the file descriptor
5160 5801 */
5161 5802 static int
5162 5803 zfs_ioc_diff(zfs_cmd_t *zc)
5163 5804 {
5164 5805 file_t *fp;
5165 5806 offset_t off;
5166 5807 int error;
5167 5808
5168 5809 fp = getf(zc->zc_cookie);
5169 5810 if (fp == NULL)
5170 5811 return (SET_ERROR(EBADF));
5171 5812
5172 5813 off = fp->f_offset;
5173 5814
5174 5815 error = dmu_diff(zc->zc_name, zc->zc_value, fp->f_vnode, &off);
5175 5816
5176 5817 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5177 5818 fp->f_offset = off;
5178 5819 releasef(zc->zc_cookie);
5179 5820
5180 5821 return (error);
5181 5822 }
5182 5823
5183 5824 /*
5184 5825 * Remove all ACL files in shares dir
5185 5826 */
5186 5827 static int
5187 5828 zfs_smb_acl_purge(znode_t *dzp)
5188 5829 {
5189 5830 zap_cursor_t zc;
5190 5831 zap_attribute_t zap;
5191 5832 zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
5192 5833 int error;
5193 5834
5194 5835 for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id);
5195 5836 (error = zap_cursor_retrieve(&zc, &zap)) == 0;
5196 5837 zap_cursor_advance(&zc)) {
5197 5838 if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
5198 5839 NULL, 0)) != 0)
5199 5840 break;
5200 5841 }
5201 5842 zap_cursor_fini(&zc);
5202 5843 return (error);
5203 5844 }
5204 5845
5205 5846 static int
5206 5847 zfs_ioc_smb_acl(zfs_cmd_t *zc)
5207 5848 {
5208 5849 vnode_t *vp;
5209 5850 znode_t *dzp;
5210 5851 vnode_t *resourcevp = NULL;
5211 5852 znode_t *sharedir;
5212 5853 zfsvfs_t *zfsvfs;
5213 5854 nvlist_t *nvlist;
5214 5855 char *src, *target;
5215 5856 vattr_t vattr;
5216 5857 vsecattr_t vsec;
5217 5858 int error = 0;
5218 5859
5219 5860 if ((error = lookupname(zc->zc_value, UIO_SYSSPACE,
5220 5861 NO_FOLLOW, NULL, &vp)) != 0)
5221 5862 return (error);
5222 5863
5223 5864 /* Now make sure mntpnt and dataset are ZFS */
5224 5865
5225 5866 if (vp->v_vfsp->vfs_fstype != zfsfstype ||
5226 5867 (strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
5227 5868 zc->zc_name) != 0)) {
5228 5869 VN_RELE(vp);
5229 5870 return (SET_ERROR(EINVAL));
5230 5871 }
5231 5872
5232 5873 dzp = VTOZ(vp);
5233 5874 zfsvfs = dzp->z_zfsvfs;
5234 5875 ZFS_ENTER(zfsvfs);
5235 5876
5236 5877 /*
5237 5878 * Create share dir if its missing.
5238 5879 */
5239 5880 mutex_enter(&zfsvfs->z_lock);
5240 5881 if (zfsvfs->z_shares_dir == 0) {
5241 5882 dmu_tx_t *tx;
5242 5883
5243 5884 tx = dmu_tx_create(zfsvfs->z_os);
5244 5885 dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
5245 5886 ZFS_SHARES_DIR);
5246 5887 dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
5247 5888 error = dmu_tx_assign(tx, TXG_WAIT);
5248 5889 if (error != 0) {
5249 5890 dmu_tx_abort(tx);
5250 5891 } else {
5251 5892 error = zfs_create_share_dir(zfsvfs, tx);
5252 5893 dmu_tx_commit(tx);
5253 5894 }
5254 5895 if (error != 0) {
5255 5896 mutex_exit(&zfsvfs->z_lock);
5256 5897 VN_RELE(vp);
5257 5898 ZFS_EXIT(zfsvfs);
5258 5899 return (error);
5259 5900 }
5260 5901 }
5261 5902 mutex_exit(&zfsvfs->z_lock);
5262 5903
5263 5904 ASSERT(zfsvfs->z_shares_dir);
5264 5905 if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
5265 5906 VN_RELE(vp);
5266 5907 ZFS_EXIT(zfsvfs);
5267 5908 return (error);
5268 5909 }
5269 5910
5270 5911 switch (zc->zc_cookie) {
5271 5912 case ZFS_SMB_ACL_ADD:
5272 5913 vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
5273 5914 vattr.va_type = VREG;
5274 5915 vattr.va_mode = S_IFREG|0777;
5275 5916 vattr.va_uid = 0;
5276 5917 vattr.va_gid = 0;
5277 5918
5278 5919 vsec.vsa_mask = VSA_ACE;
5279 5920 vsec.vsa_aclentp = &full_access;
5280 5921 vsec.vsa_aclentsz = sizeof (full_access);
5281 5922 vsec.vsa_aclcnt = 1;
5282 5923
5283 5924 error = VOP_CREATE(ZTOV(sharedir), zc->zc_string,
5284 5925 &vattr, EXCL, 0, &resourcevp, kcred, 0, NULL, &vsec);
5285 5926 if (resourcevp)
5286 5927 VN_RELE(resourcevp);
5287 5928 break;
5288 5929
5289 5930 case ZFS_SMB_ACL_REMOVE:
5290 5931 error = VOP_REMOVE(ZTOV(sharedir), zc->zc_string, kcred,
5291 5932 NULL, 0);
5292 5933 break;
5293 5934
5294 5935 case ZFS_SMB_ACL_RENAME:
5295 5936 if ((error = get_nvlist(zc->zc_nvlist_src,
5296 5937 zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
5297 5938 VN_RELE(vp);
5298 5939 VN_RELE(ZTOV(sharedir));
5299 5940 ZFS_EXIT(zfsvfs);
5300 5941 return (error);
5301 5942 }
5302 5943 if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
5303 5944 nvlist_lookup_string(nvlist, ZFS_SMB_ACL_TARGET,
5304 5945 &target)) {
5305 5946 VN_RELE(vp);
5306 5947 VN_RELE(ZTOV(sharedir));
5307 5948 ZFS_EXIT(zfsvfs);
5308 5949 nvlist_free(nvlist);
5309 5950 return (error);
5310 5951 }
5311 5952 error = VOP_RENAME(ZTOV(sharedir), src, ZTOV(sharedir), target,
5312 5953 kcred, NULL, 0);
5313 5954 nvlist_free(nvlist);
5314 5955 break;
5315 5956
5316 5957 case ZFS_SMB_ACL_PURGE:
5317 5958 error = zfs_smb_acl_purge(sharedir);
5318 5959 break;
5319 5960
5320 5961 default:
5321 5962 error = SET_ERROR(EINVAL);
5322 5963 break;
5323 5964 }
5324 5965
5325 5966 VN_RELE(vp);
5326 5967 VN_RELE(ZTOV(sharedir));
5327 5968
5328 5969 ZFS_EXIT(zfsvfs);
5329 5970
5330 5971 return (error);
5331 5972 }
5332 5973
5333 5974 /*
5334 5975 * innvl: {
5335 5976 * "holds" -> { snapname -> holdname (string), ... }
5336 5977 * (optional) "cleanup_fd" -> fd (int32)
5337 5978 * }
5338 5979 *
5339 5980 * outnvl: {
5340 5981 * snapname -> error value (int32)
5341 5982 * ...
5342 5983 * }
5343 5984 */
5344 5985 /* ARGSUSED */
5345 5986 static int
5346 5987 zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
5347 5988 {
5348 5989 nvpair_t *pair;
5349 5990 nvlist_t *holds;
5350 5991 int cleanup_fd = -1;
5351 5992 int error;
5352 5993 minor_t minor = 0;
5353 5994
5354 5995 error = nvlist_lookup_nvlist(args, "holds", &holds);
5355 5996 if (error != 0)
5356 5997 return (SET_ERROR(EINVAL));
5357 5998
5358 5999 /* make sure the user didn't pass us any invalid (empty) tags */
5359 6000 for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
5360 6001 pair = nvlist_next_nvpair(holds, pair)) {
5361 6002 char *htag;
5362 6003
5363 6004 error = nvpair_value_string(pair, &htag);
5364 6005 if (error != 0)
5365 6006 return (SET_ERROR(error));
5366 6007
5367 6008 if (strlen(htag) == 0)
5368 6009 return (SET_ERROR(EINVAL));
5369 6010 }
5370 6011
5371 6012 if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
5372 6013 error = zfs_onexit_fd_hold(cleanup_fd, &minor);
5373 6014 if (error != 0)
5374 6015 return (error);
5375 6016 }
5376 6017
5377 6018 error = dsl_dataset_user_hold(holds, minor, errlist);
5378 6019 if (minor != 0)
5379 6020 zfs_onexit_fd_rele(cleanup_fd);
5380 6021 return (error);
5381 6022 }
5382 6023
5383 6024 /*
5384 6025 * innvl is not used.
5385 6026 *
5386 6027 * outnvl: {
5387 6028 * holdname -> time added (uint64 seconds since epoch)
5388 6029 * ...
5389 6030 * }
5390 6031 */
5391 6032 /* ARGSUSED */
5392 6033 static int
5393 6034 zfs_ioc_get_holds(const char *snapname, nvlist_t *args, nvlist_t *outnvl)
5394 6035 {
5395 6036 return (dsl_dataset_get_holds(snapname, outnvl));
5396 6037 }
5397 6038
5398 6039 /*
5399 6040 * innvl: {
5400 6041 * snapname -> { holdname, ... }
5401 6042 * ...
5402 6043 * }
5403 6044 *
5404 6045 * outnvl: {
5405 6046 * snapname -> error value (int32)
5406 6047 * ...
5407 6048 * }
5408 6049 */
5409 6050 /* ARGSUSED */
5410 6051 static int
5411 6052 zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
5412 6053 {
5413 6054 return (dsl_dataset_user_release(holds, errlist));
5414 6055 }
5415 6056
5416 6057 /*
5417 6058 * inputs:
5418 6059 * zc_name name of new filesystem or snapshot
5419 6060 * zc_value full name of old snapshot
5420 6061 *
5421 6062 * outputs:
5422 6063 * zc_cookie space in bytes
5423 6064 * zc_objset_type compressed space in bytes
5424 6065 * zc_perm_action uncompressed space in bytes
5425 6066 */
5426 6067 static int
5427 6068 zfs_ioc_space_written(zfs_cmd_t *zc)
5428 6069 {
5429 6070 int error;
5430 6071 dsl_pool_t *dp;
5431 6072 dsl_dataset_t *new, *old;
5432 6073
5433 6074 error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
5434 6075 if (error != 0)
5435 6076 return (error);
5436 6077 error = dsl_dataset_hold(dp, zc->zc_name, FTAG, &new);
5437 6078 if (error != 0) {
5438 6079 dsl_pool_rele(dp, FTAG);
5439 6080 return (error);
5440 6081 }
5441 6082 error = dsl_dataset_hold(dp, zc->zc_value, FTAG, &old);
5442 6083 if (error != 0) {
5443 6084 dsl_dataset_rele(new, FTAG);
5444 6085 dsl_pool_rele(dp, FTAG);
5445 6086 return (error);
5446 6087 }
5447 6088
5448 6089 error = dsl_dataset_space_written(old, new, &zc->zc_cookie,
5449 6090 &zc->zc_objset_type, &zc->zc_perm_action);
5450 6091 dsl_dataset_rele(old, FTAG);
5451 6092 dsl_dataset_rele(new, FTAG);
5452 6093 dsl_pool_rele(dp, FTAG);
5453 6094 return (error);
5454 6095 }
5455 6096
5456 6097 /*
5457 6098 * innvl: {
5458 6099 * "firstsnap" -> snapshot name
5459 6100 * }
5460 6101 *
5461 6102 * outnvl: {
5462 6103 * "used" -> space in bytes
5463 6104 * "compressed" -> compressed space in bytes
5464 6105 * "uncompressed" -> uncompressed space in bytes
5465 6106 * }
5466 6107 */
5467 6108 static int
5468 6109 zfs_ioc_space_snaps(const char *lastsnap, nvlist_t *innvl, nvlist_t *outnvl)
5469 6110 {
5470 6111 int error;
5471 6112 dsl_pool_t *dp;
5472 6113 dsl_dataset_t *new, *old;
5473 6114 char *firstsnap;
5474 6115 uint64_t used, comp, uncomp;
5475 6116
5476 6117 if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
5477 6118 return (SET_ERROR(EINVAL));
5478 6119
5479 6120 error = dsl_pool_hold(lastsnap, FTAG, &dp);
5480 6121 if (error != 0)
5481 6122 return (error);
5482 6123
5483 6124 error = dsl_dataset_hold(dp, lastsnap, FTAG, &new);
5484 6125 if (error == 0 && !new->ds_is_snapshot) {
5485 6126 dsl_dataset_rele(new, FTAG);
5486 6127 error = SET_ERROR(EINVAL);
5487 6128 }
5488 6129 if (error != 0) {
5489 6130 dsl_pool_rele(dp, FTAG);
5490 6131 return (error);
5491 6132 }
5492 6133 error = dsl_dataset_hold(dp, firstsnap, FTAG, &old);
5493 6134 if (error == 0 && !old->ds_is_snapshot) {
5494 6135 dsl_dataset_rele(old, FTAG);
5495 6136 error = SET_ERROR(EINVAL);
5496 6137 }
5497 6138 if (error != 0) {
5498 6139 dsl_dataset_rele(new, FTAG);
5499 6140 dsl_pool_rele(dp, FTAG);
5500 6141 return (error);
5501 6142 }
5502 6143
|
↓ open down ↓ |
660 lines elided |
↑ open up ↑ |
5503 6144 error = dsl_dataset_space_wouldfree(old, new, &used, &comp, &uncomp);
5504 6145 dsl_dataset_rele(old, FTAG);
5505 6146 dsl_dataset_rele(new, FTAG);
5506 6147 dsl_pool_rele(dp, FTAG);
5507 6148 fnvlist_add_uint64(outnvl, "used", used);
5508 6149 fnvlist_add_uint64(outnvl, "compressed", comp);
5509 6150 fnvlist_add_uint64(outnvl, "uncompressed", uncomp);
5510 6151 return (error);
5511 6152 }
5512 6153
6154 +static int
6155 +zfs_ioc_vdev_set_props(zfs_cmd_t *zc)
6156 +{
6157 + nvlist_t *props;
6158 + spa_t *spa;
6159 + int error;
6160 + uint64_t vdev_guid = zc->zc_guid;
6161 +
6162 + if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
6163 + zc->zc_iflags, &props))
6164 + return (error);
6165 +
6166 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
6167 + nvlist_free(props);
6168 + return (error);
6169 + }
6170 +
6171 + error = spa_vdev_prop_set(spa, vdev_guid, props);
6172 +
6173 + nvlist_free(props);
6174 + spa_close(spa, FTAG);
6175 +
6176 + return (error);
6177 +}
6178 +
6179 +static int
6180 +zfs_ioc_vdev_get_props(zfs_cmd_t *zc)
6181 +{
6182 + spa_t *spa;
6183 + uint64_t vdev_guid = zc->zc_guid;
6184 + nvlist_t *nvp = NULL;
6185 + int error;
6186 +
6187 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
6188 + /*
6189 + * If the pool is faulted, there may be properties we can still
6190 + * get (such as altroot and cachefile), so attempt to get them
6191 + * anyway.
6192 + */
6193 + mutex_enter(&spa_namespace_lock);
6194 + if ((spa = spa_lookup(zc->zc_name)) != NULL)
6195 + error = spa_vdev_prop_get(spa, vdev_guid, &nvp);
6196 + mutex_exit(&spa_namespace_lock);
6197 + } else {
6198 + error = spa_vdev_prop_get(spa, vdev_guid, &nvp);
6199 + spa_close(spa, FTAG);
6200 + }
6201 +
6202 + if (error == 0 && zc->zc_nvlist_dst != NULL)
6203 + error = put_nvlist(zc, nvp);
6204 + else
6205 + error = EFAULT;
6206 +
6207 + nvlist_free(nvp);
6208 + return (error);
6209 +}
6210 +
6211 +static int
6212 +zfs_ioc_cos_alloc(zfs_cmd_t *zc)
6213 +{
6214 + nvlist_t *props;
6215 + spa_t *spa;
6216 + int error;
6217 +
6218 + if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
6219 + zc->zc_iflags, &props))
6220 + return (error);
6221 +
6222 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
6223 + nvlist_free(props);
6224 + return (error);
6225 + }
6226 +
6227 + error = spa_alloc_cos(spa, zc->zc_string, 0);
6228 + if (!error)
6229 + error = spa_cos_prop_set(spa, zc->zc_string, props);
6230 +
6231 + spa_close(spa, FTAG);
6232 + nvlist_free(props);
6233 +
6234 + return (error);
6235 +}
6236 +
6237 +static int
6238 +zfs_ioc_cos_free(zfs_cmd_t *zc)
6239 +{
6240 + spa_t *spa;
6241 + int error = 0;
6242 +
6243 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
6244 + return (error);
6245 +
6246 + error = spa_free_cos(spa, zc->zc_string, zc->zc_cookie);
6247 +
6248 + spa_close(spa, FTAG);
6249 +
6250 + return (error);
6251 +}
6252 +
6253 +static int
6254 +zfs_ioc_cos_list(zfs_cmd_t *zc)
6255 +{
6256 + spa_t *spa;
6257 + nvlist_t *nvl;
6258 + int error = 0;
6259 +
6260 + VERIFY(nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0);
6261 +
6262 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
6263 + nvlist_free(nvl);
6264 + return (error);
6265 + }
6266 +
6267 + error = spa_list_cos(spa, nvl);
6268 +
6269 + if (error == 0 && zc->zc_nvlist_dst != NULL)
6270 + error = put_nvlist(zc, nvl);
6271 +
6272 + spa_close(spa, FTAG);
6273 + nvlist_free(nvl);
6274 +
6275 + return (error);
6276 +}
6277 +
6278 +static int
6279 +zfs_ioc_cos_set_props(zfs_cmd_t *zc)
6280 +{
6281 + nvlist_t *props;
6282 + spa_t *spa;
6283 + cos_t *cos;
6284 + const char *cosname = NULL;
6285 + int error = 0;
6286 +
6287 + if ((zc->zc_string == NULL || zc->zc_string[0] == '\0') &&
6288 + zc->zc_guid == 0)
6289 + return (SET_ERROR(EINVAL));
6290 +
6291 + if (error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
6292 + zc->zc_iflags, &props))
6293 + return (error);
6294 +
6295 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0) {
6296 + nvlist_free(props);
6297 + return (error);
6298 + }
6299 +
6300 + if (zc->zc_guid == 0) {
6301 + cosname = zc->zc_string;
6302 + } else {
6303 + spa_cos_enter(spa);
6304 + cos = spa_lookup_cos_by_guid(spa, zc->zc_guid);
6305 + if (cos != NULL)
6306 + cosname = cos->cos_name;
6307 + else
6308 + error = SET_ERROR(ENOENT);
6309 + spa_cos_exit(spa);
6310 + }
6311 +
6312 + if (error == 0)
6313 + error = spa_cos_prop_set(spa, cosname, props);
6314 +
6315 + spa_close(spa, FTAG);
6316 + nvlist_free(props);
6317 +
6318 + return (error);
6319 +}
6320 +
6321 +static int
6322 +zfs_ioc_cos_get_props(zfs_cmd_t *zc)
6323 +{
6324 + spa_t *spa;
6325 + cos_t *cos;
6326 + nvlist_t *nvp = NULL;
6327 + const char *cosname = NULL;
6328 + int error = 0;
6329 +
6330 + if ((zc->zc_string == NULL || zc->zc_string[0] == '\0') &&
6331 + zc->zc_guid == 0)
6332 + return (SET_ERROR(EINVAL));
6333 +
6334 + if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
6335 + return (error);
6336 +
6337 + if (zc->zc_guid == 0) {
6338 + cosname = zc->zc_string;
6339 + } else {
6340 + spa_cos_enter(spa);
6341 + cos = spa_lookup_cos_by_guid(spa, zc->zc_guid);
6342 + if (cos != NULL)
6343 + cosname = cos->cos_name;
6344 + spa_cos_exit(spa);
6345 + }
6346 +
6347 + if (error == 0)
6348 + error = spa_cos_prop_get(spa, cosname, &nvp);
6349 +
6350 + spa_close(spa, FTAG);
6351 +
6352 + if (error == 0 && zc->zc_nvlist_dst != NULL)
6353 + error = put_nvlist(zc, nvp);
6354 + else
6355 + error = EFAULT;
6356 +
6357 + nvlist_free(nvp);
6358 + return (error);
6359 +}
6360 +
5513 6361 /*
5514 6362 * innvl: {
5515 6363 * "fd" -> file descriptor to write stream to (int32)
5516 6364 * (optional) "fromsnap" -> full snap name to send an incremental from
5517 6365 * (optional) "largeblockok" -> (value ignored)
5518 6366 * indicates that blocks > 128KB are permitted
5519 6367 * (optional) "embedok" -> (value ignored)
5520 6368 * presence indicates DRR_WRITE_EMBEDDED records are permitted
5521 6369 * (optional) "compressok" -> (value ignored)
5522 6370 * presence indicates compressed DRR_WRITE records are permitted
5523 6371 * (optional) "resume_object" and "resume_offset" -> (uint64)
5524 6372 * if present, resume send stream from specified object and offset.
5525 6373 * }
5526 6374 *
5527 6375 * outnvl is unused
5528 6376 */
5529 6377 /* ARGSUSED */
5530 6378 static int
5531 6379 zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5532 6380 {
5533 6381 int error;
5534 6382 offset_t off;
5535 6383 char *fromname = NULL;
5536 6384 int fd;
5537 6385 boolean_t largeblockok;
5538 6386 boolean_t embedok;
5539 6387 boolean_t compressok;
5540 6388 uint64_t resumeobj = 0;
5541 6389 uint64_t resumeoff = 0;
5542 6390
5543 6391 error = nvlist_lookup_int32(innvl, "fd", &fd);
5544 6392 if (error != 0)
5545 6393 return (SET_ERROR(EINVAL));
5546 6394
5547 6395 (void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
5548 6396
5549 6397 largeblockok = nvlist_exists(innvl, "largeblockok");
5550 6398 embedok = nvlist_exists(innvl, "embedok");
5551 6399 compressok = nvlist_exists(innvl, "compressok");
5552 6400
5553 6401 (void) nvlist_lookup_uint64(innvl, "resume_object", &resumeobj);
5554 6402 (void) nvlist_lookup_uint64(innvl, "resume_offset", &resumeoff);
5555 6403
5556 6404 file_t *fp = getf(fd);
5557 6405 if (fp == NULL)
5558 6406 return (SET_ERROR(EBADF));
5559 6407
5560 6408 off = fp->f_offset;
5561 6409 error = dmu_send(snapname, fromname, embedok, largeblockok, compressok,
5562 6410 fd, resumeobj, resumeoff, fp->f_vnode, &off);
5563 6411
5564 6412 if (VOP_SEEK(fp->f_vnode, fp->f_offset, &off, NULL) == 0)
5565 6413 fp->f_offset = off;
5566 6414 releasef(fd);
5567 6415 return (error);
5568 6416 }
5569 6417
5570 6418 /*
5571 6419 * Determine approximately how large a zfs send stream will be -- the number
5572 6420 * of bytes that will be written to the fd supplied to zfs_ioc_send_new().
5573 6421 *
5574 6422 * innvl: {
5575 6423 * (optional) "from" -> full snap or bookmark name to send an incremental
5576 6424 * from
5577 6425 * (optional) "largeblockok" -> (value ignored)
5578 6426 * indicates that blocks > 128KB are permitted
5579 6427 * (optional) "embedok" -> (value ignored)
5580 6428 * presence indicates DRR_WRITE_EMBEDDED records are permitted
5581 6429 * (optional) "compressok" -> (value ignored)
5582 6430 * presence indicates compressed DRR_WRITE records are permitted
5583 6431 * }
5584 6432 *
5585 6433 * outnvl: {
5586 6434 * "space" -> bytes of space (uint64)
5587 6435 * }
5588 6436 */
5589 6437 static int
5590 6438 zfs_ioc_send_space(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
5591 6439 {
5592 6440 dsl_pool_t *dp;
5593 6441 dsl_dataset_t *tosnap;
5594 6442 int error;
5595 6443 char *fromname;
5596 6444 boolean_t compressok;
5597 6445 uint64_t space;
5598 6446
5599 6447 error = dsl_pool_hold(snapname, FTAG, &dp);
5600 6448 if (error != 0)
5601 6449 return (error);
5602 6450
5603 6451 error = dsl_dataset_hold(dp, snapname, FTAG, &tosnap);
5604 6452 if (error != 0) {
5605 6453 dsl_pool_rele(dp, FTAG);
5606 6454 return (error);
5607 6455 }
5608 6456
5609 6457 compressok = nvlist_exists(innvl, "compressok");
5610 6458
5611 6459 error = nvlist_lookup_string(innvl, "from", &fromname);
5612 6460 if (error == 0) {
5613 6461 if (strchr(fromname, '@') != NULL) {
5614 6462 /*
5615 6463 * If from is a snapshot, hold it and use the more
5616 6464 * efficient dmu_send_estimate to estimate send space
5617 6465 * size using deadlists.
5618 6466 */
5619 6467 dsl_dataset_t *fromsnap;
5620 6468 error = dsl_dataset_hold(dp, fromname, FTAG, &fromsnap);
5621 6469 if (error != 0)
5622 6470 goto out;
5623 6471 error = dmu_send_estimate(tosnap, fromsnap, compressok,
5624 6472 &space);
5625 6473 dsl_dataset_rele(fromsnap, FTAG);
5626 6474 } else if (strchr(fromname, '#') != NULL) {
5627 6475 /*
5628 6476 * If from is a bookmark, fetch the creation TXG of the
5629 6477 * snapshot it was created from and use that to find
5630 6478 * blocks that were born after it.
5631 6479 */
5632 6480 zfs_bookmark_phys_t frombm;
5633 6481
5634 6482 error = dsl_bookmark_lookup(dp, fromname, tosnap,
5635 6483 &frombm);
5636 6484 if (error != 0)
5637 6485 goto out;
5638 6486 error = dmu_send_estimate_from_txg(tosnap,
5639 6487 frombm.zbm_creation_txg, compressok, &space);
5640 6488 } else {
5641 6489 /*
5642 6490 * from is not properly formatted as a snapshot or
5643 6491 * bookmark
5644 6492 */
5645 6493 error = SET_ERROR(EINVAL);
5646 6494 goto out;
5647 6495 }
5648 6496 } else {
5649 6497 /*
5650 6498 * If estimating the size of a full send, use dmu_send_estimate.
5651 6499 */
5652 6500 error = dmu_send_estimate(tosnap, NULL, compressok, &space);
|
↓ open down ↓ |
130 lines elided |
↑ open up ↑ |
5653 6501 }
5654 6502
5655 6503 fnvlist_add_uint64(outnvl, "space", space);
5656 6504
5657 6505 out:
5658 6506 dsl_dataset_rele(tosnap, FTAG);
5659 6507 dsl_pool_rele(dp, FTAG);
5660 6508 return (error);
5661 6509 }
5662 6510
6511 +typedef struct dp_cursor_cb_arg {
6512 + nvlist_t *outnvl;
6513 + uint64_t offset;
6514 + uint32_t count;
6515 + uint32_t skip;
6516 + boolean_t verbose;
6517 + boolean_t snaps;
6518 +} dp_cursor_cb_arg_t;
6519 +
6520 +/* ARGSUSED */
6521 +int
6522 +ds_cursor_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
6523 +{
6524 + int error;
6525 + char dsname[MAXNAMELEN];
6526 + objset_t *osp;
6527 +
6528 + dp_cursor_cb_arg_t *cb = (dp_cursor_cb_arg_t *)arg;
6529 +
6530 + dsl_dataset_name(ds, dsname);
6531 + nvlist_t *nv = fnvlist_alloc();
6532 +
6533 + fnvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_GUID),
6534 + dsl_dataset_phys(ds)->ds_guid);
6535 +
6536 + if (cb->verbose) {
6537 + uint64_t refd, avail, uobjs, aobjs;
6538 + dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs);
6539 +
6540 + fnvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_AVAILABLE),
6541 + avail);
6542 + fnvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_REFERENCED),
6543 + refd);
6544 + fnvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_USED),
6545 + dsl_dir_phys(ds->ds_dir)->dd_used_bytes);
6546 + }
6547 +
6548 + error = dmu_objset_from_ds(ds, &osp);
6549 +
6550 + if (error == 0)
6551 + fnvlist_add_uint64(nv, zfs_prop_to_name(ZFS_PROP_TYPE),
6552 + dmu_objset_type(osp));
6553 +
6554 + fnvlist_add_nvlist(cb->outnvl, dsname, nv);
6555 + nvlist_free(nv);
6556 + return (error);
6557 +}
6558 +
6559 +int
6560 +dmu_objset_find_dp_cursor(dsl_pool_t *dp, uint64_t ddobj,
6561 + int func(dsl_pool_t *, dsl_dataset_t *, void *), void *arg)
6562 +{
6563 + dsl_dir_t *dd;
6564 + dsl_dataset_t *ds;
6565 + zap_cursor_t zc;
6566 + zap_attribute_t *attr;
6567 + uint64_t thisobj;
6568 + int error, i;
6569 +
6570 + dp_cursor_cb_arg_t *cb = (dp_cursor_cb_arg_t *)arg;
6571 +
6572 + ASSERT(dsl_pool_config_held(dp));
6573 + error = dsl_dir_hold_obj(dp, ddobj, NULL, FTAG, &dd);
6574 + thisobj = dsl_dir_phys(dd)->dd_head_dataset_obj;
6575 +
6576 + if (error != 0)
6577 + return (error);
6578 +
6579 + attr = kmem_alloc(sizeof (zap_attribute_t), KM_SLEEP);
6580 +
6581 + /* we are interrestd in filesytems and volumes */
6582 + if (!cb->snaps) {
6583 +
6584 + /* init the cursor at given offset */
6585 + zap_cursor_init_serialized(&zc, dp->dp_meta_objset,
6586 + dsl_dir_phys(dd)->dd_child_dir_zapobj, cb->offset);
6587 +
6588 +
6589 + for (i = 0; i < cb->skip; i++) {
6590 + zap_cursor_advance(&zc);
6591 + if ((zap_cursor_retrieve(&zc, attr) != 0)) {
6592 + error = ENOENT;
6593 + goto out;
6594 + }
6595 + }
6596 +
6597 + for (i = 0; i < cb->count; i++) {
6598 + zap_cursor_advance(&zc);
6599 + if ((zap_cursor_retrieve(&zc, attr) != 0)) {
6600 + error = ENOENT;
6601 + goto out;
6602 + }
6603 +
6604 + ASSERT3U(attr->za_integer_length, ==,
6605 + sizeof (uint64_t));
6606 + ASSERT3U(attr->za_num_integers, ==, 1);
6607 + /* recursivly walk objects skipping $MOS and $ORIGIN */
6608 + error = dmu_objset_find_dp(dp, attr->za_first_integer,
6609 + func, arg, 0);
6610 + if (error != 0)
6611 + break;
6612 + }
6613 + } else {
6614 +
6615 + dsl_dataset_t *ds;
6616 +
6617 + error = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds);
6618 +
6619 + if (error == 0) {
6620 +
6621 + dsl_dataset_rele(ds, FTAG);
6622 + zap_cursor_init_serialized(&zc, dp->dp_meta_objset,
6623 + dsl_dataset_phys(ds)->ds_snapnames_zapobj,
6624 + cb->offset);
6625 +
6626 + for (i = 0; i < cb->skip; i++) {
6627 + zap_cursor_advance(&zc);
6628 + if ((zap_cursor_retrieve(&zc,
6629 + attr) != 0)) {
6630 + error = ENOENT;
6631 + goto out;
6632 + }
6633 + }
6634 +
6635 + for (i = 0; i < cb->count; i++) {
6636 + zap_cursor_advance(&zc);
6637 + if ((zap_cursor_retrieve(&zc, attr) != 0)) {
6638 + error = ENOENT;
6639 + goto out;
6640 +
6641 + }
6642 +
6643 + ASSERT3U(attr->za_integer_length, ==,
6644 + sizeof (uint64_t));
6645 + ASSERT3U(attr->za_num_integers, ==, 1);
6646 +
6647 + error = dsl_dataset_hold_obj(dp,
6648 + attr->za_first_integer, FTAG, &ds);
6649 + if (error != 0)
6650 + break;
6651 + error = func(dp, ds, arg);
6652 + dsl_dataset_rele(ds, FTAG);
6653 + if (error != 0)
6654 + break;
6655 + }
6656 + }
6657 + }
6658 +out:
6659 + cb->offset = zap_cursor_serialize(&zc);
6660 + zap_cursor_fini(&zc);
6661 + dsl_dir_rele(dd, FTAG);
6662 + kmem_free(attr, sizeof (zap_attribute_t));
6663 +
6664 + /* return self as the last dataset */
6665 + if (error == ENOENT) {
6666 + if ((error = dsl_dataset_hold_obj(dp, thisobj, FTAG, &ds)) != 0)
6667 + return (error);
6668 + error = func(dp, ds, arg);
6669 + dsl_dataset_rele(ds, FTAG);
6670 + if (error)
6671 + return (error);
6672 + error = ENOENT;
6673 + }
6674 +
6675 + return (error);
6676 +}
6677 +
6678 +
6679 +/*
6680 + * We want to list all dataset under the given name. Optionally, we advance the
6681 + * ZAP cursor "skip" times and retrieve "count" datasets. We return the offset
6682 + * so the user can start the next invocation where he left off.
6683 + */
6684 +
6685 +static int
6686 +zfs_ioc_list_from_cursor(const char *name, nvlist_t *innvl, nvlist_t *outnvl)
6687 +{
6688 +
6689 + dsl_pool_t *dp;
6690 + dsl_dataset_t *ds;
6691 +
6692 + int error;
6693 +
6694 + dp_cursor_cb_arg_t cb_args;
6695 +
6696 + if ((strchr(name, '@') != NULL))
6697 + return (EINVAL);
6698 +
6699 + if ((error = dsl_pool_hold(name, FTAG, &dp)) != 0)
6700 + return (error);
6701 +
6702 + if ((error = dsl_dataset_hold(dp, name, FTAG, &ds)) != 0) {
6703 + dsl_pool_rele(dp, FTAG);
6704 + return (error);
6705 + }
6706 +
6707 + (void) nvlist_lookup_uint32(innvl, "count", &cb_args.count);
6708 + (void) nvlist_lookup_uint32(innvl, "skip", &cb_args.skip);
6709 + (void) nvlist_lookup_uint64(innvl, "offset", &cb_args.offset);
6710 + (void) nvlist_lookup_boolean_value(innvl, "verbose", &cb_args.verbose);
6711 + (void) nvlist_lookup_boolean_value(innvl, "snaps", &cb_args.snaps);
6712 +
6713 + cb_args.outnvl = outnvl;
6714 + error = dmu_objset_find_dp_cursor(dp, ds->ds_dir->dd_object,
6715 + &ds_cursor_cb, &cb_args);
6716 +
6717 + fnvlist_add_uint64(outnvl, "offset", cb_args.offset);
6718 + dsl_dataset_rele(ds, FTAG);
6719 + dsl_pool_rele(dp, FTAG);
6720 +
6721 + return (error);
6722 +}
6723 +
6724 +
5663 6725 static zfs_ioc_vec_t zfs_ioc_vec[ZFS_IOC_LAST - ZFS_IOC_FIRST];
5664 6726
5665 6727 static void
5666 6728 zfs_ioctl_register_legacy(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5667 6729 zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5668 6730 boolean_t log_history, zfs_ioc_poolcheck_t pool_check)
5669 6731 {
5670 6732 zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5671 6733
5672 6734 ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5673 6735 ASSERT3U(ioc, <, ZFS_IOC_LAST);
5674 6736 ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5675 6737 ASSERT3P(vec->zvec_func, ==, NULL);
5676 6738
5677 6739 vec->zvec_legacy_func = func;
5678 6740 vec->zvec_secpolicy = secpolicy;
5679 6741 vec->zvec_namecheck = namecheck;
5680 6742 vec->zvec_allow_log = log_history;
5681 6743 vec->zvec_pool_check = pool_check;
5682 6744 }
5683 6745
5684 6746 /*
5685 6747 * See the block comment at the beginning of this file for details on
5686 6748 * each argument to this function.
5687 6749 */
5688 6750 static void
5689 6751 zfs_ioctl_register(const char *name, zfs_ioc_t ioc, zfs_ioc_func_t *func,
5690 6752 zfs_secpolicy_func_t *secpolicy, zfs_ioc_namecheck_t namecheck,
5691 6753 zfs_ioc_poolcheck_t pool_check, boolean_t smush_outnvlist,
5692 6754 boolean_t allow_log)
5693 6755 {
5694 6756 zfs_ioc_vec_t *vec = &zfs_ioc_vec[ioc - ZFS_IOC_FIRST];
5695 6757
5696 6758 ASSERT3U(ioc, >=, ZFS_IOC_FIRST);
5697 6759 ASSERT3U(ioc, <, ZFS_IOC_LAST);
5698 6760 ASSERT3P(vec->zvec_legacy_func, ==, NULL);
5699 6761 ASSERT3P(vec->zvec_func, ==, NULL);
5700 6762
5701 6763 /* if we are logging, the name must be valid */
5702 6764 ASSERT(!allow_log || namecheck != NO_NAME);
5703 6765
5704 6766 vec->zvec_name = name;
5705 6767 vec->zvec_func = func;
5706 6768 vec->zvec_secpolicy = secpolicy;
5707 6769 vec->zvec_namecheck = namecheck;
5708 6770 vec->zvec_pool_check = pool_check;
5709 6771 vec->zvec_smush_outnvlist = smush_outnvlist;
5710 6772 vec->zvec_allow_log = allow_log;
5711 6773 }
5712 6774
5713 6775 static void
5714 6776 zfs_ioctl_register_pool(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5715 6777 zfs_secpolicy_func_t *secpolicy, boolean_t log_history,
5716 6778 zfs_ioc_poolcheck_t pool_check)
5717 6779 {
5718 6780 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5719 6781 POOL_NAME, log_history, pool_check);
5720 6782 }
5721 6783
5722 6784 static void
5723 6785 zfs_ioctl_register_dataset_nolog(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5724 6786 zfs_secpolicy_func_t *secpolicy, zfs_ioc_poolcheck_t pool_check)
5725 6787 {
5726 6788 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5727 6789 DATASET_NAME, B_FALSE, pool_check);
5728 6790 }
5729 6791
5730 6792 static void
5731 6793 zfs_ioctl_register_pool_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5732 6794 {
5733 6795 zfs_ioctl_register_legacy(ioc, func, zfs_secpolicy_config,
5734 6796 POOL_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5735 6797 }
5736 6798
5737 6799 static void
5738 6800 zfs_ioctl_register_pool_meta(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5739 6801 zfs_secpolicy_func_t *secpolicy)
5740 6802 {
5741 6803 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5742 6804 NO_NAME, B_FALSE, POOL_CHECK_NONE);
5743 6805 }
5744 6806
5745 6807 static void
5746 6808 zfs_ioctl_register_dataset_read_secpolicy(zfs_ioc_t ioc,
5747 6809 zfs_ioc_legacy_func_t *func, zfs_secpolicy_func_t *secpolicy)
5748 6810 {
5749 6811 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5750 6812 DATASET_NAME, B_FALSE, POOL_CHECK_SUSPENDED);
5751 6813 }
5752 6814
5753 6815 static void
5754 6816 zfs_ioctl_register_dataset_read(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func)
5755 6817 {
5756 6818 zfs_ioctl_register_dataset_read_secpolicy(ioc, func,
5757 6819 zfs_secpolicy_read);
|
↓ open down ↓ |
85 lines elided |
↑ open up ↑ |
5758 6820 }
5759 6821
5760 6822 static void
5761 6823 zfs_ioctl_register_dataset_modify(zfs_ioc_t ioc, zfs_ioc_legacy_func_t *func,
5762 6824 zfs_secpolicy_func_t *secpolicy)
5763 6825 {
5764 6826 zfs_ioctl_register_legacy(ioc, func, secpolicy,
5765 6827 DATASET_NAME, B_TRUE, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5766 6828 }
5767 6829
6830 +/*
6831 + * Appearing to take poolname as a parameter is a concession to the ioctl
6832 + * handler. Leading underbar for generation idea nvpair exists only on output to
6833 + * avoid pool name conflict.
6834 + */
6835 +/* ARGSUSED */
6836 +static int
6837 +zfs_ioc_pool_configs_nvl(const char *poolname, nvlist_t *innvl,
6838 + nvlist_t *outnvl)
6839 +{
6840 + nvlist_t *configs;
6841 + uint64_t generation;
6842 +
6843 + if (nvlist_lookup_uint64(innvl, "generation", &generation) != 0)
6844 + return (SET_ERROR(EINVAL));
6845 +
6846 + if ((configs = spa_all_configs(&generation)) == NULL)
6847 + return (SET_ERROR(EEXIST));
6848 +
6849 + fnvlist_merge(outnvl, configs);
6850 + nvlist_free(configs);
6851 + fnvlist_add_uint64(outnvl, "_generation", generation);
6852 +
6853 + return (0);
6854 +}
6855 +
6856 +/*
6857 + * Ask spa for pool statistics. If we get a non-NULL config but a non-zero
6858 + * return from spa, we return EAGAIN to hint to callers that we've retrieved
6859 + * a config for a faulted pool. We take no arguments but declare otherwise to
6860 + * suit the ioctl handler's pattern. Similar considerations apply to outnvl as a
6861 + * single pointer that has to be merged with config allocated or nulled by spa.
6862 + */
6863 +static int
6864 +zfs_ioc_pool_stats_nvl(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
6865 +{
6866 + nvlist_t *config;
6867 + int error;
6868 + int ret = 0;
6869 +
6870 + ASSERT3P(innvl, ==, NULL);
6871 + error = spa_get_stats(poolname, &config, NULL, 0);
6872 + ASSERT3U(error, !=, EAGAIN);
6873 +
6874 + if (config != NULL) {
6875 + fnvlist_merge(outnvl, config);
6876 + nvlist_free(config);
6877 + if (error)
6878 + ret = SET_ERROR(EAGAIN);
6879 + } else {
6880 + ret = error;
6881 + }
6882 +
6883 + return (ret);
6884 +}
6885 +
6886 +static nvlist_t *
6887 +objset_stats2nv(dmu_objset_stats_t *stat)
6888 +{
6889 + nvlist_t *statlist = fnvlist_alloc();
6890 +
6891 + fnvlist_add_uint64(statlist, "dds_num_clones", stat->dds_num_clones);
6892 + fnvlist_add_uint64(statlist, "dds_creation_txg",
6893 + stat->dds_creation_txg);
6894 + fnvlist_add_uint64(statlist, "dds_guid", stat->dds_guid);
6895 + fnvlist_add_uint8(statlist, "dds_type", (uint8_t)stat->dds_type);
6896 + fnvlist_add_uint8(statlist, "dds_is_snapshot", stat->dds_is_snapshot);
6897 + fnvlist_add_uint8(statlist, "dds_inconsistent",
6898 + stat->dds_inconsistent);
6899 + fnvlist_add_string(statlist, "dds_origin", stat->dds_origin);
6900 +
6901 + return (statlist);
6902 +}
6903 +
6904 +/* Given an objset, retrieve stats and props by adding them to the output nvl */
6905 +static int
6906 +objset_render(objset_t *os, nvlist_t *outnvl)
6907 +{
6908 + int error = 0;
6909 + nvlist_t *props = NULL, *statlist = NULL;
6910 + dmu_objset_stats_t stats;
6911 +
6912 + dmu_objset_fast_stat(os, &stats);
6913 +
6914 + if ((error = dsl_prop_get_all(os, &props)) == 0) {
6915 + dmu_objset_stats(os, props);
6916 + /*
6917 + * NB: zvol_get_stats() will read the objset contents,
6918 + * which we aren't supposed to do with a
6919 + * DS_MODE_USER hold, because it could be
6920 + * inconsistent. So this is a bit of a workaround...
6921 + * XXX reading with out owning
6922 + */
6923 + if (!stats.dds_inconsistent &&
6924 + dmu_objset_type(os) == DMU_OST_ZVOL) {
6925 + error = zvol_get_stats(os, props);
6926 + if (error == EIO)
6927 + goto out;
6928 + VERIFY0(error);
6929 + }
6930 + fnvlist_add_nvlist(outnvl, "props", props);
6931 + statlist = objset_stats2nv(&stats);
6932 + fnvlist_add_nvlist(outnvl, "stats", statlist);
6933 + nvlist_free(statlist);
6934 + }
6935 +
6936 +out:
6937 + nvlist_free(props);
6938 + return (error);
6939 +}
6940 +
6941 +/*
6942 + * Note: this IOC can be called internally by other IOCs as an existence
6943 + * check against race conditions. Given a dataset name, return its stats
6944 + * and props. Optionally we can verify type, which simplifies things for
6945 + * callers that may not want to parse stats for themselves (and may discard
6946 + * the outnvl in handlers).
6947 + */
6948 +static int
6949 +zfs_ioc_objset_stats_nvl(const char *data, nvlist_t *innvl, nvlist_t *outnvl)
6950 +{
6951 + objset_t *os;
6952 + int error;
6953 + dmu_objset_type_t checktype = DMU_OST_ANY;
6954 + boolean_t gettype = B_FALSE;
6955 +
6956 + if (innvl != NULL) {
6957 + if (nvlist_lookup_uint8(innvl, "type", (uint8_t *)&checktype)
6958 + == 0)
6959 + gettype = B_TRUE;
6960 + }
6961 + if ((error = dmu_objset_hold(data, FTAG, &os)) == 0) {
6962 + error = objset_render(os, outnvl);
6963 + dmu_objset_rele(os, FTAG);
6964 +
6965 + if (error == 0) {
6966 + nvlist_t *statlist;
6967 + dmu_objset_type_t type;
6968 + statlist = fnvlist_lookup_nvlist(outnvl, "stats");
6969 + type = fnvlist_lookup_uint8_t(statlist, "dds_type");
6970 + if (checktype != DMU_OST_ANY && type != checktype) {
6971 + error = EEXIST;
6972 + fnvlist_remove(outnvl, "stats");
6973 + fnvlist_remove(outnvl, "props");
6974 + }
6975 + if (gettype)
6976 + fnvlist_add_uint8(outnvl, "type", type);
6977 + }
6978 + }
6979 +
6980 + return (error);
6981 +}
6982 +
6983 +/*
6984 + * Given a dataset name and an innvl containing a DMU cursor offset, find the
6985 + * next child dataset, and return its name, stats, and props and an updated
6986 + * cursor.
6987 + */
6988 +static int
6989 +zfs_ioc_dataset_list_next_nvl(const char *data, nvlist_t *innvl,
6990 + nvlist_t *outnvl)
6991 +{
6992 + objset_t *os;
6993 + int error;
6994 + uint64_t off;
6995 + char *p, *nextds;
6996 + char name[MAXNAMELEN];
6997 + size_t len;
6998 + size_t orig_len = strlen(data);
6999 +
7000 + if (innvl == NULL ||
7001 + nvlist_lookup_uint64(innvl, "offset", &off) != 0)
7002 + return (SET_ERROR(EINVAL));
7003 +
7004 + (void) strlcpy(name, data, sizeof (name));
7005 +top:
7006 + if (error = dmu_objset_hold(name, FTAG, &os)) {
7007 + if (error == ENOENT)
7008 + error = SET_ERROR(ESRCH);
7009 + return (error);
7010 + }
7011 +
7012 + p = strrchr(name, '/');
7013 + if (p == NULL || p[1] != '\0') {
7014 + if ((len = strlcat(name, "/", sizeof (name))) >= MAXNAMELEN) {
7015 + dmu_objset_rele(os, FTAG);
7016 + return (SET_ERROR(ESRCH));
7017 + }
7018 + } else {
7019 + len = orig_len;
7020 + }
7021 + p = name + len;
7022 +
7023 + do {
7024 + error = dmu_dir_list_next(os, sizeof (name) - len, p, NULL,
7025 + &off);
7026 + if (error == ENOENT)
7027 + error = ESRCH;
7028 + } while (error == 0 && dataset_name_hidden(name));
7029 + dmu_objset_rele(os, FTAG);
7030 +
7031 + /*
7032 + * If it's an internal dataset (ie. with a '$' in its name),
7033 + * don't try to get stats for it, otherwise we'll return ENOENT.
7034 + */
7035 + if (error == 0 && strchr(name, '$') == NULL) {
7036 + error = zfs_ioc_objset_stats_nvl(name, NULL, outnvl);
7037 + if (error == ENOENT) {
7038 + /* We lost a race with destroy, get the next one. */
7039 + name[orig_len] = '\0';
7040 + goto top;
7041 + }
7042 + len = strlen(name) + 1;
7043 + nextds = kmem_alloc(len, KM_SLEEP);
7044 + (void) strlcpy(nextds, name, len);
7045 + fnvlist_add_string(outnvl, "nextds", (const char *)nextds);
7046 + fnvlist_add_uint64(outnvl, "offset", off);
7047 + }
7048 +
7049 + return (error);
7050 +}
7051 +
7052 +/*
7053 + * Given a dataset name and a DMU cursor offset, find its next snapshot, and
7054 + * return its name, props, and stats and an updated cursor offset.
7055 + */
7056 +static int
7057 +zfs_ioc_snapshot_list_next_nvl(const char *data, nvlist_t *innvl,
7058 + nvlist_t *outnvl)
7059 +{
7060 + objset_t *os;
7061 + int error;
7062 + uint64_t off, obj;
7063 + char name[MAXNAMELEN], *nextsnap;
7064 + size_t len;
7065 +
7066 + if (innvl == NULL ||
7067 + nvlist_lookup_uint64(innvl, "offset", &off) != 0)
7068 + return (SET_ERROR(EINVAL));
7069 +
7070 + error = dmu_objset_hold(data, FTAG, &os);
7071 + if (error != 0) {
7072 + return (error == ENOENT ? ESRCH : error);
7073 + }
7074 +
7075 + /*
7076 + * A dataset name of maximum length cannot have any snapshots,
7077 + * so exit immediately.
7078 + */
7079 + (void) strlcpy(name, data, sizeof (name));
7080 + if ((len = strlcat(name, "@", sizeof (name))) >= MAXNAMELEN) {
7081 + dmu_objset_rele(os, FTAG);
7082 + return (SET_ERROR(ESRCH));
7083 + }
7084 +
7085 + /* Rest of name buffer is passed so snap ID can be appended. */
7086 + error = dmu_snapshot_list_next(os, sizeof (name) - len, name + len,
7087 + &obj, &off, NULL);
7088 +
7089 + if (error == 0) {
7090 + dsl_dataset_t *ds;
7091 + dsl_pool_t *dp = os->os_dsl_dataset->ds_dir->dd_pool;
7092 +
7093 + error = dsl_dataset_hold_obj(dp, obj, FTAG, &ds);
7094 + if (error == 0) {
7095 + objset_t *ossnap;
7096 +
7097 + error = dmu_objset_from_ds(ds, &ossnap);
7098 + if (error == 0)
7099 + error = objset_render(ossnap, outnvl);
7100 + dsl_dataset_rele(ds, FTAG);
7101 + }
7102 + } else if (error == ENOENT) {
7103 + error = ESRCH;
7104 + }
7105 +
7106 + dmu_objset_rele(os, FTAG);
7107 +
7108 + if (error == 0) {
7109 + len = strlen(name) + 1;
7110 + nextsnap = kmem_alloc(len, KM_SLEEP);
7111 + (void) strlcpy(nextsnap, name, len);
7112 + fnvlist_add_string(outnvl, "nextsnap", (const char *)nextsnap);
7113 + fnvlist_add_uint64(outnvl, "offset", off);
7114 + }
7115 + return (error);
7116 +}
7117 +
7118 +static int
7119 +zfs_ioc_pool_get_props_nvl(const char *poolname, nvlist_t *innvl,
7120 + nvlist_t *outnvl)
7121 +{
7122 + spa_t *spa;
7123 + int error;
7124 + nvlist_t *props = NULL;
7125 +
7126 + ASSERT3P(innvl, ==, NULL);
7127 + if ((error = spa_open(poolname, &spa, FTAG)) != 0) {
7128 + /*
7129 + * If the pool is faulted, there may be properties we can still
7130 + * get (such as altroot and cachefile), so attempt to get them
7131 + * anyway.
7132 + */
7133 + mutex_enter(&spa_namespace_lock);
7134 + if ((spa = spa_lookup(poolname)) != NULL)
7135 + error = spa_prop_get(spa, &props);
7136 + mutex_exit(&spa_namespace_lock);
7137 + } else {
7138 + error = spa_prop_get(spa, &props);
7139 + spa_close(spa, FTAG);
7140 + }
7141 +
7142 + if (props != NULL) {
7143 + fnvlist_merge(outnvl, props);
7144 + nvlist_free(props);
7145 + } else {
7146 + ASSERT3S(error, !=, 0);
7147 + }
7148 +
7149 + return (error);
7150 +}
7151 +
7152 +/* ARGSUSED */
7153 +static int
7154 +zfs_ioc_check_krrp(const char *dataset, nvlist_t *innvl, nvlist_t *outnvl)
7155 +{
7156 + spa_t *spa;
7157 + int err;
7158 +
7159 + /*
7160 + * Here we use different way to open spa for the given pool,
7161 + * because the pool maybe faulted
7162 + */
7163 +
7164 + mutex_enter(&spa_namespace_lock);
7165 + if ((spa = spa_lookup(dataset)) == NULL) {
7166 + mutex_exit(&spa_namespace_lock);
7167 + /* From KRRP side everything nice */
7168 + return (0);
7169 + }
7170 +
7171 + spa_open_ref(spa, FTAG);
7172 + mutex_exit(&spa_namespace_lock);
7173 +
7174 + err = autosnap_check_for_destroy(spa_get_autosnap(spa), dataset);
7175 + if (err == 0)
7176 + err = ENOTSUP;
7177 +
7178 + mutex_enter(&spa_namespace_lock);
7179 + spa_close(spa, FTAG);
7180 + mutex_exit(&spa_namespace_lock);
7181 +
7182 + return (err != 0 ? SET_ERROR(err) : 0);
7183 +}
7184 +
5768 7185 static void
5769 7186 zfs_ioctl_init(void)
5770 7187 {
7188 + zfs_ioctl_register("bulk_list", ZFS_IOC_BULK_LIST,
7189 + zfs_ioc_list_from_cursor, zfs_secpolicy_read,
7190 + DATASET_NAME, POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
7191 +
5771 7192 zfs_ioctl_register("snapshot", ZFS_IOC_SNAPSHOT,
5772 7193 zfs_ioc_snapshot, zfs_secpolicy_snapshot, POOL_NAME,
5773 7194 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5774 7195
5775 7196 zfs_ioctl_register("log_history", ZFS_IOC_LOG_HISTORY,
5776 7197 zfs_ioc_log_history, zfs_secpolicy_log_history, NO_NAME,
5777 7198 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_FALSE);
5778 7199
5779 7200 zfs_ioctl_register("space_snaps", ZFS_IOC_SPACE_SNAPS,
5780 7201 zfs_ioc_space_snaps, zfs_secpolicy_read, DATASET_NAME,
5781 7202 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5782 7203
5783 7204 zfs_ioctl_register("send", ZFS_IOC_SEND_NEW,
5784 7205 zfs_ioc_send_new, zfs_secpolicy_send_new, DATASET_NAME,
5785 7206 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5786 7207
5787 7208 zfs_ioctl_register("send_space", ZFS_IOC_SEND_SPACE,
5788 7209 zfs_ioc_send_space, zfs_secpolicy_read, DATASET_NAME,
|
↓ open down ↓ |
8 lines elided |
↑ open up ↑ |
5789 7210 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5790 7211
5791 7212 zfs_ioctl_register("create", ZFS_IOC_CREATE,
5792 7213 zfs_ioc_create, zfs_secpolicy_create_clone, DATASET_NAME,
5793 7214 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5794 7215
5795 7216 zfs_ioctl_register("clone", ZFS_IOC_CLONE,
5796 7217 zfs_ioc_clone, zfs_secpolicy_create_clone, DATASET_NAME,
5797 7218 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5798 7219
5799 - zfs_ioctl_register("remap", ZFS_IOC_REMAP,
5800 - zfs_ioc_remap, zfs_secpolicy_remap, DATASET_NAME,
5801 - POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
5802 -
5803 7220 zfs_ioctl_register("destroy_snaps", ZFS_IOC_DESTROY_SNAPS,
5804 7221 zfs_ioc_destroy_snaps, zfs_secpolicy_destroy_snaps, POOL_NAME,
5805 7222 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5806 7223
7224 + zfs_ioctl_register("check_krrp", ZFS_IOC_CHECK_KRRP,
7225 + zfs_ioc_check_krrp, zfs_secpolicy_read, DATASET_NAME,
7226 + POOL_CHECK_NONE, B_FALSE, B_FALSE);
7227 +
7228 + zfs_ioctl_register("pool_stats_nvl", ZFS_IOC_POOL_STATS_NVL,
7229 + zfs_ioc_pool_stats_nvl, zfs_secpolicy_read, POOL_NAME,
7230 + POOL_CHECK_NONE, B_FALSE, B_FALSE);
7231 +
7232 + zfs_ioctl_register("pool_configs_nvl", ZFS_IOC_POOL_CONFIGS_NVL,
7233 + zfs_ioc_pool_configs_nvl, zfs_secpolicy_none, NO_NAME,
7234 + POOL_CHECK_NONE, B_FALSE, B_FALSE);
7235 +
7236 + zfs_ioctl_register("pool_get_props_nvl", ZFS_IOC_POOL_GET_PROPS_NVL,
7237 + zfs_ioc_pool_get_props_nvl, zfs_secpolicy_read, POOL_NAME,
7238 + POOL_CHECK_NONE, B_FALSE, B_FALSE);
7239 +
7240 + zfs_ioctl_register("objset_stats_nvl", ZFS_IOC_OBJSET_STATS_NVL,
7241 + zfs_ioc_objset_stats_nvl, zfs_secpolicy_read, DATASET_NAME,
7242 + POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
7243 +
7244 + zfs_ioctl_register("dataset_list_next_nvl",
7245 + ZFS_IOC_DATASET_LIST_NEXT_NVL, zfs_ioc_dataset_list_next_nvl,
7246 + zfs_secpolicy_read, DATASET_NAME, POOL_CHECK_SUSPENDED, B_FALSE,
7247 + B_FALSE);
7248 +
7249 + zfs_ioctl_register("snapshot_list_next_nvl",
7250 + ZFS_IOC_SNAPSHOT_LIST_NEXT_NVL, zfs_ioc_snapshot_list_next_nvl,
7251 + zfs_secpolicy_read, DATASET_NAME, POOL_CHECK_SUSPENDED, B_FALSE,
7252 + B_FALSE);
7253 +
5807 7254 zfs_ioctl_register("hold", ZFS_IOC_HOLD,
5808 7255 zfs_ioc_hold, zfs_secpolicy_hold, POOL_NAME,
5809 7256 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5810 7257 zfs_ioctl_register("release", ZFS_IOC_RELEASE,
5811 7258 zfs_ioc_release, zfs_secpolicy_release, POOL_NAME,
5812 7259 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5813 7260
5814 7261 zfs_ioctl_register("get_holds", ZFS_IOC_GET_HOLDS,
5815 7262 zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME,
5816 7263 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5817 7264
5818 7265 zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK,
5819 7266 zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME,
5820 7267 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
5821 7268
5822 7269 zfs_ioctl_register("bookmark", ZFS_IOC_BOOKMARK,
5823 7270 zfs_ioc_bookmark, zfs_secpolicy_bookmark, POOL_NAME,
5824 7271 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5825 7272
5826 7273 zfs_ioctl_register("get_bookmarks", ZFS_IOC_GET_BOOKMARKS,
5827 7274 zfs_ioc_get_bookmarks, zfs_secpolicy_read, DATASET_NAME,
5828 7275 POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
5829 7276
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
5830 7277 zfs_ioctl_register("destroy_bookmarks", ZFS_IOC_DESTROY_BOOKMARKS,
5831 7278 zfs_ioc_destroy_bookmarks, zfs_secpolicy_destroy_bookmarks,
5832 7279 POOL_NAME,
5833 7280 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
5834 7281
5835 7282 zfs_ioctl_register("channel_program", ZFS_IOC_CHANNEL_PROGRAM,
5836 7283 zfs_ioc_channel_program, zfs_secpolicy_config,
5837 7284 POOL_NAME, POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE,
5838 7285 B_TRUE);
5839 7286
7287 + zfs_ioctl_register("set_props_mds", ZFS_IOC_SET_PROPS_MDS,
7288 + zfs_ioc_set_prop_mds, zfs_secpolicy_config,
7289 + POOL_NAME,
7290 + POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_TRUE, B_TRUE);
7291 +
5840 7292 /* IOCTLS that use the legacy function signature */
5841 7293
5842 7294 zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
5843 7295 zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_READONLY);
5844 7296
5845 7297 zfs_ioctl_register_pool(ZFS_IOC_POOL_CREATE, zfs_ioc_pool_create,
5846 7298 zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5847 7299 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SCAN,
5848 7300 zfs_ioc_pool_scan);
7301 + zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_TRIM,
7302 + zfs_ioc_pool_trim);
5849 7303 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_UPGRADE,
5850 7304 zfs_ioc_pool_upgrade);
5851 7305 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ADD,
5852 7306 zfs_ioc_vdev_add);
5853 7307 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_REMOVE,
5854 7308 zfs_ioc_vdev_remove);
5855 7309 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SET_STATE,
5856 7310 zfs_ioc_vdev_set_state);
5857 7311 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_ATTACH,
5858 7312 zfs_ioc_vdev_attach);
5859 7313 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_DETACH,
5860 7314 zfs_ioc_vdev_detach);
7315 + zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETL2ADDDT,
7316 + zfs_ioc_vdev_setl2adddt);
5861 7317 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETPATH,
5862 7318 zfs_ioc_vdev_setpath);
5863 7319 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SETFRU,
5864 7320 zfs_ioc_vdev_setfru);
5865 7321 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_SET_PROPS,
5866 7322 zfs_ioc_pool_set_props);
5867 7323 zfs_ioctl_register_pool_modify(ZFS_IOC_VDEV_SPLIT,
5868 7324 zfs_ioc_vdev_split);
5869 7325 zfs_ioctl_register_pool_modify(ZFS_IOC_POOL_REGUID,
5870 7326 zfs_ioc_pool_reguid);
5871 7327
5872 7328 zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_CONFIGS,
5873 7329 zfs_ioc_pool_configs, zfs_secpolicy_none);
5874 7330 zfs_ioctl_register_pool_meta(ZFS_IOC_POOL_TRYIMPORT,
5875 7331 zfs_ioc_pool_tryimport, zfs_secpolicy_config);
5876 7332 zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_FAULT,
5877 7333 zfs_ioc_inject_fault, zfs_secpolicy_inject);
5878 7334 zfs_ioctl_register_pool_meta(ZFS_IOC_CLEAR_FAULT,
5879 7335 zfs_ioc_clear_fault, zfs_secpolicy_inject);
5880 7336 zfs_ioctl_register_pool_meta(ZFS_IOC_INJECT_LIST_NEXT,
5881 7337 zfs_ioc_inject_list_next, zfs_secpolicy_inject);
5882 7338
5883 7339 /*
5884 7340 * pool destroy, and export don't log the history as part of
5885 7341 * zfsdev_ioctl, but rather zfs_ioc_pool_export
5886 7342 * does the logging of those commands.
5887 7343 */
5888 7344 zfs_ioctl_register_pool(ZFS_IOC_POOL_DESTROY, zfs_ioc_pool_destroy,
5889 7345 zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5890 7346 zfs_ioctl_register_pool(ZFS_IOC_POOL_EXPORT, zfs_ioc_pool_export,
5891 7347 zfs_secpolicy_config, B_FALSE, POOL_CHECK_NONE);
5892 7348
5893 7349 zfs_ioctl_register_pool(ZFS_IOC_POOL_STATS, zfs_ioc_pool_stats,
5894 7350 zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5895 7351 zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_PROPS, zfs_ioc_pool_get_props,
5896 7352 zfs_secpolicy_read, B_FALSE, POOL_CHECK_NONE);
5897 7353
5898 7354 zfs_ioctl_register_pool(ZFS_IOC_ERROR_LOG, zfs_ioc_error_log,
5899 7355 zfs_secpolicy_inject, B_FALSE, POOL_CHECK_SUSPENDED);
5900 7356 zfs_ioctl_register_pool(ZFS_IOC_DSOBJ_TO_DSNAME,
|
↓ open down ↓ |
30 lines elided |
↑ open up ↑ |
5901 7357 zfs_ioc_dsobj_to_dsname,
5902 7358 zfs_secpolicy_diff, B_FALSE, POOL_CHECK_SUSPENDED);
5903 7359 zfs_ioctl_register_pool(ZFS_IOC_POOL_GET_HISTORY,
5904 7360 zfs_ioc_pool_get_history,
5905 7361 zfs_secpolicy_config, B_FALSE, POOL_CHECK_SUSPENDED);
5906 7362
5907 7363 zfs_ioctl_register_pool(ZFS_IOC_POOL_IMPORT, zfs_ioc_pool_import,
5908 7364 zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5909 7365
5910 7366 zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
5911 - zfs_secpolicy_config, B_TRUE, POOL_CHECK_READONLY);
7367 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
5912 7368 zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
5913 7369 zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
5914 -
7370 + zfs_ioctl_register_pool(ZFS_IOC_VDEV_SET_PROPS, zfs_ioc_vdev_set_props,
7371 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7372 + zfs_ioctl_register_pool(ZFS_IOC_VDEV_GET_PROPS, zfs_ioc_vdev_get_props,
7373 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7374 + zfs_ioctl_register_pool(ZFS_IOC_COS_ALLOC, zfs_ioc_cos_alloc,
7375 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7376 + zfs_ioctl_register_pool(ZFS_IOC_COS_FREE, zfs_ioc_cos_free,
7377 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7378 + zfs_ioctl_register_pool(ZFS_IOC_COS_LIST, zfs_ioc_cos_list,
7379 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7380 + zfs_ioctl_register_pool(ZFS_IOC_COS_SET_PROPS, zfs_ioc_cos_set_props,
7381 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
7382 + zfs_ioctl_register_pool(ZFS_IOC_COS_GET_PROPS, zfs_ioc_cos_get_props,
7383 + zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
5915 7384 zfs_ioctl_register_dataset_read(ZFS_IOC_SPACE_WRITTEN,
5916 7385 zfs_ioc_space_written);
5917 7386 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_RECVD_PROPS,
5918 7387 zfs_ioc_objset_recvd_props);
5919 7388 zfs_ioctl_register_dataset_read(ZFS_IOC_NEXT_OBJ,
5920 7389 zfs_ioc_next_obj);
5921 7390 zfs_ioctl_register_dataset_read(ZFS_IOC_GET_FSACL,
5922 7391 zfs_ioc_get_fsacl);
5923 7392 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_STATS,
5924 7393 zfs_ioc_objset_stats);
5925 7394 zfs_ioctl_register_dataset_read(ZFS_IOC_OBJSET_ZPLPROPS,
5926 7395 zfs_ioc_objset_zplprops);
5927 7396 zfs_ioctl_register_dataset_read(ZFS_IOC_DATASET_LIST_NEXT,
5928 7397 zfs_ioc_dataset_list_next);
5929 7398 zfs_ioctl_register_dataset_read(ZFS_IOC_SNAPSHOT_LIST_NEXT,
5930 7399 zfs_ioc_snapshot_list_next);
5931 7400 zfs_ioctl_register_dataset_read(ZFS_IOC_SEND_PROGRESS,
5932 7401 zfs_ioc_send_progress);
5933 7402
5934 7403 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_DIFF,
5935 7404 zfs_ioc_diff, zfs_secpolicy_diff);
5936 7405 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_STATS,
5937 7406 zfs_ioc_obj_to_stats, zfs_secpolicy_diff);
5938 7407 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_OBJ_TO_PATH,
5939 7408 zfs_ioc_obj_to_path, zfs_secpolicy_diff);
5940 7409 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_ONE,
5941 7410 zfs_ioc_userspace_one, zfs_secpolicy_userspace_one);
5942 7411 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_USERSPACE_MANY,
5943 7412 zfs_ioc_userspace_many, zfs_secpolicy_userspace_many);
5944 7413 zfs_ioctl_register_dataset_read_secpolicy(ZFS_IOC_SEND,
5945 7414 zfs_ioc_send, zfs_secpolicy_send);
5946 7415
5947 7416 zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_PROP, zfs_ioc_set_prop,
5948 7417 zfs_secpolicy_none);
5949 7418 zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
5950 7419 zfs_secpolicy_destroy);
5951 7420 zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
5952 7421 zfs_secpolicy_rename);
5953 7422 zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
5954 7423 zfs_secpolicy_recv);
5955 7424 zfs_ioctl_register_dataset_modify(ZFS_IOC_PROMOTE, zfs_ioc_promote,
5956 7425 zfs_secpolicy_promote);
5957 7426 zfs_ioctl_register_dataset_modify(ZFS_IOC_INHERIT_PROP,
5958 7427 zfs_ioc_inherit_prop, zfs_secpolicy_inherit_prop);
5959 7428 zfs_ioctl_register_dataset_modify(ZFS_IOC_SET_FSACL, zfs_ioc_set_fsacl,
5960 7429 zfs_secpolicy_set_fsacl);
5961 7430
5962 7431 zfs_ioctl_register_dataset_nolog(ZFS_IOC_SHARE, zfs_ioc_share,
5963 7432 zfs_secpolicy_share, POOL_CHECK_NONE);
5964 7433 zfs_ioctl_register_dataset_nolog(ZFS_IOC_SMB_ACL, zfs_ioc_smb_acl,
5965 7434 zfs_secpolicy_smb_acl, POOL_CHECK_NONE);
5966 7435 zfs_ioctl_register_dataset_nolog(ZFS_IOC_USERSPACE_UPGRADE,
5967 7436 zfs_ioc_userspace_upgrade, zfs_secpolicy_userspace_upgrade,
5968 7437 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5969 7438 zfs_ioctl_register_dataset_nolog(ZFS_IOC_TMP_SNAPSHOT,
5970 7439 zfs_ioc_tmp_snapshot, zfs_secpolicy_tmp_snapshot,
5971 7440 POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
5972 7441 }
5973 7442
5974 7443 int
5975 7444 pool_status_check(const char *name, zfs_ioc_namecheck_t type,
5976 7445 zfs_ioc_poolcheck_t check)
5977 7446 {
5978 7447 spa_t *spa;
5979 7448 int error;
5980 7449
5981 7450 ASSERT(type == POOL_NAME || type == DATASET_NAME);
5982 7451
5983 7452 if (check & POOL_CHECK_NONE)
5984 7453 return (0);
5985 7454
5986 7455 error = spa_open(name, &spa, FTAG);
5987 7456 if (error == 0) {
5988 7457 if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
5989 7458 error = SET_ERROR(EAGAIN);
5990 7459 else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
5991 7460 error = SET_ERROR(EROFS);
5992 7461 spa_close(spa, FTAG);
5993 7462 }
5994 7463 return (error);
5995 7464 }
5996 7465
5997 7466 /*
5998 7467 * Find a free minor number.
5999 7468 */
6000 7469 minor_t
6001 7470 zfsdev_minor_alloc(void)
6002 7471 {
6003 7472 static minor_t last_minor;
6004 7473 minor_t m;
6005 7474
6006 7475 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
6007 7476
6008 7477 for (m = last_minor + 1; m != last_minor; m++) {
6009 7478 if (m > ZFSDEV_MAX_MINOR)
6010 7479 m = 1;
6011 7480 if (ddi_get_soft_state(zfsdev_state, m) == NULL) {
6012 7481 last_minor = m;
6013 7482 return (m);
6014 7483 }
6015 7484 }
6016 7485
6017 7486 return (0);
6018 7487 }
6019 7488
6020 7489 static int
6021 7490 zfs_ctldev_init(dev_t *devp)
6022 7491 {
6023 7492 minor_t minor;
6024 7493 zfs_soft_state_t *zs;
6025 7494
6026 7495 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
6027 7496 ASSERT(getminor(*devp) == 0);
6028 7497
6029 7498 minor = zfsdev_minor_alloc();
6030 7499 if (minor == 0)
6031 7500 return (SET_ERROR(ENXIO));
6032 7501
6033 7502 if (ddi_soft_state_zalloc(zfsdev_state, minor) != DDI_SUCCESS)
6034 7503 return (SET_ERROR(EAGAIN));
6035 7504
6036 7505 *devp = makedevice(getemajor(*devp), minor);
6037 7506
6038 7507 zs = ddi_get_soft_state(zfsdev_state, minor);
6039 7508 zs->zss_type = ZSST_CTLDEV;
6040 7509 zfs_onexit_init((zfs_onexit_t **)&zs->zss_data);
6041 7510
6042 7511 return (0);
6043 7512 }
6044 7513
6045 7514 static void
6046 7515 zfs_ctldev_destroy(zfs_onexit_t *zo, minor_t minor)
6047 7516 {
6048 7517 ASSERT(MUTEX_HELD(&zfsdev_state_lock));
6049 7518
6050 7519 zfs_onexit_destroy(zo);
6051 7520 ddi_soft_state_free(zfsdev_state, minor);
6052 7521 }
6053 7522
6054 7523 void *
6055 7524 zfsdev_get_soft_state(minor_t minor, enum zfs_soft_state_type which)
6056 7525 {
6057 7526 zfs_soft_state_t *zp;
6058 7527
6059 7528 zp = ddi_get_soft_state(zfsdev_state, minor);
6060 7529 if (zp == NULL || zp->zss_type != which)
6061 7530 return (NULL);
6062 7531
6063 7532 return (zp->zss_data);
6064 7533 }
6065 7534
6066 7535 static int
6067 7536 zfsdev_open(dev_t *devp, int flag, int otyp, cred_t *cr)
6068 7537 {
6069 7538 int error = 0;
6070 7539
6071 7540 if (getminor(*devp) != 0)
6072 7541 return (zvol_open(devp, flag, otyp, cr));
6073 7542
6074 7543 /* This is the control device. Allocate a new minor if requested. */
6075 7544 if (flag & FEXCL) {
6076 7545 mutex_enter(&zfsdev_state_lock);
6077 7546 error = zfs_ctldev_init(devp);
6078 7547 mutex_exit(&zfsdev_state_lock);
6079 7548 }
6080 7549
6081 7550 return (error);
6082 7551 }
6083 7552
6084 7553 static int
6085 7554 zfsdev_close(dev_t dev, int flag, int otyp, cred_t *cr)
6086 7555 {
6087 7556 zfs_onexit_t *zo;
6088 7557 minor_t minor = getminor(dev);
6089 7558
6090 7559 if (minor == 0)
6091 7560 return (0);
6092 7561
6093 7562 mutex_enter(&zfsdev_state_lock);
6094 7563 zo = zfsdev_get_soft_state(minor, ZSST_CTLDEV);
6095 7564 if (zo == NULL) {
6096 7565 mutex_exit(&zfsdev_state_lock);
6097 7566 return (zvol_close(dev, flag, otyp, cr));
6098 7567 }
6099 7568 zfs_ctldev_destroy(zo, minor);
6100 7569 mutex_exit(&zfsdev_state_lock);
6101 7570
6102 7571 return (0);
6103 7572 }
6104 7573
6105 7574 static int
6106 7575 zfsdev_ioctl(dev_t dev, int cmd, intptr_t arg, int flag, cred_t *cr, int *rvalp)
6107 7576 {
6108 7577 zfs_cmd_t *zc;
6109 7578 uint_t vecnum;
6110 7579 int error, rc, len;
6111 7580 minor_t minor = getminor(dev);
6112 7581 const zfs_ioc_vec_t *vec;
6113 7582 char *saved_poolname = NULL;
6114 7583 nvlist_t *innvl = NULL;
6115 7584
6116 7585 if (minor != 0 &&
6117 7586 zfsdev_get_soft_state(minor, ZSST_CTLDEV) == NULL)
6118 7587 return (zvol_ioctl(dev, cmd, arg, flag, cr, rvalp));
6119 7588
6120 7589 vecnum = cmd - ZFS_IOC_FIRST;
6121 7590 ASSERT3U(getmajor(dev), ==, ddi_driver_major(zfs_dip));
6122 7591
6123 7592 if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
6124 7593 return (SET_ERROR(EINVAL));
6125 7594 vec = &zfs_ioc_vec[vecnum];
6126 7595
6127 7596 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
6128 7597
6129 7598 error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
6130 7599 if (error != 0) {
6131 7600 error = SET_ERROR(EFAULT);
6132 7601 goto out;
6133 7602 }
6134 7603
6135 7604 zc->zc_iflags = flag & FKIOCTL;
6136 7605 if (zc->zc_nvlist_src_size != 0) {
6137 7606 error = get_nvlist(zc->zc_nvlist_src, zc->zc_nvlist_src_size,
6138 7607 zc->zc_iflags, &innvl);
6139 7608 if (error != 0)
6140 7609 goto out;
6141 7610 }
6142 7611
6143 7612 /*
6144 7613 * Ensure that all pool/dataset names are valid before we pass down to
6145 7614 * the lower layers.
6146 7615 */
6147 7616 zc->zc_name[sizeof (zc->zc_name) - 1] = '\0';
6148 7617 switch (vec->zvec_namecheck) {
6149 7618 case POOL_NAME:
6150 7619 if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
6151 7620 error = SET_ERROR(EINVAL);
6152 7621 else
6153 7622 error = pool_status_check(zc->zc_name,
6154 7623 vec->zvec_namecheck, vec->zvec_pool_check);
6155 7624 break;
6156 7625
6157 7626 case DATASET_NAME:
6158 7627 if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
6159 7628 error = SET_ERROR(EINVAL);
6160 7629 else
6161 7630 error = pool_status_check(zc->zc_name,
6162 7631 vec->zvec_namecheck, vec->zvec_pool_check);
6163 7632 break;
6164 7633
6165 7634 case NO_NAME:
6166 7635 break;
6167 7636 }
6168 7637
6169 7638
6170 7639 if (error == 0)
6171 7640 error = vec->zvec_secpolicy(zc, innvl, cr);
6172 7641
6173 7642 if (error != 0)
6174 7643 goto out;
6175 7644
6176 7645 /* legacy ioctls can modify zc_name */
6177 7646 len = strcspn(zc->zc_name, "/@#") + 1;
6178 7647 saved_poolname = kmem_alloc(len, KM_SLEEP);
6179 7648 (void) strlcpy(saved_poolname, zc->zc_name, len);
6180 7649
6181 7650 if (vec->zvec_func != NULL) {
6182 7651 nvlist_t *outnvl;
6183 7652 int puterror = 0;
6184 7653 spa_t *spa;
6185 7654 nvlist_t *lognv = NULL;
6186 7655
6187 7656 ASSERT(vec->zvec_legacy_func == NULL);
6188 7657
6189 7658 /*
6190 7659 * Add the innvl to the lognv before calling the func,
6191 7660 * in case the func changes the innvl.
6192 7661 */
6193 7662 if (vec->zvec_allow_log) {
6194 7663 lognv = fnvlist_alloc();
6195 7664 fnvlist_add_string(lognv, ZPOOL_HIST_IOCTL,
6196 7665 vec->zvec_name);
6197 7666 if (!nvlist_empty(innvl)) {
6198 7667 fnvlist_add_nvlist(lognv, ZPOOL_HIST_INPUT_NVL,
6199 7668 innvl);
6200 7669 }
6201 7670 }
6202 7671
6203 7672 outnvl = fnvlist_alloc();
6204 7673 error = vec->zvec_func(zc->zc_name, innvl, outnvl);
6205 7674
6206 7675 /*
6207 7676 * Some commands can partially execute, modfiy state, and still
6208 7677 * return an error. In these cases, attempt to record what
6209 7678 * was modified.
6210 7679 */
6211 7680 if ((error == 0 ||
6212 7681 (cmd == ZFS_IOC_CHANNEL_PROGRAM && error != EINVAL)) &&
6213 7682 vec->zvec_allow_log &&
6214 7683 spa_open(zc->zc_name, &spa, FTAG) == 0) {
6215 7684 if (!nvlist_empty(outnvl)) {
6216 7685 fnvlist_add_nvlist(lognv, ZPOOL_HIST_OUTPUT_NVL,
6217 7686 outnvl);
6218 7687 }
6219 7688 if (error != 0) {
6220 7689 fnvlist_add_int64(lognv, ZPOOL_HIST_ERRNO,
6221 7690 error);
6222 7691 }
6223 7692 (void) spa_history_log_nvl(spa, lognv);
6224 7693 spa_close(spa, FTAG);
6225 7694 }
6226 7695 fnvlist_free(lognv);
6227 7696
6228 7697 if (!nvlist_empty(outnvl) || zc->zc_nvlist_dst_size != 0) {
6229 7698 int smusherror = 0;
6230 7699 if (vec->zvec_smush_outnvlist) {
6231 7700 smusherror = nvlist_smush(outnvl,
6232 7701 zc->zc_nvlist_dst_size);
6233 7702 }
6234 7703 if (smusherror == 0)
6235 7704 puterror = put_nvlist(zc, outnvl);
6236 7705 }
6237 7706
6238 7707 if (puterror != 0)
6239 7708 error = puterror;
6240 7709
6241 7710 nvlist_free(outnvl);
6242 7711 } else {
6243 7712 error = vec->zvec_legacy_func(zc);
6244 7713 }
6245 7714
6246 7715 out:
6247 7716 nvlist_free(innvl);
6248 7717 rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
6249 7718 if (error == 0 && rc != 0)
6250 7719 error = SET_ERROR(EFAULT);
6251 7720 if (error == 0 && vec->zvec_allow_log) {
6252 7721 char *s = tsd_get(zfs_allow_log_key);
6253 7722 if (s != NULL)
6254 7723 strfree(s);
6255 7724 (void) tsd_set(zfs_allow_log_key, saved_poolname);
6256 7725 } else {
6257 7726 if (saved_poolname != NULL)
6258 7727 strfree(saved_poolname);
6259 7728 }
6260 7729
6261 7730 kmem_free(zc, sizeof (zfs_cmd_t));
6262 7731 return (error);
6263 7732 }
6264 7733
6265 7734 static int
6266 7735 zfs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
6267 7736 {
6268 7737 if (cmd != DDI_ATTACH)
6269 7738 return (DDI_FAILURE);
6270 7739
6271 7740 if (ddi_create_minor_node(dip, "zfs", S_IFCHR, 0,
6272 7741 DDI_PSEUDO, 0) == DDI_FAILURE)
6273 7742 return (DDI_FAILURE);
6274 7743
6275 7744 zfs_dip = dip;
6276 7745
6277 7746 ddi_report_dev(dip);
6278 7747
6279 7748 return (DDI_SUCCESS);
6280 7749 }
6281 7750
6282 7751 static int
6283 7752 zfs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
6284 7753 {
6285 7754 if (spa_busy() || zfs_busy() || zvol_busy())
6286 7755 return (DDI_FAILURE);
6287 7756
6288 7757 if (cmd != DDI_DETACH)
6289 7758 return (DDI_FAILURE);
6290 7759
6291 7760 zfs_dip = NULL;
6292 7761
6293 7762 ddi_prop_remove_all(dip);
6294 7763 ddi_remove_minor_node(dip, NULL);
6295 7764
6296 7765 return (DDI_SUCCESS);
6297 7766 }
6298 7767
6299 7768 /*ARGSUSED*/
6300 7769 static int
6301 7770 zfs_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
6302 7771 {
6303 7772 switch (infocmd) {
6304 7773 case DDI_INFO_DEVT2DEVINFO:
6305 7774 *result = zfs_dip;
6306 7775 return (DDI_SUCCESS);
6307 7776
6308 7777 case DDI_INFO_DEVT2INSTANCE:
6309 7778 *result = (void *)0;
6310 7779 return (DDI_SUCCESS);
6311 7780 }
6312 7781
6313 7782 return (DDI_FAILURE);
6314 7783 }
6315 7784
6316 7785 /*
6317 7786 * OK, so this is a little weird.
6318 7787 *
6319 7788 * /dev/zfs is the control node, i.e. minor 0.
6320 7789 * /dev/zvol/[r]dsk/pool/dataset are the zvols, minor > 0.
6321 7790 *
6322 7791 * /dev/zfs has basically nothing to do except serve up ioctls,
6323 7792 * so most of the standard driver entry points are in zvol.c.
6324 7793 */
6325 7794 static struct cb_ops zfs_cb_ops = {
6326 7795 zfsdev_open, /* open */
6327 7796 zfsdev_close, /* close */
6328 7797 zvol_strategy, /* strategy */
6329 7798 nodev, /* print */
6330 7799 zvol_dump, /* dump */
6331 7800 zvol_read, /* read */
6332 7801 zvol_write, /* write */
6333 7802 zfsdev_ioctl, /* ioctl */
6334 7803 nodev, /* devmap */
6335 7804 nodev, /* mmap */
6336 7805 nodev, /* segmap */
6337 7806 nochpoll, /* poll */
6338 7807 ddi_prop_op, /* prop_op */
6339 7808 NULL, /* streamtab */
6340 7809 D_NEW | D_MP | D_64BIT, /* Driver compatibility flag */
6341 7810 CB_REV, /* version */
6342 7811 nodev, /* async read */
6343 7812 nodev, /* async write */
6344 7813 };
6345 7814
6346 7815 static struct dev_ops zfs_dev_ops = {
6347 7816 DEVO_REV, /* version */
6348 7817 0, /* refcnt */
6349 7818 zfs_info, /* info */
6350 7819 nulldev, /* identify */
6351 7820 nulldev, /* probe */
6352 7821 zfs_attach, /* attach */
6353 7822 zfs_detach, /* detach */
6354 7823 nodev, /* reset */
6355 7824 &zfs_cb_ops, /* driver operations */
6356 7825 NULL, /* no bus operations */
6357 7826 NULL, /* power */
6358 7827 ddi_quiesce_not_needed, /* quiesce */
6359 7828 };
6360 7829
6361 7830 static struct modldrv zfs_modldrv = {
6362 7831 &mod_driverops,
6363 7832 "ZFS storage pool",
6364 7833 &zfs_dev_ops
6365 7834 };
6366 7835
6367 7836 static struct modlinkage modlinkage = {
6368 7837 MODREV_1,
6369 7838 (void *)&zfs_modlfs,
6370 7839 (void *)&zfs_modldrv,
6371 7840 NULL
6372 7841 };
6373 7842
6374 7843 static void
6375 7844 zfs_allow_log_destroy(void *arg)
6376 7845 {
6377 7846 char *poolname = arg;
6378 7847 strfree(poolname);
6379 7848 }
6380 7849
6381 7850 int
6382 7851 _init(void)
6383 7852 {
6384 7853 int error;
6385 7854
6386 7855 spa_init(FREAD | FWRITE);
6387 7856 zfs_init();
6388 7857 zvol_init();
6389 7858 zfs_ioctl_init();
6390 7859
6391 7860 if ((error = mod_install(&modlinkage)) != 0) {
6392 7861 zvol_fini();
6393 7862 zfs_fini();
6394 7863 spa_fini();
6395 7864 return (error);
|
↓ open down ↓ |
471 lines elided |
↑ open up ↑ |
6396 7865 }
6397 7866
6398 7867 tsd_create(&zfs_fsyncer_key, NULL);
6399 7868 tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
6400 7869 tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
6401 7870
6402 7871 error = ldi_ident_from_mod(&modlinkage, &zfs_li);
6403 7872 ASSERT(error == 0);
6404 7873 mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
6405 7874
7875 + if (sysevent_evc_bind(ZFS_EVENT_CHANNEL, &zfs_channel,
7876 + EVCH_HOLD_PEND | EVCH_CREAT) != 0)
7877 + cmn_err(CE_NOTE, "Failed to bind to zfs event channel");
7878 +
6406 7879 return (0);
6407 7880 }
6408 7881
6409 7882 int
6410 7883 _fini(void)
6411 7884 {
6412 7885 int error;
6413 7886
6414 7887 if (spa_busy() || zfs_busy() || zvol_busy() || zio_injection_enabled)
6415 7888 return (SET_ERROR(EBUSY));
6416 7889
6417 7890 if ((error = mod_remove(&modlinkage)) != 0)
6418 7891 return (error);
6419 7892
6420 7893 zvol_fini();
6421 7894 zfs_fini();
6422 7895 spa_fini();
6423 7896 if (zfs_nfsshare_inited)
6424 7897 (void) ddi_modclose(nfs_mod);
|
↓ open down ↓ |
9 lines elided |
↑ open up ↑ |
6425 7898 if (zfs_smbshare_inited)
6426 7899 (void) ddi_modclose(smbsrv_mod);
6427 7900 if (zfs_nfsshare_inited || zfs_smbshare_inited)
6428 7901 (void) ddi_modclose(sharefs_mod);
6429 7902
6430 7903 tsd_destroy(&zfs_fsyncer_key);
6431 7904 ldi_ident_release(zfs_li);
6432 7905 zfs_li = NULL;
6433 7906 mutex_destroy(&zfs_share_lock);
6434 7907
7908 + if (zfs_channel)
7909 + (void) sysevent_evc_unbind(zfs_channel);
7910 +
6435 7911 return (error);
6436 7912 }
6437 7913
6438 7914 int
6439 7915 _info(struct modinfo *modinfop)
6440 7916 {
6441 7917 return (mod_info(&modlinkage, modinfop));
6442 7918 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX