author | Rich Morris <Richard.Morris@Sun.COM> |
Wed, 10 Sep 2008 10:59:12 -0400 | |
changeset 7538 | 18c2451107fd |
parent 7366 | 33de5956afbb |
child 9396 | f41cf682d0d3 |
permissions | -rw-r--r-- |
789 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
2082 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
789 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
3126 | 21 |
|
789 | 22 |
/* |
6027
68b03551f113
6609196 'zfs destroy -r' can needlessly iterate over all filesystems in pool
rm160521
parents:
5610
diff
changeset
|
23 |
* Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
789 | 24 |
* Use is subject to license terms. |
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
25 |
* |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
26 |
* Portions Copyright 2007 Ramprakash Jelari |
789 | 27 |
*/ |
28 |
||
29 |
#include <libintl.h> |
|
30 |
#include <libuutil.h> |
|
31 |
#include <stddef.h> |
|
32 |
#include <stdlib.h> |
|
33 |
#include <string.h> |
|
34 |
#include <unistd.h> |
|
35 |
#include <zone.h> |
|
36 |
||
37 |
#include <libzfs.h> |
|
38 |
||
39 |
#include "libzfs_impl.h" |
|
40 |
||
41 |
/* |
|
42 |
* Structure to keep track of dataset state. Before changing the 'sharenfs' or |
|
43 |
* 'mountpoint' property, we record whether the filesystem was previously |
|
44 |
* mounted/shared. This prior state dictates whether we remount/reshare the |
|
45 |
* dataset after the property has been changed. |
|
46 |
* |
|
47 |
* The interface consists of the following sequence of functions: |
|
48 |
* |
|
49 |
* changelist_gather() |
|
50 |
* changelist_prefix() |
|
51 |
* < change property > |
|
52 |
* changelist_postfix() |
|
53 |
* changelist_free() |
|
54 |
* |
|
55 |
* Other interfaces: |
|
56 |
* |
|
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
57 |
* changelist_remove() - remove a node from a gathered list |
789 | 58 |
* changelist_rename() - renames all datasets appropriately when doing a rename |
59 |
* changelist_unshare() - unshares all the nodes in a given changelist |
|
60 |
* changelist_haszonedchild() - check if there is any child exported to |
|
61 |
* a local zone |
|
62 |
*/ |
|
63 |
typedef struct prop_changenode { |
|
64 |
zfs_handle_t *cn_handle; |
|
65 |
int cn_shared; |
|
66 |
int cn_mounted; |
|
67 |
int cn_zoned; |
|
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
68 |
boolean_t cn_needpost; /* is postfix() needed? */ |
789 | 69 |
uu_list_node_t cn_listnode; |
70 |
} prop_changenode_t; |
|
71 |
||
72 |
struct prop_changelist { |
|
73 |
zfs_prop_t cl_prop; |
|
74 |
zfs_prop_t cl_realprop; |
|
5331 | 75 |
zfs_prop_t cl_shareprop; /* used with sharenfs/sharesmb */ |
789 | 76 |
uu_list_pool_t *cl_pool; |
77 |
uu_list_t *cl_list; |
|
2082 | 78 |
boolean_t cl_waslegacy; |
79 |
boolean_t cl_allchildren; |
|
80 |
boolean_t cl_alldependents; |
|
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
81 |
int cl_mflags; /* Mount flags */ |
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
82 |
int cl_gflags; /* Gather request flags */ |
2082 | 83 |
boolean_t cl_haszonedchild; |
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
84 |
boolean_t cl_sorted; |
789 | 85 |
}; |
86 |
||
87 |
/* |
|
88 |
* If the property is 'mountpoint', go through and unmount filesystems as |
|
89 |
* necessary. We don't do the same for 'sharenfs', because we can just re-share |
|
6113
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
90 |
* with different options without interrupting service. We do handle 'sharesmb' |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
91 |
* since there may be old resource names that need to be removed. |
789 | 92 |
*/ |
93 |
int |
|
94 |
changelist_prefix(prop_changelist_t *clp) |
|
95 |
{ |
|
96 |
prop_changenode_t *cn; |
|
97 |
int ret = 0; |
|
98 |
||
6113
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
99 |
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT && |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
100 |
clp->cl_prop != ZFS_PROP_SHARESMB) |
789 | 101 |
return (0); |
102 |
||
103 |
for (cn = uu_list_first(clp->cl_list); cn != NULL; |
|
104 |
cn = uu_list_next(clp->cl_list, cn)) { |
|
5610 | 105 |
|
106 |
/* if a previous loop failed, set the remaining to false */ |
|
107 |
if (ret == -1) { |
|
108 |
cn->cn_needpost = B_FALSE; |
|
109 |
continue; |
|
110 |
} |
|
111 |
||
789 | 112 |
/* |
3126 | 113 |
* If we are in the global zone, but this dataset is exported |
114 |
* to a local zone, do nothing. |
|
789 | 115 |
*/ |
3126 | 116 |
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned) |
789 | 117 |
continue; |
118 |
||
3126 | 119 |
if (ZFS_IS_VOLUME(cn->cn_handle)) { |
120 |
switch (clp->cl_realprop) { |
|
121 |
case ZFS_PROP_NAME: |
|
122 |
/* |
|
123 |
* If this was a rename, unshare the zvol, and |
|
124 |
* remove the /dev/zvol links. |
|
125 |
*/ |
|
126 |
(void) zfs_unshare_iscsi(cn->cn_handle); |
|
127 |
||
128 |
if (zvol_remove_link(cn->cn_handle->zfs_hdl, |
|
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
129 |
cn->cn_handle->zfs_name) != 0) { |
3126 | 130 |
ret = -1; |
5610 | 131 |
cn->cn_needpost = B_FALSE; |
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
132 |
(void) zfs_share_iscsi(cn->cn_handle); |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
133 |
} |
3126 | 134 |
break; |
135 |
||
136 |
case ZFS_PROP_VOLSIZE: |
|
137 |
/* |
|
138 |
* If this was a change to the volume size, we |
|
139 |
* need to unshare and reshare the volume. |
|
140 |
*/ |
|
141 |
(void) zfs_unshare_iscsi(cn->cn_handle); |
|
142 |
break; |
|
143 |
} |
|
6113
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
144 |
} else { |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
145 |
/* |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
146 |
* Do the property specific processing. |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
147 |
*/ |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
148 |
switch (clp->cl_prop) { |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
149 |
case ZFS_PROP_MOUNTPOINT: |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
150 |
if (zfs_unmount(cn->cn_handle, NULL, |
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
151 |
clp->cl_mflags) != 0) { |
6113
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
152 |
ret = -1; |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
153 |
cn->cn_needpost = B_FALSE; |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
154 |
} |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
155 |
break; |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
156 |
case ZFS_PROP_SHARESMB: |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
157 |
(void) zfs_unshare_smb(cn->cn_handle, NULL); |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
158 |
break; |
700d1435ce0c
6660651 Modifying a CIFS Resource Name causes share to become available to CIFS clients by either name
dougm
parents:
6027
diff
changeset
|
159 |
} |
4577 | 160 |
} |
789 | 161 |
} |
162 |
||
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
163 |
if (ret == -1) |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
164 |
(void) changelist_postfix(clp); |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
165 |
|
789 | 166 |
return (ret); |
167 |
} |
|
168 |
||
169 |
/* |
|
3126 | 170 |
* If the property is 'mountpoint' or 'sharenfs', go through and remount and/or |
789 | 171 |
* reshare the filesystems as necessary. In changelist_gather() we recorded |
172 |
* whether the filesystem was previously shared or mounted. The action we take |
|
173 |
* depends on the previous state, and whether the value was previously 'legacy'. |
|
174 |
* For non-legacy properties, we only remount/reshare the filesystem if it was |
|
175 |
* previously mounted/shared. Otherwise, we always remount/reshare the |
|
176 |
* filesystem. |
|
177 |
*/ |
|
178 |
int |
|
179 |
changelist_postfix(prop_changelist_t *clp) |
|
180 |
{ |
|
181 |
prop_changenode_t *cn; |
|
3126 | 182 |
char shareopts[ZFS_MAXPROPLEN]; |
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
183 |
int errors = 0; |
4180
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
184 |
libzfs_handle_t *hdl; |
789 | 185 |
|
186 |
/* |
|
187 |
* If we're changing the mountpoint, attempt to destroy the underlying |
|
188 |
* mountpoint. All other datasets will have inherited from this dataset |
|
189 |
* (in which case their mountpoints exist in the filesystem in the new |
|
190 |
* location), or have explicit mountpoints set (in which case they won't |
|
191 |
* be in the changelist). |
|
192 |
*/ |
|
193 |
if ((cn = uu_list_last(clp->cl_list)) == NULL) |
|
194 |
return (0); |
|
195 |
||
196 |
if (clp->cl_prop == ZFS_PROP_MOUNTPOINT) |
|
197 |
remove_mountpoint(cn->cn_handle); |
|
198 |
||
199 |
/* |
|
4180
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
200 |
* It is possible that the changelist_prefix() used libshare |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
201 |
* to unshare some entries. Since libshare caches data, an |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
202 |
* attempt to reshare during postfix can fail unless libshare |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
203 |
* is uninitialized here so that it will reinitialize later. |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
204 |
*/ |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
205 |
if (cn->cn_handle != NULL) { |
4302 | 206 |
hdl = cn->cn_handle->zfs_hdl; |
207 |
assert(hdl != NULL); |
|
208 |
zfs_uninit_libshare(hdl); |
|
4180
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
209 |
} |
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
210 |
|
30b15f0bd3c9
6491973 sharemgr: zfs set sharenfs=on is slow with lots of zfs filesystems
dougm
parents:
4074
diff
changeset
|
211 |
/* |
789 | 212 |
* We walk the datasets in reverse, because we want to mount any parent |
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
213 |
* datasets before mounting the children. We walk all datasets even if |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
214 |
* there are errors. |
789 | 215 |
*/ |
216 |
for (cn = uu_list_last(clp->cl_list); cn != NULL; |
|
217 |
cn = uu_list_prev(clp->cl_list, cn)) { |
|
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
218 |
|
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
219 |
boolean_t sharenfs; |
5331 | 220 |
boolean_t sharesmb; |
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
221 |
|
789 | 222 |
/* |
3126 | 223 |
* If we are in the global zone, but this dataset is exported |
224 |
* to a local zone, do nothing. |
|
789 | 225 |
*/ |
3126 | 226 |
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned) |
789 | 227 |
continue; |
228 |
||
5610 | 229 |
/* Only do post-processing if it's required */ |
5542
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
230 |
if (!cn->cn_needpost) |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
231 |
continue; |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
232 |
cn->cn_needpost = B_FALSE; |
bf520ef4fd90
6428435 zfs rename failure can leave file systems unmounted.
mmusante
parents:
5473
diff
changeset
|
233 |
|
789 | 234 |
zfs_refresh_properties(cn->cn_handle); |
235 |
||
3126 | 236 |
if (ZFS_IS_VOLUME(cn->cn_handle)) { |
237 |
/* |
|
238 |
* If we're doing a rename, recreate the /dev/zvol |
|
239 |
* links. |
|
240 |
*/ |
|
241 |
if (clp->cl_realprop == ZFS_PROP_NAME && |
|
242 |
zvol_create_link(cn->cn_handle->zfs_hdl, |
|
243 |
cn->cn_handle->zfs_name) != 0) { |
|
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
244 |
errors++; |
3126 | 245 |
} else if (cn->cn_shared || |
246 |
clp->cl_prop == ZFS_PROP_SHAREISCSI) { |
|
247 |
if (zfs_prop_get(cn->cn_handle, |
|
248 |
ZFS_PROP_SHAREISCSI, shareopts, |
|
249 |
sizeof (shareopts), NULL, NULL, 0, |
|
250 |
B_FALSE) == 0 && |
|
251 |
strcmp(shareopts, "off") == 0) { |
|
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
252 |
errors += |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
253 |
zfs_unshare_iscsi(cn->cn_handle); |
3126 | 254 |
} else { |
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
255 |
errors += |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
256 |
zfs_share_iscsi(cn->cn_handle); |
3126 | 257 |
} |
258 |
} |
|
259 |
||
789 | 260 |
continue; |
261 |
} |
|
262 |
||
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
263 |
/* |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
264 |
* Remount if previously mounted or mountpoint was legacy, |
5331 | 265 |
* or sharenfs or sharesmb property is set. |
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
266 |
*/ |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
267 |
sharenfs = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARENFS, |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
268 |
shareopts, sizeof (shareopts), NULL, NULL, 0, |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
269 |
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0)); |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
270 |
|
5331 | 271 |
sharesmb = ((zfs_prop_get(cn->cn_handle, ZFS_PROP_SHARESMB, |
272 |
shareopts, sizeof (shareopts), NULL, NULL, 0, |
|
273 |
B_FALSE) == 0) && (strcmp(shareopts, "off") != 0)); |
|
274 |
||
275 |
if ((cn->cn_mounted || clp->cl_waslegacy || sharenfs || |
|
276 |
sharesmb) && !zfs_is_mounted(cn->cn_handle, NULL) && |
|
789 | 277 |
zfs_mount(cn->cn_handle, NULL, 0) != 0) |
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
278 |
errors++; |
789 | 279 |
|
280 |
/* |
|
281 |
* We always re-share even if the filesystem is currently |
|
282 |
* shared, so that we can adopt any new options. |
|
283 |
*/ |
|
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
284 |
if (sharenfs) |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
285 |
errors += zfs_share_nfs(cn->cn_handle); |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
286 |
else if (cn->cn_shared || clp->cl_waslegacy) |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
287 |
errors += zfs_unshare_nfs(cn->cn_handle, NULL); |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
288 |
if (sharesmb) |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
289 |
errors += zfs_share_smb(cn->cn_handle); |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
290 |
else if (cn->cn_shared || clp->cl_waslegacy) |
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
291 |
errors += zfs_unshare_smb(cn->cn_handle, NULL); |
789 | 292 |
} |
293 |
||
5473
fcdd1931b3aa
6590941 zfs set mountpoint should not return 0 when it fails
rm160521
parents:
5367
diff
changeset
|
294 |
return (errors ? -1 : 0); |
789 | 295 |
} |
296 |
||
297 |
/* |
|
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
298 |
* Is this "dataset" a child of "parent"? |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
299 |
*/ |
6027
68b03551f113
6609196 'zfs destroy -r' can needlessly iterate over all filesystems in pool
rm160521
parents:
5610
diff
changeset
|
300 |
boolean_t |
3841
496dd81e3d5c
6449807 'zfs rename <vol@snap>' does not re-create device link
mmusante
parents:
3126
diff
changeset
|
301 |
isa_child_of(const char *dataset, const char *parent) |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
302 |
{ |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
303 |
int len; |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
304 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
305 |
len = strlen(parent); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
306 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
307 |
if (strncmp(dataset, parent, len) == 0 && |
3841
496dd81e3d5c
6449807 'zfs rename <vol@snap>' does not re-create device link
mmusante
parents:
3126
diff
changeset
|
308 |
(dataset[len] == '@' || dataset[len] == '/' || |
496dd81e3d5c
6449807 'zfs rename <vol@snap>' does not re-create device link
mmusante
parents:
3126
diff
changeset
|
309 |
dataset[len] == '\0')) |
2082 | 310 |
return (B_TRUE); |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
311 |
else |
2082 | 312 |
return (B_FALSE); |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
313 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
314 |
} |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
315 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
316 |
/* |
3126 | 317 |
* If we rename a filesystem, child filesystem handles are no longer valid |
318 |
* since we identify each dataset by its name in the ZFS namespace. As a |
|
319 |
* result, we have to go through and fix up all the names appropriately. We |
|
320 |
* could do this automatically if libzfs kept track of all open handles, but |
|
321 |
* this is a lot less work. |
|
789 | 322 |
*/ |
323 |
void |
|
324 |
changelist_rename(prop_changelist_t *clp, const char *src, const char *dst) |
|
325 |
{ |
|
326 |
prop_changenode_t *cn; |
|
327 |
char newname[ZFS_MAXNAMELEN]; |
|
328 |
||
329 |
for (cn = uu_list_first(clp->cl_list); cn != NULL; |
|
330 |
cn = uu_list_next(clp->cl_list, cn)) { |
|
331 |
/* |
|
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
332 |
* Do not rename a clone that's not in the source hierarchy. |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
333 |
*/ |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
334 |
if (!isa_child_of(cn->cn_handle->zfs_name, src)) |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
335 |
continue; |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
336 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
337 |
/* |
789 | 338 |
* Destroy the previous mountpoint if needed. |
339 |
*/ |
|
340 |
remove_mountpoint(cn->cn_handle); |
|
341 |
||
342 |
(void) strlcpy(newname, dst, sizeof (newname)); |
|
343 |
(void) strcat(newname, cn->cn_handle->zfs_name + strlen(src)); |
|
344 |
||
345 |
(void) strlcpy(cn->cn_handle->zfs_name, newname, |
|
346 |
sizeof (cn->cn_handle->zfs_name)); |
|
347 |
} |
|
348 |
} |
|
349 |
||
350 |
/* |
|
5331 | 351 |
* Given a gathered changelist for the 'sharenfs' or 'sharesmb' property, |
352 |
* unshare all the datasets in the list. |
|
789 | 353 |
*/ |
354 |
int |
|
5331 | 355 |
changelist_unshare(prop_changelist_t *clp, zfs_share_proto_t *proto) |
789 | 356 |
{ |
357 |
prop_changenode_t *cn; |
|
358 |
int ret = 0; |
|
359 |
||
5331 | 360 |
if (clp->cl_prop != ZFS_PROP_SHARENFS && |
361 |
clp->cl_prop != ZFS_PROP_SHARESMB) |
|
789 | 362 |
return (0); |
363 |
||
364 |
for (cn = uu_list_first(clp->cl_list); cn != NULL; |
|
365 |
cn = uu_list_next(clp->cl_list, cn)) { |
|
5331 | 366 |
if (zfs_unshare_proto(cn->cn_handle, NULL, proto) != 0) |
789 | 367 |
ret = -1; |
368 |
} |
|
369 |
||
370 |
return (ret); |
|
371 |
} |
|
372 |
||
373 |
/* |
|
3126 | 374 |
* Check if there is any child exported to a local zone in a given changelist. |
375 |
* This information has already been recorded while gathering the changelist |
|
376 |
* via changelist_gather(). |
|
789 | 377 |
*/ |
378 |
int |
|
379 |
changelist_haszonedchild(prop_changelist_t *clp) |
|
380 |
{ |
|
381 |
return (clp->cl_haszonedchild); |
|
382 |
} |
|
383 |
||
384 |
/* |
|
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
385 |
* Remove a node from a gathered list. |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
386 |
*/ |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
387 |
void |
5367 | 388 |
changelist_remove(prop_changelist_t *clp, const char *name) |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
389 |
{ |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
390 |
prop_changenode_t *cn; |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
391 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
392 |
for (cn = uu_list_first(clp->cl_list); cn != NULL; |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
393 |
cn = uu_list_next(clp->cl_list, cn)) { |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
394 |
|
5367 | 395 |
if (strcmp(cn->cn_handle->zfs_name, name) == 0) { |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
396 |
uu_list_remove(clp->cl_list, cn); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
397 |
zfs_close(cn->cn_handle); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
398 |
free(cn); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
399 |
return; |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
400 |
} |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
401 |
} |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
402 |
} |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
403 |
|
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
404 |
/* |
789 | 405 |
* Release any memory associated with a changelist. |
406 |
*/ |
|
407 |
void |
|
408 |
changelist_free(prop_changelist_t *clp) |
|
409 |
{ |
|
410 |
prop_changenode_t *cn; |
|
4074
58874e1ba2ef
6547185 libzfs should make use of uu_{list,avl}_teardown
eschrock
parents:
3841
diff
changeset
|
411 |
void *cookie; |
789 | 412 |
|
2142
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
413 |
if (clp->cl_list) { |
4074
58874e1ba2ef
6547185 libzfs should make use of uu_{list,avl}_teardown
eschrock
parents:
3841
diff
changeset
|
414 |
cookie = NULL; |
58874e1ba2ef
6547185 libzfs should make use of uu_{list,avl}_teardown
eschrock
parents:
3841
diff
changeset
|
415 |
while ((cn = uu_list_teardown(clp->cl_list, &cookie)) != NULL) { |
2142
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
416 |
zfs_close(cn->cn_handle); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
417 |
free(cn); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
418 |
} |
789 | 419 |
|
2142
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
420 |
uu_list_destroy(clp->cl_list); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
421 |
} |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
422 |
if (clp->cl_pool) |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
423 |
uu_list_pool_destroy(clp->cl_pool); |
789 | 424 |
|
425 |
free(clp); |
|
426 |
} |
|
427 |
||
428 |
static int |
|
429 |
change_one(zfs_handle_t *zhp, void *data) |
|
430 |
{ |
|
431 |
prop_changelist_t *clp = data; |
|
432 |
char property[ZFS_MAXPROPLEN]; |
|
433 |
char where[64]; |
|
434 |
prop_changenode_t *cn; |
|
5094 | 435 |
zprop_source_t sourcetype; |
5331 | 436 |
zprop_source_t share_sourcetype; |
789 | 437 |
|
438 |
/* |
|
3126 | 439 |
* We only want to unmount/unshare those filesystems that may inherit |
440 |
* from the target filesystem. If we find any filesystem with a |
|
441 |
* locally set mountpoint, we ignore any children since changing the |
|
442 |
* property will not affect them. If this is a rename, we iterate |
|
443 |
* over all children regardless, since we need them unmounted in |
|
444 |
* order to do the rename. Also, if this is a volume and we're doing |
|
445 |
* a rename, then always add it to the changelist. |
|
789 | 446 |
*/ |
447 |
||
2676 | 448 |
if (!(ZFS_IS_VOLUME(zhp) && clp->cl_realprop == ZFS_PROP_NAME) && |
789 | 449 |
zfs_prop_get(zhp, clp->cl_prop, property, |
450 |
sizeof (property), &sourcetype, where, sizeof (where), |
|
2082 | 451 |
B_FALSE) != 0) { |
452 |
zfs_close(zhp); |
|
789 | 453 |
return (0); |
2082 | 454 |
} |
789 | 455 |
|
5331 | 456 |
/* |
457 |
* If we are "watching" sharenfs or sharesmb |
|
458 |
* then check out the companion property which is tracked |
|
459 |
* in cl_shareprop |
|
460 |
*/ |
|
461 |
if (clp->cl_shareprop != ZPROP_INVAL && |
|
462 |
zfs_prop_get(zhp, clp->cl_shareprop, property, |
|
463 |
sizeof (property), &share_sourcetype, where, sizeof (where), |
|
464 |
B_FALSE) != 0) { |
|
465 |
zfs_close(zhp); |
|
466 |
return (0); |
|
467 |
} |
|
468 |
||
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
469 |
if (clp->cl_alldependents || clp->cl_allchildren || |
5094 | 470 |
sourcetype == ZPROP_SRC_DEFAULT || |
5331 | 471 |
sourcetype == ZPROP_SRC_INHERITED || |
472 |
(clp->cl_shareprop != ZPROP_INVAL && |
|
473 |
(share_sourcetype == ZPROP_SRC_DEFAULT || |
|
474 |
share_sourcetype == ZPROP_SRC_INHERITED))) { |
|
2082 | 475 |
if ((cn = zfs_alloc(zfs_get_handle(zhp), |
476 |
sizeof (prop_changenode_t))) == NULL) { |
|
477 |
zfs_close(zhp); |
|
478 |
return (-1); |
|
479 |
} |
|
789 | 480 |
|
481 |
cn->cn_handle = zhp; |
|
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
482 |
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) || |
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
483 |
zfs_is_mounted(zhp, NULL); |
3126 | 484 |
cn->cn_shared = zfs_is_shared(zhp); |
789 | 485 |
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); |
5610 | 486 |
cn->cn_needpost = B_TRUE; |
789 | 487 |
|
3126 | 488 |
/* Indicate if any child is exported to a local zone. */ |
489 |
if (getzoneid() == GLOBAL_ZONEID && cn->cn_zoned) |
|
2082 | 490 |
clp->cl_haszonedchild = B_TRUE; |
789 | 491 |
|
492 |
uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool); |
|
493 |
||
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
494 |
if (clp->cl_sorted) { |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
495 |
uu_list_index_t idx; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
496 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
497 |
(void) uu_list_find(clp->cl_list, cn, NULL, |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
498 |
&idx); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
499 |
uu_list_insert(clp->cl_list, cn, idx); |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
500 |
} else { |
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
501 |
ASSERT(!clp->cl_alldependents); |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
502 |
verify(uu_list_insert_before(clp->cl_list, |
4074
58874e1ba2ef
6547185 libzfs should make use of uu_{list,avl}_teardown
eschrock
parents:
3841
diff
changeset
|
503 |
uu_list_first(clp->cl_list), cn) == 0); |
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
504 |
} |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
505 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
506 |
if (!clp->cl_alldependents) |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
507 |
return (zfs_iter_children(zhp, change_one, data)); |
789 | 508 |
} else { |
509 |
zfs_close(zhp); |
|
510 |
} |
|
511 |
||
512 |
return (0); |
|
513 |
} |
|
514 |
||
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
515 |
/*ARGSUSED*/ |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
516 |
static int |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
517 |
compare_mountpoints(const void *a, const void *b, void *unused) |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
518 |
{ |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
519 |
const prop_changenode_t *ca = a; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
520 |
const prop_changenode_t *cb = b; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
521 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
522 |
char mounta[MAXPATHLEN]; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
523 |
char mountb[MAXPATHLEN]; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
524 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
525 |
boolean_t hasmounta, hasmountb; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
526 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
527 |
/* |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
528 |
* When unsharing or unmounting filesystems, we need to do it in |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
529 |
* mountpoint order. This allows the user to have a mountpoint |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
530 |
* hierarchy that is different from the dataset hierarchy, and still |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
531 |
* allow it to be changed. However, if either dataset doesn't have a |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
532 |
* mountpoint (because it is a volume or a snapshot), we place it at the |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
533 |
* end of the list, because it doesn't affect our change at all. |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
534 |
*/ |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
535 |
hasmounta = (zfs_prop_get(ca->cn_handle, ZFS_PROP_MOUNTPOINT, mounta, |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
536 |
sizeof (mounta), NULL, NULL, 0, B_FALSE) == 0); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
537 |
hasmountb = (zfs_prop_get(cb->cn_handle, ZFS_PROP_MOUNTPOINT, mountb, |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
538 |
sizeof (mountb), NULL, NULL, 0, B_FALSE) == 0); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
539 |
|
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
540 |
if (!hasmounta && hasmountb) |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
541 |
return (-1); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
542 |
else if (hasmounta && !hasmountb) |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
543 |
return (1); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
544 |
else if (!hasmounta && !hasmountb) |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
545 |
return (0); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
546 |
else |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
547 |
return (strcmp(mountb, mounta)); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
548 |
} |
789 | 549 |
|
550 |
/* |
|
3126 | 551 |
* Given a ZFS handle and a property, construct a complete list of datasets |
552 |
* that need to be modified as part of this process. For anything but the |
|
789 | 553 |
* 'mountpoint' and 'sharenfs' properties, this just returns an empty list. |
3126 | 554 |
* Otherwise, we iterate over all children and look for any datasets that |
555 |
* inherit the property. For each such dataset, we add it to the list and |
|
556 |
* mark whether it was shared beforehand. |
|
789 | 557 |
*/ |
558 |
prop_changelist_t * |
|
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
559 |
changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags, |
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
560 |
int mnt_flags) |
789 | 561 |
{ |
2082 | 562 |
prop_changelist_t *clp; |
789 | 563 |
prop_changenode_t *cn; |
564 |
zfs_handle_t *temp; |
|
565 |
char property[ZFS_MAXPROPLEN]; |
|
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
566 |
uu_compare_fn_t *compare = NULL; |
789 | 567 |
|
2082 | 568 |
if ((clp = zfs_alloc(zhp->zfs_hdl, sizeof (prop_changelist_t))) == NULL) |
569 |
return (NULL); |
|
570 |
||
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
571 |
/* |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
572 |
* For mountpoint-related tasks, we want to sort everything by |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
573 |
* mountpoint, so that we mount and unmount them in the appropriate |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
574 |
* order, regardless of their position in the hierarchy. |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
575 |
*/ |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
576 |
if (prop == ZFS_PROP_NAME || prop == ZFS_PROP_ZONED || |
5331 | 577 |
prop == ZFS_PROP_MOUNTPOINT || prop == ZFS_PROP_SHARENFS || |
578 |
prop == ZFS_PROP_SHARESMB) { |
|
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
579 |
compare = compare_mountpoints; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
580 |
clp->cl_sorted = B_TRUE; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
581 |
} |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
582 |
|
789 | 583 |
clp->cl_pool = uu_list_pool_create("changelist_pool", |
584 |
sizeof (prop_changenode_t), |
|
585 |
offsetof(prop_changenode_t, cn_listnode), |
|
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
586 |
compare, 0); |
2142
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
587 |
if (clp->cl_pool == NULL) { |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
588 |
assert(uu_error() == UU_ERROR_NO_MEMORY); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
589 |
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error"); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
590 |
changelist_free(clp); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
591 |
return (NULL); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
592 |
} |
789 | 593 |
|
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
594 |
clp->cl_list = uu_list_create(clp->cl_pool, NULL, |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
595 |
clp->cl_sorted ? UU_LIST_SORTED : 0); |
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
596 |
clp->cl_gflags = gather_flags; |
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
597 |
clp->cl_mflags = mnt_flags; |
789 | 598 |
|
2142
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
599 |
if (clp->cl_list == NULL) { |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
600 |
assert(uu_error() == UU_ERROR_NO_MEMORY); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
601 |
(void) zfs_error(zhp->zfs_hdl, EZFS_NOMEM, "internal error"); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
602 |
changelist_free(clp); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
603 |
return (NULL); |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
604 |
} |
f6e0487aa9a3
6433264 crash when adding spare: nvlist_lookup_string(cnv, "path", &path) == 0
eschrock
parents:
2082
diff
changeset
|
605 |
|
789 | 606 |
/* |
607 |
* If this is a rename or the 'zoned' property, we pretend we're |
|
608 |
* changing the mountpoint and flag it so we can catch all children in |
|
609 |
* change_one(). |
|
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
610 |
* |
3126 | 611 |
* Flag cl_alldependents to catch all children plus the dependents |
612 |
* (clones) that are not in the hierarchy. |
|
789 | 613 |
*/ |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
614 |
if (prop == ZFS_PROP_NAME) { |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
615 |
clp->cl_prop = ZFS_PROP_MOUNTPOINT; |
2082 | 616 |
clp->cl_alldependents = B_TRUE; |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
617 |
} else if (prop == ZFS_PROP_ZONED) { |
789 | 618 |
clp->cl_prop = ZFS_PROP_MOUNTPOINT; |
2082 | 619 |
clp->cl_allchildren = B_TRUE; |
2676 | 620 |
} else if (prop == ZFS_PROP_CANMOUNT) { |
621 |
clp->cl_prop = ZFS_PROP_MOUNTPOINT; |
|
3126 | 622 |
} else if (prop == ZFS_PROP_VOLSIZE) { |
623 |
clp->cl_prop = ZFS_PROP_MOUNTPOINT; |
|
4577 | 624 |
} else if (prop == ZFS_PROP_VERSION) { |
625 |
clp->cl_prop = ZFS_PROP_MOUNTPOINT; |
|
789 | 626 |
} else { |
627 |
clp->cl_prop = prop; |
|
628 |
} |
|
629 |
clp->cl_realprop = prop; |
|
630 |
||
631 |
if (clp->cl_prop != ZFS_PROP_MOUNTPOINT && |
|
3126 | 632 |
clp->cl_prop != ZFS_PROP_SHARENFS && |
5331 | 633 |
clp->cl_prop != ZFS_PROP_SHARESMB && |
3126 | 634 |
clp->cl_prop != ZFS_PROP_SHAREISCSI) |
789 | 635 |
return (clp); |
636 |
||
5331 | 637 |
/* |
638 |
* If watching SHARENFS or SHARESMB then |
|
639 |
* also watch its companion property. |
|
640 |
*/ |
|
641 |
if (clp->cl_prop == ZFS_PROP_SHARENFS) |
|
642 |
clp->cl_shareprop = ZFS_PROP_SHARESMB; |
|
643 |
else if (clp->cl_prop == ZFS_PROP_SHARESMB) |
|
644 |
clp->cl_shareprop = ZFS_PROP_SHARENFS; |
|
645 |
||
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
646 |
if (clp->cl_alldependents) { |
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
647 |
if (zfs_iter_dependents(zhp, B_TRUE, change_one, clp) != 0) { |
1294
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
648 |
changelist_free(clp); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
649 |
return (NULL); |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
650 |
} |
87b43e5de5ee
6364129 need to unmount any child datasets before doing the rollback
lling
parents:
789
diff
changeset
|
651 |
} else if (zfs_iter_children(zhp, change_one, clp) != 0) { |
789 | 652 |
changelist_free(clp); |
653 |
return (NULL); |
|
654 |
} |
|
655 |
||
656 |
/* |
|
657 |
* We have to re-open ourselves because we auto-close all the handles |
|
658 |
* and can't tell the difference. |
|
659 |
*/ |
|
2082 | 660 |
if ((temp = zfs_open(zhp->zfs_hdl, zfs_get_name(zhp), |
5094 | 661 |
ZFS_TYPE_DATASET)) == NULL) { |
2082 | 662 |
changelist_free(clp); |
789 | 663 |
return (NULL); |
664 |
} |
|
665 |
||
666 |
/* |
|
667 |
* Always add ourself to the list. We add ourselves to the end so that |
|
668 |
* we're the last to be unmounted. |
|
669 |
*/ |
|
2082 | 670 |
if ((cn = zfs_alloc(zhp->zfs_hdl, |
671 |
sizeof (prop_changenode_t))) == NULL) { |
|
672 |
zfs_close(temp); |
|
673 |
changelist_free(clp); |
|
674 |
return (NULL); |
|
675 |
} |
|
676 |
||
789 | 677 |
cn->cn_handle = temp; |
7366
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
678 |
cn->cn_mounted = (clp->cl_gflags & CL_GATHER_MOUNT_ALWAYS) || |
33de5956afbb
6678308 zfs receive dumps core when -n is used, fails on replication stream
Tim Haley <Tim.Haley@Sun.COM>
parents:
6168
diff
changeset
|
679 |
zfs_is_mounted(temp, NULL); |
3126 | 680 |
cn->cn_shared = zfs_is_shared(temp); |
789 | 681 |
cn->cn_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED); |
5610 | 682 |
cn->cn_needpost = B_TRUE; |
789 | 683 |
|
684 |
uu_list_node_init(cn, &cn->cn_listnode, clp->cl_pool); |
|
2474
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
685 |
if (clp->cl_sorted) { |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
686 |
uu_list_index_t idx; |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
687 |
(void) uu_list_find(clp->cl_list, cn, NULL, &idx); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
688 |
uu_list_insert(clp->cl_list, cn, idx); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
689 |
} else { |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
690 |
verify(uu_list_insert_after(clp->cl_list, |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
691 |
uu_list_last(clp->cl_list), cn) == 0); |
c001ad7e0c25
6368751 libzfs interface for mount/umounting all the file systems for a given pool
eschrock
parents:
2142
diff
changeset
|
692 |
} |
789 | 693 |
|
694 |
/* |
|
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
695 |
* If the mountpoint property was previously 'legacy', or 'none', |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
696 |
* record it as the behavior of changelist_postfix() will be different. |
789 | 697 |
*/ |
4840
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
698 |
if ((clp->cl_prop == ZFS_PROP_MOUNTPOINT) && |
cb7aae35fdf7
6589962 set sharenfs=on does not work on onnv 0805 build
rm160521
parents:
4778
diff
changeset
|
699 |
(zfs_prop_get(zhp, prop, property, sizeof (property), |
2082 | 700 |
NULL, NULL, 0, B_FALSE) == 0 && |
6168
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
701 |
(strcmp(property, "legacy") == 0 || |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
702 |
strcmp(property, "none") == 0))) { |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
703 |
/* |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
704 |
* do not automatically mount ex-legacy datasets if |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
705 |
* we specifically set canmount to noauto |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
706 |
*/ |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
707 |
if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) != |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
708 |
ZFS_CANMOUNT_NOAUTO) |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
709 |
clp->cl_waslegacy = B_TRUE; |
51c045dcc498
PSARC 2008/168 Support for ZFS property value canmount=noauto
hs24103
parents:
6113
diff
changeset
|
710 |
} |
789 | 711 |
|
712 |
return (clp); |
|
713 |
} |