]> git.proxmox.com Git - mirror_zfs.git/blob - lib/libzfs/libzfs_dataset.c
libzfs: Convert to fnvpair functions
[mirror_zfs.git] / lib / libzfs / libzfs_dataset.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2019 Joyent, Inc.
25 * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
26 * Copyright (c) 2012 DEY Storage Systems, Inc. All rights reserved.
27 * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
28 * Copyright (c) 2013 Martin Matuska. All rights reserved.
29 * Copyright (c) 2013 Steven Hartland. All rights reserved.
30 * Copyright 2017 Nexenta Systems, Inc.
31 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
32 * Copyright 2017-2018 RackTop Systems.
33 * Copyright (c) 2019 Datto Inc.
34 * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>
35 * Copyright (c) 2021 Matt Fiddaman
36 */
37
38 #include <ctype.h>
39 #include <errno.h>
40 #include <libintl.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <strings.h>
44 #include <unistd.h>
45 #include <stddef.h>
46 #include <zone.h>
47 #include <fcntl.h>
48 #include <sys/mntent.h>
49 #include <sys/mount.h>
50 #include <pwd.h>
51 #include <grp.h>
52 #include <ucred.h>
53 #ifdef HAVE_IDMAP
54 #include <idmap.h>
55 #include <aclutils.h>
56 #include <directory.h>
57 #endif /* HAVE_IDMAP */
58
59 #include <sys/dnode.h>
60 #include <sys/spa.h>
61 #include <sys/zap.h>
62 #include <sys/dsl_crypt.h>
63 #include <libzfs.h>
64 #include <libzutil.h>
65
66 #include "zfs_namecheck.h"
67 #include "zfs_prop.h"
68 #include "libzfs_impl.h"
69 #include "zfs_deleg.h"
70
71 static int userquota_propname_decode(const char *propname, boolean_t zoned,
72 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp);
73
74 /*
75 * Given a single type (not a mask of types), return the type in a human
76 * readable form.
77 */
78 const char *
79 zfs_type_to_name(zfs_type_t type)
80 {
81 switch (type) {
82 case ZFS_TYPE_FILESYSTEM:
83 return (dgettext(TEXT_DOMAIN, "filesystem"));
84 case ZFS_TYPE_SNAPSHOT:
85 return (dgettext(TEXT_DOMAIN, "snapshot"));
86 case ZFS_TYPE_VOLUME:
87 return (dgettext(TEXT_DOMAIN, "volume"));
88 case ZFS_TYPE_POOL:
89 return (dgettext(TEXT_DOMAIN, "pool"));
90 case ZFS_TYPE_BOOKMARK:
91 return (dgettext(TEXT_DOMAIN, "bookmark"));
92 default:
93 assert(!"unhandled zfs_type_t");
94 }
95
96 return (NULL);
97 }
98
99 /*
100 * Validate a ZFS path. This is used even before trying to open the dataset, to
101 * provide a more meaningful error message. We call zfs_error_aux() to
102 * explain exactly why the name was not valid.
103 */
104 int
105 zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
106 boolean_t modifying)
107 {
108 namecheck_err_t why;
109 char what;
110
111 if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
112 if (hdl != NULL)
113 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
114 "snapshot delimiter '@' is not expected here"));
115 return (0);
116 }
117
118 if (type == ZFS_TYPE_SNAPSHOT && strchr(path, '@') == NULL) {
119 if (hdl != NULL)
120 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
121 "missing '@' delimiter in snapshot name"));
122 return (0);
123 }
124
125 if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) {
126 if (hdl != NULL)
127 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
128 "bookmark delimiter '#' is not expected here"));
129 return (0);
130 }
131
132 if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) {
133 if (hdl != NULL)
134 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
135 "missing '#' delimiter in bookmark name"));
136 return (0);
137 }
138
139 if (modifying && strchr(path, '%') != NULL) {
140 if (hdl != NULL)
141 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
142 "invalid character %c in name"), '%');
143 return (0);
144 }
145
146 if (entity_namecheck(path, &why, &what) != 0) {
147 if (hdl != NULL) {
148 switch (why) {
149 case NAME_ERR_TOOLONG:
150 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
151 "name is too long"));
152 break;
153
154 case NAME_ERR_LEADING_SLASH:
155 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
156 "leading slash in name"));
157 break;
158
159 case NAME_ERR_EMPTY_COMPONENT:
160 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
161 "empty component or misplaced '@'"
162 " or '#' delimiter in name"));
163 break;
164
165 case NAME_ERR_TRAILING_SLASH:
166 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
167 "trailing slash in name"));
168 break;
169
170 case NAME_ERR_INVALCHAR:
171 zfs_error_aux(hdl,
172 dgettext(TEXT_DOMAIN, "invalid character "
173 "'%c' in name"), what);
174 break;
175
176 case NAME_ERR_MULTIPLE_DELIMITERS:
177 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
178 "multiple '@' and/or '#' delimiters in "
179 "name"));
180 break;
181
182 case NAME_ERR_NOLETTER:
183 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
184 "pool doesn't begin with a letter"));
185 break;
186
187 case NAME_ERR_RESERVED:
188 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
189 "name is reserved"));
190 break;
191
192 case NAME_ERR_DISKLIKE:
193 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
194 "reserved disk name"));
195 break;
196
197 case NAME_ERR_SELF_REF:
198 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
199 "self reference, '.' is found in name"));
200 break;
201
202 case NAME_ERR_PARENT_REF:
203 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
204 "parent reference, '..' is found in name"));
205 break;
206
207 default:
208 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
209 "(%d) not defined"), why);
210 break;
211 }
212 }
213
214 return (0);
215 }
216
217 return (-1);
218 }
219
220 int
221 zfs_name_valid(const char *name, zfs_type_t type)
222 {
223 if (type == ZFS_TYPE_POOL)
224 return (zpool_name_valid(NULL, B_FALSE, name));
225 return (zfs_validate_name(NULL, name, type, B_FALSE));
226 }
227
228 /*
229 * This function takes the raw DSL properties, and filters out the user-defined
230 * properties into a separate nvlist.
231 */
232 static nvlist_t *
233 process_user_props(zfs_handle_t *zhp, nvlist_t *props)
234 {
235 libzfs_handle_t *hdl = zhp->zfs_hdl;
236 nvpair_t *elem;
237 nvlist_t *nvl;
238
239 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
240 (void) no_memory(hdl);
241 return (NULL);
242 }
243
244 elem = NULL;
245 while ((elem = nvlist_next_nvpair(props, elem)) != NULL) {
246 if (!zfs_prop_user(nvpair_name(elem)))
247 continue;
248
249 nvlist_t *propval = fnvpair_value_nvlist(elem);
250 if (nvlist_add_nvlist(nvl, nvpair_name(elem), propval) != 0) {
251 nvlist_free(nvl);
252 (void) no_memory(hdl);
253 return (NULL);
254 }
255 }
256
257 return (nvl);
258 }
259
260 static zpool_handle_t *
261 zpool_add_handle(zfs_handle_t *zhp, const char *pool_name)
262 {
263 libzfs_handle_t *hdl = zhp->zfs_hdl;
264 zpool_handle_t *zph;
265
266 if ((zph = zpool_open_canfail(hdl, pool_name)) != NULL) {
267 if (hdl->libzfs_pool_handles != NULL)
268 zph->zpool_next = hdl->libzfs_pool_handles;
269 hdl->libzfs_pool_handles = zph;
270 }
271 return (zph);
272 }
273
274 static zpool_handle_t *
275 zpool_find_handle(zfs_handle_t *zhp, const char *pool_name, int len)
276 {
277 libzfs_handle_t *hdl = zhp->zfs_hdl;
278 zpool_handle_t *zph = hdl->libzfs_pool_handles;
279
280 while ((zph != NULL) &&
281 (strncmp(pool_name, zpool_get_name(zph), len) != 0))
282 zph = zph->zpool_next;
283 return (zph);
284 }
285
286 /*
287 * Returns a handle to the pool that contains the provided dataset.
288 * If a handle to that pool already exists then that handle is returned.
289 * Otherwise, a new handle is created and added to the list of handles.
290 */
291 static zpool_handle_t *
292 zpool_handle(zfs_handle_t *zhp)
293 {
294 char *pool_name;
295 int len;
296 zpool_handle_t *zph;
297
298 len = strcspn(zhp->zfs_name, "/@#") + 1;
299 pool_name = zfs_alloc(zhp->zfs_hdl, len);
300 (void) strlcpy(pool_name, zhp->zfs_name, len);
301
302 zph = zpool_find_handle(zhp, pool_name, len);
303 if (zph == NULL)
304 zph = zpool_add_handle(zhp, pool_name);
305
306 free(pool_name);
307 return (zph);
308 }
309
310 void
311 zpool_free_handles(libzfs_handle_t *hdl)
312 {
313 zpool_handle_t *next, *zph = hdl->libzfs_pool_handles;
314
315 while (zph != NULL) {
316 next = zph->zpool_next;
317 zpool_close(zph);
318 zph = next;
319 }
320 hdl->libzfs_pool_handles = NULL;
321 }
322
323 /*
324 * Utility function to gather stats (objset and zpl) for the given object.
325 */
326 static int
327 get_stats_ioctl(zfs_handle_t *zhp, zfs_cmd_t *zc)
328 {
329 libzfs_handle_t *hdl = zhp->zfs_hdl;
330
331 (void) strlcpy(zc->zc_name, zhp->zfs_name, sizeof (zc->zc_name));
332
333 while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, zc) != 0) {
334 if (errno == ENOMEM) {
335 if (zcmd_expand_dst_nvlist(hdl, zc) != 0) {
336 return (-1);
337 }
338 } else {
339 return (-1);
340 }
341 }
342 return (0);
343 }
344
345 /*
346 * Utility function to get the received properties of the given object.
347 */
348 static int
349 get_recvd_props_ioctl(zfs_handle_t *zhp)
350 {
351 libzfs_handle_t *hdl = zhp->zfs_hdl;
352 nvlist_t *recvdprops;
353 zfs_cmd_t zc = {"\0"};
354 int err;
355
356 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0)
357 return (-1);
358
359 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
360
361 while (zfs_ioctl(hdl, ZFS_IOC_OBJSET_RECVD_PROPS, &zc) != 0) {
362 if (errno == ENOMEM) {
363 if (zcmd_expand_dst_nvlist(hdl, &zc) != 0) {
364 return (-1);
365 }
366 } else {
367 zcmd_free_nvlists(&zc);
368 return (-1);
369 }
370 }
371
372 err = zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &recvdprops);
373 zcmd_free_nvlists(&zc);
374 if (err != 0)
375 return (-1);
376
377 nvlist_free(zhp->zfs_recvd_props);
378 zhp->zfs_recvd_props = recvdprops;
379
380 return (0);
381 }
382
383 static int
384 put_stats_zhdl(zfs_handle_t *zhp, zfs_cmd_t *zc)
385 {
386 nvlist_t *allprops, *userprops;
387
388 zhp->zfs_dmustats = zc->zc_objset_stats; /* structure assignment */
389
390 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, zc, &allprops) != 0) {
391 return (-1);
392 }
393
394 /*
395 * XXX Why do we store the user props separately, in addition to
396 * storing them in zfs_props?
397 */
398 if ((userprops = process_user_props(zhp, allprops)) == NULL) {
399 nvlist_free(allprops);
400 return (-1);
401 }
402
403 nvlist_free(zhp->zfs_props);
404 nvlist_free(zhp->zfs_user_props);
405
406 zhp->zfs_props = allprops;
407 zhp->zfs_user_props = userprops;
408
409 return (0);
410 }
411
412 static int
413 get_stats(zfs_handle_t *zhp)
414 {
415 int rc = 0;
416 zfs_cmd_t zc = {"\0"};
417
418 if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
419 return (-1);
420 if (get_stats_ioctl(zhp, &zc) != 0)
421 rc = -1;
422 else if (put_stats_zhdl(zhp, &zc) != 0)
423 rc = -1;
424 zcmd_free_nvlists(&zc);
425 return (rc);
426 }
427
428 /*
429 * Refresh the properties currently stored in the handle.
430 */
431 void
432 zfs_refresh_properties(zfs_handle_t *zhp)
433 {
434 (void) get_stats(zhp);
435 }
436
437 /*
438 * Makes a handle from the given dataset name. Used by zfs_open() and
439 * zfs_iter_* to create child handles on the fly.
440 */
441 static int
442 make_dataset_handle_common(zfs_handle_t *zhp, zfs_cmd_t *zc)
443 {
444 if (put_stats_zhdl(zhp, zc) != 0)
445 return (-1);
446
447 /*
448 * We've managed to open the dataset and gather statistics. Determine
449 * the high-level type.
450 */
451 if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL) {
452 zhp->zfs_head_type = ZFS_TYPE_VOLUME;
453 } else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS) {
454 zhp->zfs_head_type = ZFS_TYPE_FILESYSTEM;
455 } else if (zhp->zfs_dmustats.dds_type == DMU_OST_OTHER) {
456 errno = EINVAL;
457 return (-1);
458 } else if (zhp->zfs_dmustats.dds_inconsistent) {
459 errno = EBUSY;
460 return (-1);
461 } else {
462 abort();
463 }
464
465 if (zhp->zfs_dmustats.dds_is_snapshot)
466 zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
467 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZVOL)
468 zhp->zfs_type = ZFS_TYPE_VOLUME;
469 else if (zhp->zfs_dmustats.dds_type == DMU_OST_ZFS)
470 zhp->zfs_type = ZFS_TYPE_FILESYSTEM;
471 else
472 abort(); /* we should never see any other types */
473
474 if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL)
475 return (-1);
476
477 return (0);
478 }
479
480 zfs_handle_t *
481 make_dataset_handle(libzfs_handle_t *hdl, const char *path)
482 {
483 zfs_cmd_t zc = {"\0"};
484
485 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
486
487 if (zhp == NULL)
488 return (NULL);
489
490 zhp->zfs_hdl = hdl;
491 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
492 if (zcmd_alloc_dst_nvlist(hdl, &zc, 0) != 0) {
493 free(zhp);
494 return (NULL);
495 }
496 if (get_stats_ioctl(zhp, &zc) == -1) {
497 zcmd_free_nvlists(&zc);
498 free(zhp);
499 return (NULL);
500 }
501 if (make_dataset_handle_common(zhp, &zc) == -1) {
502 free(zhp);
503 zhp = NULL;
504 }
505 zcmd_free_nvlists(&zc);
506 return (zhp);
507 }
508
509 zfs_handle_t *
510 make_dataset_handle_zc(libzfs_handle_t *hdl, zfs_cmd_t *zc)
511 {
512 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
513
514 if (zhp == NULL)
515 return (NULL);
516
517 zhp->zfs_hdl = hdl;
518 (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
519 if (make_dataset_handle_common(zhp, zc) == -1) {
520 free(zhp);
521 return (NULL);
522 }
523 return (zhp);
524 }
525
526 zfs_handle_t *
527 make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
528 {
529 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
530
531 if (zhp == NULL)
532 return (NULL);
533
534 zhp->zfs_hdl = pzhp->zfs_hdl;
535 (void) strlcpy(zhp->zfs_name, zc->zc_name, sizeof (zhp->zfs_name));
536 zhp->zfs_head_type = pzhp->zfs_type;
537 zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
538 zhp->zpool_hdl = zpool_handle(zhp);
539
540 return (zhp);
541 }
542
543 zfs_handle_t *
544 zfs_handle_dup(zfs_handle_t *zhp_orig)
545 {
546 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
547
548 if (zhp == NULL)
549 return (NULL);
550
551 zhp->zfs_hdl = zhp_orig->zfs_hdl;
552 zhp->zpool_hdl = zhp_orig->zpool_hdl;
553 (void) strlcpy(zhp->zfs_name, zhp_orig->zfs_name,
554 sizeof (zhp->zfs_name));
555 zhp->zfs_type = zhp_orig->zfs_type;
556 zhp->zfs_head_type = zhp_orig->zfs_head_type;
557 zhp->zfs_dmustats = zhp_orig->zfs_dmustats;
558 if (zhp_orig->zfs_props != NULL) {
559 if (nvlist_dup(zhp_orig->zfs_props, &zhp->zfs_props, 0) != 0) {
560 (void) no_memory(zhp->zfs_hdl);
561 zfs_close(zhp);
562 return (NULL);
563 }
564 }
565 if (zhp_orig->zfs_user_props != NULL) {
566 if (nvlist_dup(zhp_orig->zfs_user_props,
567 &zhp->zfs_user_props, 0) != 0) {
568 (void) no_memory(zhp->zfs_hdl);
569 zfs_close(zhp);
570 return (NULL);
571 }
572 }
573 if (zhp_orig->zfs_recvd_props != NULL) {
574 if (nvlist_dup(zhp_orig->zfs_recvd_props,
575 &zhp->zfs_recvd_props, 0)) {
576 (void) no_memory(zhp->zfs_hdl);
577 zfs_close(zhp);
578 return (NULL);
579 }
580 }
581 zhp->zfs_mntcheck = zhp_orig->zfs_mntcheck;
582 if (zhp_orig->zfs_mntopts != NULL) {
583 zhp->zfs_mntopts = zfs_strdup(zhp_orig->zfs_hdl,
584 zhp_orig->zfs_mntopts);
585 }
586 zhp->zfs_props_table = zhp_orig->zfs_props_table;
587 return (zhp);
588 }
589
590 boolean_t
591 zfs_bookmark_exists(const char *path)
592 {
593 nvlist_t *bmarks;
594 nvlist_t *props;
595 char fsname[ZFS_MAX_DATASET_NAME_LEN];
596 char *bmark_name;
597 char *pound;
598 int err;
599 boolean_t rv;
600
601 (void) strlcpy(fsname, path, sizeof (fsname));
602 pound = strchr(fsname, '#');
603 if (pound == NULL)
604 return (B_FALSE);
605
606 *pound = '\0';
607 bmark_name = pound + 1;
608 props = fnvlist_alloc();
609 err = lzc_get_bookmarks(fsname, props, &bmarks);
610 nvlist_free(props);
611 if (err != 0) {
612 nvlist_free(bmarks);
613 return (B_FALSE);
614 }
615
616 rv = nvlist_exists(bmarks, bmark_name);
617 nvlist_free(bmarks);
618 return (rv);
619 }
620
621 zfs_handle_t *
622 make_bookmark_handle(zfs_handle_t *parent, const char *path,
623 nvlist_t *bmark_props)
624 {
625 zfs_handle_t *zhp = calloc(1, sizeof (zfs_handle_t));
626
627 if (zhp == NULL)
628 return (NULL);
629
630 /* Fill in the name. */
631 zhp->zfs_hdl = parent->zfs_hdl;
632 (void) strlcpy(zhp->zfs_name, path, sizeof (zhp->zfs_name));
633
634 /* Set the property lists. */
635 if (nvlist_dup(bmark_props, &zhp->zfs_props, 0) != 0) {
636 free(zhp);
637 return (NULL);
638 }
639
640 /* Set the types. */
641 zhp->zfs_head_type = parent->zfs_head_type;
642 zhp->zfs_type = ZFS_TYPE_BOOKMARK;
643
644 if ((zhp->zpool_hdl = zpool_handle(zhp)) == NULL) {
645 nvlist_free(zhp->zfs_props);
646 free(zhp);
647 return (NULL);
648 }
649
650 return (zhp);
651 }
652
653 struct zfs_open_bookmarks_cb_data {
654 const char *path;
655 zfs_handle_t *zhp;
656 };
657
658 static int
659 zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data)
660 {
661 struct zfs_open_bookmarks_cb_data *dp = data;
662
663 /*
664 * Is it the one we are looking for?
665 */
666 if (strcmp(dp->path, zfs_get_name(zhp)) == 0) {
667 /*
668 * We found it. Save it and let the caller know we are done.
669 */
670 dp->zhp = zhp;
671 return (EEXIST);
672 }
673
674 /*
675 * Not found. Close the handle and ask for another one.
676 */
677 zfs_close(zhp);
678 return (0);
679 }
680
681 /*
682 * Opens the given snapshot, bookmark, filesystem, or volume. The 'types'
683 * argument is a mask of acceptable types. The function will print an
684 * appropriate error message and return NULL if it can't be opened.
685 */
686 zfs_handle_t *
687 zfs_open(libzfs_handle_t *hdl, const char *path, int types)
688 {
689 zfs_handle_t *zhp;
690 char errbuf[1024];
691 char *bookp;
692
693 (void) snprintf(errbuf, sizeof (errbuf),
694 dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
695
696 /*
697 * Validate the name before we even try to open it.
698 */
699 if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
700 (void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
701 return (NULL);
702 }
703
704 /*
705 * Bookmarks needs to be handled separately.
706 */
707 bookp = strchr(path, '#');
708 if (bookp == NULL) {
709 /*
710 * Try to get stats for the dataset, which will tell us if it
711 * exists.
712 */
713 errno = 0;
714 if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
715 (void) zfs_standard_error(hdl, errno, errbuf);
716 return (NULL);
717 }
718 } else {
719 char dsname[ZFS_MAX_DATASET_NAME_LEN];
720 zfs_handle_t *pzhp;
721 struct zfs_open_bookmarks_cb_data cb_data = {path, NULL};
722
723 /*
724 * We need to cut out '#' and everything after '#'
725 * to get the parent dataset name only.
726 */
727 assert(bookp - path < sizeof (dsname));
728 (void) strncpy(dsname, path, bookp - path);
729 dsname[bookp - path] = '\0';
730
731 /*
732 * Create handle for the parent dataset.
733 */
734 errno = 0;
735 if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) {
736 (void) zfs_standard_error(hdl, errno, errbuf);
737 return (NULL);
738 }
739
740 /*
741 * Iterate bookmarks to find the right one.
742 */
743 errno = 0;
744 if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb,
745 &cb_data) == 0) && (cb_data.zhp == NULL)) {
746 (void) zfs_error(hdl, EZFS_NOENT, errbuf);
747 zfs_close(pzhp);
748 return (NULL);
749 }
750 if (cb_data.zhp == NULL) {
751 (void) zfs_standard_error(hdl, errno, errbuf);
752 zfs_close(pzhp);
753 return (NULL);
754 }
755 zhp = cb_data.zhp;
756
757 /*
758 * Cleanup.
759 */
760 zfs_close(pzhp);
761 }
762
763 if (!(types & zhp->zfs_type)) {
764 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
765 zfs_close(zhp);
766 return (NULL);
767 }
768
769 return (zhp);
770 }
771
772 /*
773 * Release a ZFS handle. Nothing to do but free the associated memory.
774 */
775 void
776 zfs_close(zfs_handle_t *zhp)
777 {
778 if (zhp->zfs_mntopts)
779 free(zhp->zfs_mntopts);
780 nvlist_free(zhp->zfs_props);
781 nvlist_free(zhp->zfs_user_props);
782 nvlist_free(zhp->zfs_recvd_props);
783 free(zhp);
784 }
785
786 typedef struct mnttab_node {
787 struct mnttab mtn_mt;
788 avl_node_t mtn_node;
789 } mnttab_node_t;
790
791 static int
792 libzfs_mnttab_cache_compare(const void *arg1, const void *arg2)
793 {
794 const mnttab_node_t *mtn1 = (const mnttab_node_t *)arg1;
795 const mnttab_node_t *mtn2 = (const mnttab_node_t *)arg2;
796 int rv;
797
798 rv = strcmp(mtn1->mtn_mt.mnt_special, mtn2->mtn_mt.mnt_special);
799
800 return (TREE_ISIGN(rv));
801 }
802
803 void
804 libzfs_mnttab_init(libzfs_handle_t *hdl)
805 {
806 pthread_mutex_init(&hdl->libzfs_mnttab_cache_lock, NULL);
807 assert(avl_numnodes(&hdl->libzfs_mnttab_cache) == 0);
808 avl_create(&hdl->libzfs_mnttab_cache, libzfs_mnttab_cache_compare,
809 sizeof (mnttab_node_t), offsetof(mnttab_node_t, mtn_node));
810 }
811
812 static int
813 libzfs_mnttab_update(libzfs_handle_t *hdl)
814 {
815 FILE *mnttab;
816 struct mnttab entry;
817
818 if ((mnttab = fopen(MNTTAB, "re")) == NULL)
819 return (ENOENT);
820
821 while (getmntent(mnttab, &entry) == 0) {
822 mnttab_node_t *mtn;
823 avl_index_t where;
824
825 if (strcmp(entry.mnt_fstype, MNTTYPE_ZFS) != 0)
826 continue;
827
828 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
829 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, entry.mnt_special);
830 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, entry.mnt_mountp);
831 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, entry.mnt_fstype);
832 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, entry.mnt_mntopts);
833
834 /* Exclude duplicate mounts */
835 if (avl_find(&hdl->libzfs_mnttab_cache, mtn, &where) != NULL) {
836 free(mtn->mtn_mt.mnt_special);
837 free(mtn->mtn_mt.mnt_mountp);
838 free(mtn->mtn_mt.mnt_fstype);
839 free(mtn->mtn_mt.mnt_mntopts);
840 free(mtn);
841 continue;
842 }
843
844 avl_add(&hdl->libzfs_mnttab_cache, mtn);
845 }
846
847 (void) fclose(mnttab);
848 return (0);
849 }
850
851 void
852 libzfs_mnttab_fini(libzfs_handle_t *hdl)
853 {
854 void *cookie = NULL;
855 mnttab_node_t *mtn;
856
857 while ((mtn = avl_destroy_nodes(&hdl->libzfs_mnttab_cache, &cookie))
858 != NULL) {
859 free(mtn->mtn_mt.mnt_special);
860 free(mtn->mtn_mt.mnt_mountp);
861 free(mtn->mtn_mt.mnt_fstype);
862 free(mtn->mtn_mt.mnt_mntopts);
863 free(mtn);
864 }
865 avl_destroy(&hdl->libzfs_mnttab_cache);
866 (void) pthread_mutex_destroy(&hdl->libzfs_mnttab_cache_lock);
867 }
868
869 void
870 libzfs_mnttab_cache(libzfs_handle_t *hdl, boolean_t enable)
871 {
872 hdl->libzfs_mnttab_enable = enable;
873 }
874
875 int
876 libzfs_mnttab_find(libzfs_handle_t *hdl, const char *fsname,
877 struct mnttab *entry)
878 {
879 FILE *mnttab;
880 mnttab_node_t find;
881 mnttab_node_t *mtn;
882 int ret = ENOENT;
883
884 if (!hdl->libzfs_mnttab_enable) {
885 struct mnttab srch = { 0 };
886
887 if (avl_numnodes(&hdl->libzfs_mnttab_cache))
888 libzfs_mnttab_fini(hdl);
889
890 if ((mnttab = fopen(MNTTAB, "re")) == NULL)
891 return (ENOENT);
892
893 srch.mnt_special = (char *)fsname;
894 srch.mnt_fstype = MNTTYPE_ZFS;
895 ret = getmntany(mnttab, entry, &srch) ? ENOENT : 0;
896 (void) fclose(mnttab);
897 return (ret);
898 }
899
900 pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
901 if (avl_numnodes(&hdl->libzfs_mnttab_cache) == 0) {
902 int error;
903
904 if ((error = libzfs_mnttab_update(hdl)) != 0) {
905 pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
906 return (error);
907 }
908 }
909
910 find.mtn_mt.mnt_special = (char *)fsname;
911 mtn = avl_find(&hdl->libzfs_mnttab_cache, &find, NULL);
912 if (mtn) {
913 *entry = mtn->mtn_mt;
914 ret = 0;
915 }
916 pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
917 return (ret);
918 }
919
920 void
921 libzfs_mnttab_add(libzfs_handle_t *hdl, const char *special,
922 const char *mountp, const char *mntopts)
923 {
924 mnttab_node_t *mtn;
925
926 pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
927 if (avl_numnodes(&hdl->libzfs_mnttab_cache) != 0) {
928 mtn = zfs_alloc(hdl, sizeof (mnttab_node_t));
929 mtn->mtn_mt.mnt_special = zfs_strdup(hdl, special);
930 mtn->mtn_mt.mnt_mountp = zfs_strdup(hdl, mountp);
931 mtn->mtn_mt.mnt_fstype = zfs_strdup(hdl, MNTTYPE_ZFS);
932 mtn->mtn_mt.mnt_mntopts = zfs_strdup(hdl, mntopts);
933 /*
934 * Another thread may have already added this entry
935 * via libzfs_mnttab_update. If so we should skip it.
936 */
937 if (avl_find(&hdl->libzfs_mnttab_cache, mtn, NULL) != NULL) {
938 free(mtn->mtn_mt.mnt_special);
939 free(mtn->mtn_mt.mnt_mountp);
940 free(mtn->mtn_mt.mnt_fstype);
941 free(mtn->mtn_mt.mnt_mntopts);
942 free(mtn);
943 } else {
944 avl_add(&hdl->libzfs_mnttab_cache, mtn);
945 }
946 }
947 pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
948 }
949
950 void
951 libzfs_mnttab_remove(libzfs_handle_t *hdl, const char *fsname)
952 {
953 mnttab_node_t find;
954 mnttab_node_t *ret;
955
956 pthread_mutex_lock(&hdl->libzfs_mnttab_cache_lock);
957 find.mtn_mt.mnt_special = (char *)fsname;
958 if ((ret = avl_find(&hdl->libzfs_mnttab_cache, (void *)&find, NULL))
959 != NULL) {
960 avl_remove(&hdl->libzfs_mnttab_cache, ret);
961 free(ret->mtn_mt.mnt_special);
962 free(ret->mtn_mt.mnt_mountp);
963 free(ret->mtn_mt.mnt_fstype);
964 free(ret->mtn_mt.mnt_mntopts);
965 free(ret);
966 }
967 pthread_mutex_unlock(&hdl->libzfs_mnttab_cache_lock);
968 }
969
970 int
971 zfs_spa_version(zfs_handle_t *zhp, int *spa_version)
972 {
973 zpool_handle_t *zpool_handle = zhp->zpool_hdl;
974
975 if (zpool_handle == NULL)
976 return (-1);
977
978 *spa_version = zpool_get_prop_int(zpool_handle,
979 ZPOOL_PROP_VERSION, NULL);
980 return (0);
981 }
982
983 /*
984 * The choice of reservation property depends on the SPA version.
985 */
986 static int
987 zfs_which_resv_prop(zfs_handle_t *zhp, zfs_prop_t *resv_prop)
988 {
989 int spa_version;
990
991 if (zfs_spa_version(zhp, &spa_version) < 0)
992 return (-1);
993
994 if (spa_version >= SPA_VERSION_REFRESERVATION)
995 *resv_prop = ZFS_PROP_REFRESERVATION;
996 else
997 *resv_prop = ZFS_PROP_RESERVATION;
998
999 return (0);
1000 }
1001
1002 /*
1003 * Given an nvlist of properties to set, validates that they are correct, and
1004 * parses any numeric properties (index, boolean, etc) if they are specified as
1005 * strings.
1006 */
1007 nvlist_t *
1008 zfs_valid_proplist(libzfs_handle_t *hdl, zfs_type_t type, nvlist_t *nvl,
1009 uint64_t zoned, zfs_handle_t *zhp, zpool_handle_t *zpool_hdl,
1010 boolean_t key_params_ok, const char *errbuf)
1011 {
1012 nvpair_t *elem;
1013 uint64_t intval;
1014 char *strval;
1015 zfs_prop_t prop;
1016 nvlist_t *ret;
1017 int chosen_normal = -1;
1018 int chosen_utf = -1;
1019
1020 if (nvlist_alloc(&ret, NV_UNIQUE_NAME, 0) != 0) {
1021 (void) no_memory(hdl);
1022 return (NULL);
1023 }
1024
1025 /*
1026 * Make sure this property is valid and applies to this type.
1027 */
1028
1029 elem = NULL;
1030 while ((elem = nvlist_next_nvpair(nvl, elem)) != NULL) {
1031 const char *propname = nvpair_name(elem);
1032
1033 prop = zfs_name_to_prop(propname);
1034 if (prop == ZPROP_INVAL && zfs_prop_user(propname)) {
1035 /*
1036 * This is a user property: make sure it's a
1037 * string, and that it's less than ZAP_MAXNAMELEN.
1038 */
1039 if (nvpair_type(elem) != DATA_TYPE_STRING) {
1040 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1041 "'%s' must be a string"), propname);
1042 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1043 goto error;
1044 }
1045
1046 if (strlen(nvpair_name(elem)) >= ZAP_MAXNAMELEN) {
1047 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1048 "property name '%s' is too long"),
1049 propname);
1050 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1051 goto error;
1052 }
1053
1054 (void) nvpair_value_string(elem, &strval);
1055 if (nvlist_add_string(ret, propname, strval) != 0) {
1056 (void) no_memory(hdl);
1057 goto error;
1058 }
1059 continue;
1060 }
1061
1062 /*
1063 * Currently, only user properties can be modified on
1064 * snapshots.
1065 */
1066 if (type == ZFS_TYPE_SNAPSHOT) {
1067 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1068 "this property can not be modified for snapshots"));
1069 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
1070 goto error;
1071 }
1072
1073 if (prop == ZPROP_INVAL && zfs_prop_userquota(propname)) {
1074 zfs_userquota_prop_t uqtype;
1075 char *newpropname = NULL;
1076 char domain[128];
1077 uint64_t rid;
1078 uint64_t valary[3];
1079 int rc;
1080
1081 if (userquota_propname_decode(propname, zoned,
1082 &uqtype, domain, sizeof (domain), &rid) != 0) {
1083 zfs_error_aux(hdl,
1084 dgettext(TEXT_DOMAIN,
1085 "'%s' has an invalid user/group name"),
1086 propname);
1087 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1088 goto error;
1089 }
1090
1091 if (uqtype != ZFS_PROP_USERQUOTA &&
1092 uqtype != ZFS_PROP_GROUPQUOTA &&
1093 uqtype != ZFS_PROP_USEROBJQUOTA &&
1094 uqtype != ZFS_PROP_GROUPOBJQUOTA &&
1095 uqtype != ZFS_PROP_PROJECTQUOTA &&
1096 uqtype != ZFS_PROP_PROJECTOBJQUOTA) {
1097 zfs_error_aux(hdl,
1098 dgettext(TEXT_DOMAIN, "'%s' is readonly"),
1099 propname);
1100 (void) zfs_error(hdl, EZFS_PROPREADONLY,
1101 errbuf);
1102 goto error;
1103 }
1104
1105 if (nvpair_type(elem) == DATA_TYPE_STRING) {
1106 (void) nvpair_value_string(elem, &strval);
1107 if (strcmp(strval, "none") == 0) {
1108 intval = 0;
1109 } else if (zfs_nicestrtonum(hdl,
1110 strval, &intval) != 0) {
1111 (void) zfs_error(hdl,
1112 EZFS_BADPROP, errbuf);
1113 goto error;
1114 }
1115 } else if (nvpair_type(elem) ==
1116 DATA_TYPE_UINT64) {
1117 (void) nvpair_value_uint64(elem, &intval);
1118 if (intval == 0) {
1119 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1120 "use 'none' to disable "
1121 "{user|group|project}quota"));
1122 goto error;
1123 }
1124 } else {
1125 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1126 "'%s' must be a number"), propname);
1127 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1128 goto error;
1129 }
1130
1131 /*
1132 * Encode the prop name as
1133 * userquota@<hex-rid>-domain, to make it easy
1134 * for the kernel to decode.
1135 */
1136 rc = asprintf(&newpropname, "%s%llx-%s",
1137 zfs_userquota_prop_prefixes[uqtype],
1138 (longlong_t)rid, domain);
1139 if (rc == -1 || newpropname == NULL) {
1140 (void) no_memory(hdl);
1141 goto error;
1142 }
1143
1144 valary[0] = uqtype;
1145 valary[1] = rid;
1146 valary[2] = intval;
1147 if (nvlist_add_uint64_array(ret, newpropname,
1148 valary, 3) != 0) {
1149 free(newpropname);
1150 (void) no_memory(hdl);
1151 goto error;
1152 }
1153 free(newpropname);
1154 continue;
1155 } else if (prop == ZPROP_INVAL && zfs_prop_written(propname)) {
1156 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1157 "'%s' is readonly"),
1158 propname);
1159 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
1160 goto error;
1161 }
1162
1163 if (prop == ZPROP_INVAL) {
1164 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1165 "invalid property '%s'"), propname);
1166 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1167 goto error;
1168 }
1169
1170 if (!zfs_prop_valid_for_type(prop, type, B_FALSE)) {
1171 zfs_error_aux(hdl,
1172 dgettext(TEXT_DOMAIN, "'%s' does not "
1173 "apply to datasets of this type"), propname);
1174 (void) zfs_error(hdl, EZFS_PROPTYPE, errbuf);
1175 goto error;
1176 }
1177
1178 if (zfs_prop_readonly(prop) &&
1179 !(zfs_prop_setonce(prop) && zhp == NULL) &&
1180 !(zfs_prop_encryption_key_param(prop) && key_params_ok)) {
1181 zfs_error_aux(hdl,
1182 dgettext(TEXT_DOMAIN, "'%s' is readonly"),
1183 propname);
1184 (void) zfs_error(hdl, EZFS_PROPREADONLY, errbuf);
1185 goto error;
1186 }
1187
1188 if (zprop_parse_value(hdl, elem, prop, type, ret,
1189 &strval, &intval, errbuf) != 0)
1190 goto error;
1191
1192 /*
1193 * Perform some additional checks for specific properties.
1194 */
1195 switch (prop) {
1196 case ZFS_PROP_VERSION:
1197 {
1198 int version;
1199
1200 if (zhp == NULL)
1201 break;
1202 version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
1203 if (intval < version) {
1204 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1205 "Can not downgrade; already at version %u"),
1206 version);
1207 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1208 goto error;
1209 }
1210 break;
1211 }
1212
1213 case ZFS_PROP_VOLBLOCKSIZE:
1214 case ZFS_PROP_RECORDSIZE:
1215 {
1216 int maxbs = SPA_MAXBLOCKSIZE;
1217 char buf[64];
1218
1219 if (zpool_hdl != NULL) {
1220 maxbs = zpool_get_prop_int(zpool_hdl,
1221 ZPOOL_PROP_MAXBLOCKSIZE, NULL);
1222 }
1223 /*
1224 * The value must be a power of two between
1225 * SPA_MINBLOCKSIZE and maxbs.
1226 */
1227 if (intval < SPA_MINBLOCKSIZE ||
1228 intval > maxbs || !ISP2(intval)) {
1229 zfs_nicebytes(maxbs, buf, sizeof (buf));
1230 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1231 "'%s' must be power of 2 from 512B "
1232 "to %s"), propname, buf);
1233 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1234 goto error;
1235 }
1236 break;
1237 }
1238
1239 case ZFS_PROP_SPECIAL_SMALL_BLOCKS:
1240 {
1241 int maxbs = SPA_OLD_MAXBLOCKSIZE;
1242 char buf[64];
1243
1244 if (zpool_hdl != NULL) {
1245 char state[64] = "";
1246
1247 maxbs = zpool_get_prop_int(zpool_hdl,
1248 ZPOOL_PROP_MAXBLOCKSIZE, NULL);
1249
1250 /*
1251 * Issue a warning but do not fail so that
1252 * tests for settable properties succeed.
1253 */
1254 if (zpool_prop_get_feature(zpool_hdl,
1255 "feature@allocation_classes", state,
1256 sizeof (state)) != 0 ||
1257 strcmp(state, ZFS_FEATURE_ACTIVE) != 0) {
1258 (void) fprintf(stderr, gettext(
1259 "%s: property requires a special "
1260 "device in the pool\n"), propname);
1261 }
1262 }
1263 if (intval != 0 &&
1264 (intval < SPA_MINBLOCKSIZE ||
1265 intval > maxbs || !ISP2(intval))) {
1266 zfs_nicebytes(maxbs, buf, sizeof (buf));
1267 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1268 "invalid '%s=%llu' property: must be zero "
1269 "or a power of 2 from 512B to %s"),
1270 propname, (unsigned long long)intval, buf);
1271 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1272 goto error;
1273 }
1274 break;
1275 }
1276
1277 case ZFS_PROP_MLSLABEL:
1278 {
1279 #ifdef HAVE_MLSLABEL
1280 /*
1281 * Verify the mlslabel string and convert to
1282 * internal hex label string.
1283 */
1284
1285 m_label_t *new_sl;
1286 char *hex = NULL; /* internal label string */
1287
1288 /* Default value is already OK. */
1289 if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
1290 break;
1291
1292 /* Verify the label can be converted to binary form */
1293 if (((new_sl = m_label_alloc(MAC_LABEL)) == NULL) ||
1294 (str_to_label(strval, &new_sl, MAC_LABEL,
1295 L_NO_CORRECTION, NULL) == -1)) {
1296 goto badlabel;
1297 }
1298
1299 /* Now translate to hex internal label string */
1300 if (label_to_str(new_sl, &hex, M_INTERNAL,
1301 DEF_NAMES) != 0) {
1302 if (hex)
1303 free(hex);
1304 goto badlabel;
1305 }
1306 m_label_free(new_sl);
1307
1308 /* If string is already in internal form, we're done. */
1309 if (strcmp(strval, hex) == 0) {
1310 free(hex);
1311 break;
1312 }
1313
1314 /* Replace the label string with the internal form. */
1315 (void) nvlist_remove(ret, zfs_prop_to_name(prop),
1316 DATA_TYPE_STRING);
1317 fnvlist_add_string(ret, zfs_prop_to_name(prop), hex);
1318 free(hex);
1319
1320 break;
1321
1322 badlabel:
1323 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1324 "invalid mlslabel '%s'"), strval);
1325 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1326 m_label_free(new_sl); /* OK if null */
1327 goto error;
1328 #else
1329 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1330 "mlslabels are unsupported"));
1331 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1332 goto error;
1333 #endif /* HAVE_MLSLABEL */
1334 }
1335
1336 case ZFS_PROP_MOUNTPOINT:
1337 {
1338 namecheck_err_t why;
1339
1340 if (strcmp(strval, ZFS_MOUNTPOINT_NONE) == 0 ||
1341 strcmp(strval, ZFS_MOUNTPOINT_LEGACY) == 0)
1342 break;
1343
1344 if (mountpoint_namecheck(strval, &why)) {
1345 switch (why) {
1346 case NAME_ERR_LEADING_SLASH:
1347 zfs_error_aux(hdl,
1348 dgettext(TEXT_DOMAIN,
1349 "'%s' must be an absolute path, "
1350 "'none', or 'legacy'"), propname);
1351 break;
1352 case NAME_ERR_TOOLONG:
1353 zfs_error_aux(hdl,
1354 dgettext(TEXT_DOMAIN,
1355 "component of '%s' is too long"),
1356 propname);
1357 break;
1358
1359 default:
1360 zfs_error_aux(hdl,
1361 dgettext(TEXT_DOMAIN,
1362 "(%d) not defined"),
1363 why);
1364 break;
1365 }
1366 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1367 goto error;
1368 }
1369 zfs_fallthrough;
1370 }
1371
1372 case ZFS_PROP_SHARESMB:
1373 case ZFS_PROP_SHARENFS:
1374 /*
1375 * For the mountpoint and sharenfs or sharesmb
1376 * properties, check if it can be set in a
1377 * global/non-global zone based on
1378 * the zoned property value:
1379 *
1380 * global zone non-global zone
1381 * --------------------------------------------------
1382 * zoned=on mountpoint (no) mountpoint (yes)
1383 * sharenfs (no) sharenfs (no)
1384 * sharesmb (no) sharesmb (no)
1385 *
1386 * zoned=off mountpoint (yes) N/A
1387 * sharenfs (yes)
1388 * sharesmb (yes)
1389 */
1390 if (zoned) {
1391 if (getzoneid() == GLOBAL_ZONEID) {
1392 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1393 "'%s' cannot be set on "
1394 "dataset in a non-global zone"),
1395 propname);
1396 (void) zfs_error(hdl, EZFS_ZONED,
1397 errbuf);
1398 goto error;
1399 } else if (prop == ZFS_PROP_SHARENFS ||
1400 prop == ZFS_PROP_SHARESMB) {
1401 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1402 "'%s' cannot be set in "
1403 "a non-global zone"), propname);
1404 (void) zfs_error(hdl, EZFS_ZONED,
1405 errbuf);
1406 goto error;
1407 }
1408 } else if (getzoneid() != GLOBAL_ZONEID) {
1409 /*
1410 * If zoned property is 'off', this must be in
1411 * a global zone. If not, something is wrong.
1412 */
1413 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1414 "'%s' cannot be set while dataset "
1415 "'zoned' property is set"), propname);
1416 (void) zfs_error(hdl, EZFS_ZONED, errbuf);
1417 goto error;
1418 }
1419
1420 /*
1421 * At this point, it is legitimate to set the
1422 * property. Now we want to make sure that the
1423 * property value is valid if it is sharenfs.
1424 */
1425 if ((prop == ZFS_PROP_SHARENFS ||
1426 prop == ZFS_PROP_SHARESMB) &&
1427 strcmp(strval, "on") != 0 &&
1428 strcmp(strval, "off") != 0) {
1429 zfs_share_proto_t proto;
1430
1431 if (prop == ZFS_PROP_SHARESMB)
1432 proto = PROTO_SMB;
1433 else
1434 proto = PROTO_NFS;
1435
1436 if (zfs_parse_options(strval, proto) != SA_OK) {
1437 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1438 "'%s' cannot be set to invalid "
1439 "options"), propname);
1440 (void) zfs_error(hdl, EZFS_BADPROP,
1441 errbuf);
1442 goto error;
1443 }
1444 }
1445
1446 break;
1447
1448 case ZFS_PROP_KEYLOCATION:
1449 if (!zfs_prop_valid_keylocation(strval, B_FALSE)) {
1450 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1451 "invalid keylocation"));
1452 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1453 goto error;
1454 }
1455
1456 if (zhp != NULL) {
1457 uint64_t crypt =
1458 zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
1459
1460 if (crypt == ZIO_CRYPT_OFF &&
1461 strcmp(strval, "none") != 0) {
1462 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1463 "keylocation must be 'none' "
1464 "for unencrypted datasets"));
1465 (void) zfs_error(hdl, EZFS_BADPROP,
1466 errbuf);
1467 goto error;
1468 } else if (crypt != ZIO_CRYPT_OFF &&
1469 strcmp(strval, "none") == 0) {
1470 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1471 "keylocation must not be 'none' "
1472 "for encrypted datasets"));
1473 (void) zfs_error(hdl, EZFS_BADPROP,
1474 errbuf);
1475 goto error;
1476 }
1477 }
1478 break;
1479
1480 case ZFS_PROP_PBKDF2_ITERS:
1481 if (intval < MIN_PBKDF2_ITERATIONS) {
1482 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1483 "minimum pbkdf2 iterations is %u"),
1484 MIN_PBKDF2_ITERATIONS);
1485 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1486 goto error;
1487 }
1488 break;
1489
1490 case ZFS_PROP_UTF8ONLY:
1491 chosen_utf = (int)intval;
1492 break;
1493
1494 case ZFS_PROP_NORMALIZE:
1495 chosen_normal = (int)intval;
1496 break;
1497
1498 default:
1499 break;
1500 }
1501
1502 /*
1503 * For changes to existing volumes, we have some additional
1504 * checks to enforce.
1505 */
1506 if (type == ZFS_TYPE_VOLUME && zhp != NULL) {
1507 uint64_t blocksize = zfs_prop_get_int(zhp,
1508 ZFS_PROP_VOLBLOCKSIZE);
1509 char buf[64];
1510
1511 switch (prop) {
1512 case ZFS_PROP_VOLSIZE:
1513 if (intval % blocksize != 0) {
1514 zfs_nicebytes(blocksize, buf,
1515 sizeof (buf));
1516 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1517 "'%s' must be a multiple of "
1518 "volume block size (%s)"),
1519 propname, buf);
1520 (void) zfs_error(hdl, EZFS_BADPROP,
1521 errbuf);
1522 goto error;
1523 }
1524
1525 if (intval == 0) {
1526 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1527 "'%s' cannot be zero"),
1528 propname);
1529 (void) zfs_error(hdl, EZFS_BADPROP,
1530 errbuf);
1531 goto error;
1532 }
1533 break;
1534
1535 default:
1536 break;
1537 }
1538 }
1539
1540 /* check encryption properties */
1541 if (zhp != NULL) {
1542 int64_t crypt = zfs_prop_get_int(zhp,
1543 ZFS_PROP_ENCRYPTION);
1544
1545 switch (prop) {
1546 case ZFS_PROP_COPIES:
1547 if (crypt != ZIO_CRYPT_OFF && intval > 2) {
1548 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1549 "encrypted datasets cannot have "
1550 "3 copies"));
1551 (void) zfs_error(hdl, EZFS_BADPROP,
1552 errbuf);
1553 goto error;
1554 }
1555 break;
1556 default:
1557 break;
1558 }
1559 }
1560 }
1561
1562 /*
1563 * If normalization was chosen, but no UTF8 choice was made,
1564 * enforce rejection of non-UTF8 names.
1565 *
1566 * If normalization was chosen, but rejecting non-UTF8 names
1567 * was explicitly not chosen, it is an error.
1568 *
1569 * If utf8only was turned off, but the parent has normalization,
1570 * turn off normalization.
1571 */
1572 if (chosen_normal > 0 && chosen_utf < 0) {
1573 if (nvlist_add_uint64(ret,
1574 zfs_prop_to_name(ZFS_PROP_UTF8ONLY), 1) != 0) {
1575 (void) no_memory(hdl);
1576 goto error;
1577 }
1578 } else if (chosen_normal > 0 && chosen_utf == 0) {
1579 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1580 "'%s' must be set 'on' if normalization chosen"),
1581 zfs_prop_to_name(ZFS_PROP_UTF8ONLY));
1582 (void) zfs_error(hdl, EZFS_BADPROP, errbuf);
1583 goto error;
1584 } else if (chosen_normal < 0 && chosen_utf == 0) {
1585 if (nvlist_add_uint64(ret,
1586 zfs_prop_to_name(ZFS_PROP_NORMALIZE), 0) != 0) {
1587 (void) no_memory(hdl);
1588 goto error;
1589 }
1590 }
1591 return (ret);
1592
1593 error:
1594 nvlist_free(ret);
1595 return (NULL);
1596 }
1597
1598 static int
1599 zfs_add_synthetic_resv(zfs_handle_t *zhp, nvlist_t *nvl)
1600 {
1601 uint64_t old_volsize;
1602 uint64_t new_volsize;
1603 uint64_t old_reservation;
1604 uint64_t new_reservation;
1605 zfs_prop_t resv_prop;
1606 nvlist_t *props;
1607 zpool_handle_t *zph = zpool_handle(zhp);
1608
1609 /*
1610 * If this is an existing volume, and someone is setting the volsize,
1611 * make sure that it matches the reservation, or add it if necessary.
1612 */
1613 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
1614 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
1615 return (-1);
1616 old_reservation = zfs_prop_get_int(zhp, resv_prop);
1617
1618 props = fnvlist_alloc();
1619 fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
1620 zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
1621
1622 if ((zvol_volsize_to_reservation(zph, old_volsize, props) !=
1623 old_reservation) || nvlist_exists(nvl,
1624 zfs_prop_to_name(resv_prop))) {
1625 fnvlist_free(props);
1626 return (0);
1627 }
1628 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1629 &new_volsize) != 0) {
1630 fnvlist_free(props);
1631 return (-1);
1632 }
1633 new_reservation = zvol_volsize_to_reservation(zph, new_volsize, props);
1634 fnvlist_free(props);
1635
1636 if (nvlist_add_uint64(nvl, zfs_prop_to_name(resv_prop),
1637 new_reservation) != 0) {
1638 (void) no_memory(zhp->zfs_hdl);
1639 return (-1);
1640 }
1641 return (1);
1642 }
1643
1644 /*
1645 * Helper for 'zfs {set|clone} refreservation=auto'. Must be called after
1646 * zfs_valid_proplist(), as it is what sets the UINT64_MAX sentinel value.
1647 * Return codes must match zfs_add_synthetic_resv().
1648 */
1649 static int
1650 zfs_fix_auto_resv(zfs_handle_t *zhp, nvlist_t *nvl)
1651 {
1652 uint64_t volsize;
1653 uint64_t resvsize;
1654 zfs_prop_t prop;
1655 nvlist_t *props;
1656
1657 if (!ZFS_IS_VOLUME(zhp)) {
1658 return (0);
1659 }
1660
1661 if (zfs_which_resv_prop(zhp, &prop) != 0) {
1662 return (-1);
1663 }
1664
1665 if (prop != ZFS_PROP_REFRESERVATION) {
1666 return (0);
1667 }
1668
1669 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(prop), &resvsize) != 0) {
1670 /* No value being set, so it can't be "auto" */
1671 return (0);
1672 }
1673 if (resvsize != UINT64_MAX) {
1674 /* Being set to a value other than "auto" */
1675 return (0);
1676 }
1677
1678 props = fnvlist_alloc();
1679
1680 fnvlist_add_uint64(props, zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
1681 zfs_prop_get_int(zhp, ZFS_PROP_VOLBLOCKSIZE));
1682
1683 if (nvlist_lookup_uint64(nvl, zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1684 &volsize) != 0) {
1685 volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
1686 }
1687
1688 resvsize = zvol_volsize_to_reservation(zpool_handle(zhp), volsize,
1689 props);
1690 fnvlist_free(props);
1691
1692 (void) nvlist_remove_all(nvl, zfs_prop_to_name(prop));
1693 if (nvlist_add_uint64(nvl, zfs_prop_to_name(prop), resvsize) != 0) {
1694 (void) no_memory(zhp->zfs_hdl);
1695 return (-1);
1696 }
1697 return (1);
1698 }
1699
1700 static boolean_t
1701 zfs_is_namespace_prop(zfs_prop_t prop)
1702 {
1703 switch (prop) {
1704
1705 case ZFS_PROP_ATIME:
1706 case ZFS_PROP_RELATIME:
1707 case ZFS_PROP_DEVICES:
1708 case ZFS_PROP_EXEC:
1709 case ZFS_PROP_SETUID:
1710 case ZFS_PROP_READONLY:
1711 case ZFS_PROP_XATTR:
1712 case ZFS_PROP_NBMAND:
1713 return (B_TRUE);
1714
1715 default:
1716 return (B_FALSE);
1717 }
1718 }
1719
1720 /*
1721 * Given a property name and value, set the property for the given dataset.
1722 */
1723 int
1724 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1725 {
1726 int ret = -1;
1727 char errbuf[1024];
1728 libzfs_handle_t *hdl = zhp->zfs_hdl;
1729 nvlist_t *nvl = NULL;
1730
1731 (void) snprintf(errbuf, sizeof (errbuf),
1732 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1733 zhp->zfs_name);
1734
1735 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1736 nvlist_add_string(nvl, propname, propval) != 0) {
1737 (void) no_memory(hdl);
1738 goto error;
1739 }
1740
1741 ret = zfs_prop_set_list(zhp, nvl);
1742
1743 error:
1744 nvlist_free(nvl);
1745 return (ret);
1746 }
1747
1748
1749
1750 /*
1751 * Given an nvlist of property names and values, set the properties for the
1752 * given dataset.
1753 */
1754 int
1755 zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
1756 {
1757 zfs_cmd_t zc = {"\0"};
1758 int ret = -1;
1759 prop_changelist_t **cls = NULL;
1760 int cl_idx;
1761 char errbuf[1024];
1762 libzfs_handle_t *hdl = zhp->zfs_hdl;
1763 nvlist_t *nvl;
1764 int nvl_len = 0;
1765 int added_resv = 0;
1766 zfs_prop_t prop = 0;
1767 nvpair_t *elem;
1768
1769 (void) snprintf(errbuf, sizeof (errbuf),
1770 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1771 zhp->zfs_name);
1772
1773 if ((nvl = zfs_valid_proplist(hdl, zhp->zfs_type, props,
1774 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, zhp->zpool_hdl,
1775 B_FALSE, errbuf)) == NULL)
1776 goto error;
1777
1778 /*
1779 * We have to check for any extra properties which need to be added
1780 * before computing the length of the nvlist.
1781 */
1782 for (elem = nvlist_next_nvpair(nvl, NULL);
1783 elem != NULL;
1784 elem = nvlist_next_nvpair(nvl, elem)) {
1785 if (zfs_name_to_prop(nvpair_name(elem)) == ZFS_PROP_VOLSIZE &&
1786 (added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1) {
1787 goto error;
1788 }
1789 }
1790
1791 if (added_resv != 1 &&
1792 (added_resv = zfs_fix_auto_resv(zhp, nvl)) == -1) {
1793 goto error;
1794 }
1795
1796 /*
1797 * Check how many properties we're setting and allocate an array to
1798 * store changelist pointers for postfix().
1799 */
1800 for (elem = nvlist_next_nvpair(nvl, NULL);
1801 elem != NULL;
1802 elem = nvlist_next_nvpair(nvl, elem))
1803 nvl_len++;
1804 if ((cls = calloc(nvl_len, sizeof (prop_changelist_t *))) == NULL)
1805 goto error;
1806
1807 cl_idx = 0;
1808 for (elem = nvlist_next_nvpair(nvl, NULL);
1809 elem != NULL;
1810 elem = nvlist_next_nvpair(nvl, elem)) {
1811
1812 prop = zfs_name_to_prop(nvpair_name(elem));
1813
1814 assert(cl_idx < nvl_len);
1815 /*
1816 * We don't want to unmount & remount the dataset when changing
1817 * its canmount property to 'on' or 'noauto'. We only use
1818 * the changelist logic to unmount when setting canmount=off.
1819 */
1820 if (prop != ZFS_PROP_CANMOUNT ||
1821 (fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
1822 zfs_is_mounted(zhp, NULL))) {
1823 cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
1824 if (cls[cl_idx] == NULL)
1825 goto error;
1826 }
1827
1828 if (prop == ZFS_PROP_MOUNTPOINT &&
1829 changelist_haszonedchild(cls[cl_idx])) {
1830 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1831 "child dataset with inherited mountpoint is used "
1832 "in a non-global zone"));
1833 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1834 goto error;
1835 }
1836
1837 if (cls[cl_idx] != NULL &&
1838 (ret = changelist_prefix(cls[cl_idx])) != 0)
1839 goto error;
1840
1841 cl_idx++;
1842 }
1843 assert(cl_idx == nvl_len);
1844
1845 /*
1846 * Execute the corresponding ioctl() to set this list of properties.
1847 */
1848 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1849
1850 if ((ret = zcmd_write_src_nvlist(hdl, &zc, nvl)) != 0 ||
1851 (ret = zcmd_alloc_dst_nvlist(hdl, &zc, 0)) != 0)
1852 goto error;
1853
1854 ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1855
1856 if (ret != 0) {
1857 if (zc.zc_nvlist_dst_filled == B_FALSE) {
1858 (void) zfs_standard_error(hdl, errno, errbuf);
1859 goto error;
1860 }
1861
1862 /* Get the list of unset properties back and report them. */
1863 nvlist_t *errorprops = NULL;
1864 if (zcmd_read_dst_nvlist(hdl, &zc, &errorprops) != 0)
1865 goto error;
1866 for (nvpair_t *elem = nvlist_next_nvpair(errorprops, NULL);
1867 elem != NULL;
1868 elem = nvlist_next_nvpair(errorprops, elem)) {
1869 prop = zfs_name_to_prop(nvpair_name(elem));
1870 zfs_setprop_error(hdl, prop, errno, errbuf);
1871 }
1872 nvlist_free(errorprops);
1873
1874 if (added_resv && errno == ENOSPC) {
1875 /* clean up the volsize property we tried to set */
1876 uint64_t old_volsize = zfs_prop_get_int(zhp,
1877 ZFS_PROP_VOLSIZE);
1878 nvlist_free(nvl);
1879 nvl = NULL;
1880 zcmd_free_nvlists(&zc);
1881
1882 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0)
1883 goto error;
1884 if (nvlist_add_uint64(nvl,
1885 zfs_prop_to_name(ZFS_PROP_VOLSIZE),
1886 old_volsize) != 0)
1887 goto error;
1888 if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1889 goto error;
1890 (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1891 }
1892 } else {
1893 for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
1894 if (cls[cl_idx] != NULL) {
1895 int clp_err = changelist_postfix(cls[cl_idx]);
1896 if (clp_err != 0)
1897 ret = clp_err;
1898 }
1899 }
1900
1901 if (ret == 0) {
1902 /*
1903 * Refresh the statistics so the new property
1904 * value is reflected.
1905 */
1906 (void) get_stats(zhp);
1907
1908 /*
1909 * Remount the filesystem to propagate the change
1910 * if one of the options handled by the generic
1911 * Linux namespace layer has been modified.
1912 */
1913 if (zfs_is_namespace_prop(prop) &&
1914 zfs_is_mounted(zhp, NULL))
1915 ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
1916 }
1917 }
1918
1919 error:
1920 nvlist_free(nvl);
1921 zcmd_free_nvlists(&zc);
1922 if (cls != NULL) {
1923 for (cl_idx = 0; cl_idx < nvl_len; cl_idx++) {
1924 if (cls[cl_idx] != NULL)
1925 changelist_free(cls[cl_idx]);
1926 }
1927 free(cls);
1928 }
1929 return (ret);
1930 }
1931
1932 /*
1933 * Given a property, inherit the value from the parent dataset, or if received
1934 * is TRUE, revert to the received value, if any.
1935 */
1936 int
1937 zfs_prop_inherit(zfs_handle_t *zhp, const char *propname, boolean_t received)
1938 {
1939 zfs_cmd_t zc = {"\0"};
1940 int ret;
1941 prop_changelist_t *cl;
1942 libzfs_handle_t *hdl = zhp->zfs_hdl;
1943 char errbuf[1024];
1944 zfs_prop_t prop;
1945
1946 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1947 "cannot inherit %s for '%s'"), propname, zhp->zfs_name);
1948
1949 zc.zc_cookie = received;
1950 if ((prop = zfs_name_to_prop(propname)) == ZPROP_INVAL) {
1951 /*
1952 * For user properties, the amount of work we have to do is very
1953 * small, so just do it here.
1954 */
1955 if (!zfs_prop_user(propname)) {
1956 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1957 "invalid property"));
1958 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
1959 }
1960
1961 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1962 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1963
1964 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc) != 0)
1965 return (zfs_standard_error(hdl, errno, errbuf));
1966
1967 (void) get_stats(zhp);
1968 return (0);
1969 }
1970
1971 /*
1972 * Verify that this property is inheritable.
1973 */
1974 if (zfs_prop_readonly(prop))
1975 return (zfs_error(hdl, EZFS_PROPREADONLY, errbuf));
1976
1977 if (!zfs_prop_inheritable(prop) && !received)
1978 return (zfs_error(hdl, EZFS_PROPNONINHERIT, errbuf));
1979
1980 /*
1981 * Check to see if the value applies to this type
1982 */
1983 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
1984 return (zfs_error(hdl, EZFS_PROPTYPE, errbuf));
1985
1986 /*
1987 * Normalize the name, to get rid of shorthand abbreviations.
1988 */
1989 propname = zfs_prop_to_name(prop);
1990 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1991 (void) strlcpy(zc.zc_value, propname, sizeof (zc.zc_value));
1992
1993 if (prop == ZFS_PROP_MOUNTPOINT && getzoneid() == GLOBAL_ZONEID &&
1994 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
1995 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1996 "dataset is used in a non-global zone"));
1997 return (zfs_error(hdl, EZFS_ZONED, errbuf));
1998 }
1999
2000 /*
2001 * Determine datasets which will be affected by this change, if any.
2002 */
2003 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
2004 return (-1);
2005
2006 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
2007 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2008 "child dataset with inherited mountpoint is used "
2009 "in a non-global zone"));
2010 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
2011 goto error;
2012 }
2013
2014 if ((ret = changelist_prefix(cl)) != 0)
2015 goto error;
2016
2017 if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_INHERIT_PROP, &zc)) != 0) {
2018 return (zfs_standard_error(hdl, errno, errbuf));
2019 } else {
2020
2021 if ((ret = changelist_postfix(cl)) != 0)
2022 goto error;
2023
2024 /*
2025 * Refresh the statistics so the new property is reflected.
2026 */
2027 (void) get_stats(zhp);
2028
2029 /*
2030 * Remount the filesystem to propagate the change
2031 * if one of the options handled by the generic
2032 * Linux namespace layer has been modified.
2033 */
2034 if (zfs_is_namespace_prop(prop) &&
2035 zfs_is_mounted(zhp, NULL))
2036 ret = zfs_mount(zhp, MNTOPT_REMOUNT, 0);
2037 }
2038
2039 error:
2040 changelist_free(cl);
2041 return (ret);
2042 }
2043
2044 /*
2045 * True DSL properties are stored in an nvlist. The following two functions
2046 * extract them appropriately.
2047 */
2048 uint64_t
2049 getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2050 {
2051 nvlist_t *nv;
2052 uint64_t value;
2053
2054 *source = NULL;
2055 if (nvlist_lookup_nvlist(zhp->zfs_props,
2056 zfs_prop_to_name(prop), &nv) == 0) {
2057 value = fnvlist_lookup_uint64(nv, ZPROP_VALUE);
2058 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2059 } else {
2060 verify(!zhp->zfs_props_table ||
2061 zhp->zfs_props_table[prop] == B_TRUE);
2062 value = zfs_prop_default_numeric(prop);
2063 *source = "";
2064 }
2065
2066 return (value);
2067 }
2068
2069 static const char *
2070 getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source)
2071 {
2072 nvlist_t *nv;
2073 const char *value;
2074
2075 *source = NULL;
2076 if (nvlist_lookup_nvlist(zhp->zfs_props,
2077 zfs_prop_to_name(prop), &nv) == 0) {
2078 value = fnvlist_lookup_string(nv, ZPROP_VALUE);
2079 (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source);
2080 } else {
2081 verify(!zhp->zfs_props_table ||
2082 zhp->zfs_props_table[prop] == B_TRUE);
2083 value = zfs_prop_default_string(prop);
2084 *source = "";
2085 }
2086
2087 return (value);
2088 }
2089
2090 static boolean_t
2091 zfs_is_recvd_props_mode(zfs_handle_t *zhp)
2092 {
2093 return (zhp->zfs_props == zhp->zfs_recvd_props);
2094 }
2095
2096 static void
2097 zfs_set_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
2098 {
2099 *cookie = (uint64_t)(uintptr_t)zhp->zfs_props;
2100 zhp->zfs_props = zhp->zfs_recvd_props;
2101 }
2102
2103 static void
2104 zfs_unset_recvd_props_mode(zfs_handle_t *zhp, uint64_t *cookie)
2105 {
2106 zhp->zfs_props = (nvlist_t *)(uintptr_t)*cookie;
2107 *cookie = 0;
2108 }
2109
2110 /*
2111 * Internal function for getting a numeric property. Both zfs_prop_get() and
2112 * zfs_prop_get_int() are built using this interface.
2113 *
2114 * Certain properties can be overridden using 'mount -o'. In this case, scan
2115 * the contents of the /proc/self/mounts entry, searching for the
2116 * appropriate options. If they differ from the on-disk values, report the
2117 * current values and mark the source "temporary".
2118 */
2119 static int
2120 get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
2121 char **source, uint64_t *val)
2122 {
2123 zfs_cmd_t zc = {"\0"};
2124 nvlist_t *zplprops = NULL;
2125 struct mnttab mnt;
2126 char *mntopt_on = NULL;
2127 char *mntopt_off = NULL;
2128 boolean_t received = zfs_is_recvd_props_mode(zhp);
2129
2130 *source = NULL;
2131
2132 /*
2133 * If the property is being fetched for a snapshot, check whether
2134 * the property is valid for the snapshot's head dataset type.
2135 */
2136 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT &&
2137 !zfs_prop_valid_for_type(prop, zhp->zfs_head_type, B_TRUE)) {
2138 *val = zfs_prop_default_numeric(prop);
2139 return (-1);
2140 }
2141
2142 switch (prop) {
2143 case ZFS_PROP_ATIME:
2144 mntopt_on = MNTOPT_ATIME;
2145 mntopt_off = MNTOPT_NOATIME;
2146 break;
2147
2148 case ZFS_PROP_RELATIME:
2149 mntopt_on = MNTOPT_RELATIME;
2150 mntopt_off = MNTOPT_NORELATIME;
2151 break;
2152
2153 case ZFS_PROP_DEVICES:
2154 mntopt_on = MNTOPT_DEVICES;
2155 mntopt_off = MNTOPT_NODEVICES;
2156 break;
2157
2158 case ZFS_PROP_EXEC:
2159 mntopt_on = MNTOPT_EXEC;
2160 mntopt_off = MNTOPT_NOEXEC;
2161 break;
2162
2163 case ZFS_PROP_READONLY:
2164 mntopt_on = MNTOPT_RO;
2165 mntopt_off = MNTOPT_RW;
2166 break;
2167
2168 case ZFS_PROP_SETUID:
2169 mntopt_on = MNTOPT_SETUID;
2170 mntopt_off = MNTOPT_NOSETUID;
2171 break;
2172
2173 case ZFS_PROP_XATTR:
2174 mntopt_on = MNTOPT_XATTR;
2175 mntopt_off = MNTOPT_NOXATTR;
2176 break;
2177
2178 case ZFS_PROP_NBMAND:
2179 mntopt_on = MNTOPT_NBMAND;
2180 mntopt_off = MNTOPT_NONBMAND;
2181 break;
2182
2183 default:
2184 break;
2185 }
2186
2187 /*
2188 * Because looking up the mount options is potentially expensive
2189 * (iterating over all of /proc/self/mounts), we defer its
2190 * calculation until we're looking up a property which requires
2191 * its presence.
2192 */
2193 if (!zhp->zfs_mntcheck &&
2194 (mntopt_on != NULL || prop == ZFS_PROP_MOUNTED)) {
2195 libzfs_handle_t *hdl = zhp->zfs_hdl;
2196 struct mnttab entry;
2197
2198 if (libzfs_mnttab_find(hdl, zhp->zfs_name, &entry) == 0) {
2199 zhp->zfs_mntopts = zfs_strdup(hdl,
2200 entry.mnt_mntopts);
2201 if (zhp->zfs_mntopts == NULL)
2202 return (-1);
2203 }
2204
2205 zhp->zfs_mntcheck = B_TRUE;
2206 }
2207
2208 if (zhp->zfs_mntopts == NULL)
2209 mnt.mnt_mntopts = "";
2210 else
2211 mnt.mnt_mntopts = zhp->zfs_mntopts;
2212
2213 switch (prop) {
2214 case ZFS_PROP_ATIME:
2215 case ZFS_PROP_RELATIME:
2216 case ZFS_PROP_DEVICES:
2217 case ZFS_PROP_EXEC:
2218 case ZFS_PROP_READONLY:
2219 case ZFS_PROP_SETUID:
2220 #ifndef __FreeBSD__
2221 case ZFS_PROP_XATTR:
2222 #endif
2223 case ZFS_PROP_NBMAND:
2224 *val = getprop_uint64(zhp, prop, source);
2225
2226 if (received)
2227 break;
2228
2229 if (hasmntopt(&mnt, mntopt_on) && !*val) {
2230 *val = B_TRUE;
2231 if (src)
2232 *src = ZPROP_SRC_TEMPORARY;
2233 } else if (hasmntopt(&mnt, mntopt_off) && *val) {
2234 *val = B_FALSE;
2235 if (src)
2236 *src = ZPROP_SRC_TEMPORARY;
2237 }
2238 break;
2239
2240 case ZFS_PROP_CANMOUNT:
2241 case ZFS_PROP_VOLSIZE:
2242 case ZFS_PROP_QUOTA:
2243 case ZFS_PROP_REFQUOTA:
2244 case ZFS_PROP_RESERVATION:
2245 case ZFS_PROP_REFRESERVATION:
2246 case ZFS_PROP_FILESYSTEM_LIMIT:
2247 case ZFS_PROP_SNAPSHOT_LIMIT:
2248 case ZFS_PROP_FILESYSTEM_COUNT:
2249 case ZFS_PROP_SNAPSHOT_COUNT:
2250 *val = getprop_uint64(zhp, prop, source);
2251
2252 if (*source == NULL) {
2253 /* not default, must be local */
2254 *source = zhp->zfs_name;
2255 }
2256 break;
2257
2258 case ZFS_PROP_MOUNTED:
2259 *val = (zhp->zfs_mntopts != NULL);
2260 break;
2261
2262 case ZFS_PROP_NUMCLONES:
2263 *val = zhp->zfs_dmustats.dds_num_clones;
2264 break;
2265
2266 case ZFS_PROP_VERSION:
2267 case ZFS_PROP_NORMALIZE:
2268 case ZFS_PROP_UTF8ONLY:
2269 case ZFS_PROP_CASE:
2270 if (zcmd_alloc_dst_nvlist(zhp->zfs_hdl, &zc, 0) != 0)
2271 return (-1);
2272 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
2273 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_OBJSET_ZPLPROPS, &zc)) {
2274 zcmd_free_nvlists(&zc);
2275 if (prop == ZFS_PROP_VERSION &&
2276 zhp->zfs_type == ZFS_TYPE_VOLUME)
2277 *val = zfs_prop_default_numeric(prop);
2278 return (-1);
2279 }
2280 if (zcmd_read_dst_nvlist(zhp->zfs_hdl, &zc, &zplprops) != 0 ||
2281 nvlist_lookup_uint64(zplprops, zfs_prop_to_name(prop),
2282 val) != 0) {
2283 zcmd_free_nvlists(&zc);
2284 return (-1);
2285 }
2286 nvlist_free(zplprops);
2287 zcmd_free_nvlists(&zc);
2288 break;
2289
2290 case ZFS_PROP_INCONSISTENT:
2291 *val = zhp->zfs_dmustats.dds_inconsistent;
2292 break;
2293
2294 case ZFS_PROP_REDACTED:
2295 *val = zhp->zfs_dmustats.dds_redacted;
2296 break;
2297
2298 default:
2299 switch (zfs_prop_get_type(prop)) {
2300 case PROP_TYPE_NUMBER:
2301 case PROP_TYPE_INDEX:
2302 *val = getprop_uint64(zhp, prop, source);
2303 /*
2304 * If we tried to use a default value for a
2305 * readonly property, it means that it was not
2306 * present. Note this only applies to "truly"
2307 * readonly properties, not set-once properties
2308 * like volblocksize.
2309 */
2310 if (zfs_prop_readonly(prop) &&
2311 !zfs_prop_setonce(prop) &&
2312 *source != NULL && (*source)[0] == '\0') {
2313 *source = NULL;
2314 return (-1);
2315 }
2316 break;
2317
2318 case PROP_TYPE_STRING:
2319 default:
2320 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
2321 "cannot get non-numeric property"));
2322 return (zfs_error(zhp->zfs_hdl, EZFS_BADPROP,
2323 dgettext(TEXT_DOMAIN, "internal error")));
2324 }
2325 }
2326
2327 return (0);
2328 }
2329
2330 /*
2331 * Calculate the source type, given the raw source string.
2332 */
2333 static void
2334 get_source(zfs_handle_t *zhp, zprop_source_t *srctype, char *source,
2335 char *statbuf, size_t statlen)
2336 {
2337 if (statbuf == NULL ||
2338 srctype == NULL || *srctype == ZPROP_SRC_TEMPORARY) {
2339 return;
2340 }
2341
2342 if (source == NULL) {
2343 *srctype = ZPROP_SRC_NONE;
2344 } else if (source[0] == '\0') {
2345 *srctype = ZPROP_SRC_DEFAULT;
2346 } else if (strstr(source, ZPROP_SOURCE_VAL_RECVD) != NULL) {
2347 *srctype = ZPROP_SRC_RECEIVED;
2348 } else {
2349 if (strcmp(source, zhp->zfs_name) == 0) {
2350 *srctype = ZPROP_SRC_LOCAL;
2351 } else {
2352 (void) strlcpy(statbuf, source, statlen);
2353 *srctype = ZPROP_SRC_INHERITED;
2354 }
2355 }
2356
2357 }
2358
2359 int
2360 zfs_prop_get_recvd(zfs_handle_t *zhp, const char *propname, char *propbuf,
2361 size_t proplen, boolean_t literal)
2362 {
2363 zfs_prop_t prop;
2364 int err = 0;
2365
2366 if (zhp->zfs_recvd_props == NULL)
2367 if (get_recvd_props_ioctl(zhp) != 0)
2368 return (-1);
2369
2370 prop = zfs_name_to_prop(propname);
2371
2372 if (prop != ZPROP_INVAL) {
2373 uint64_t cookie;
2374 if (!nvlist_exists(zhp->zfs_recvd_props, propname))
2375 return (-1);
2376 zfs_set_recvd_props_mode(zhp, &cookie);
2377 err = zfs_prop_get(zhp, prop, propbuf, proplen,
2378 NULL, NULL, 0, literal);
2379 zfs_unset_recvd_props_mode(zhp, &cookie);
2380 } else {
2381 nvlist_t *propval;
2382 char *recvdval;
2383 if (nvlist_lookup_nvlist(zhp->zfs_recvd_props,
2384 propname, &propval) != 0)
2385 return (-1);
2386 recvdval = fnvlist_lookup_string(propval, ZPROP_VALUE);
2387 (void) strlcpy(propbuf, recvdval, proplen);
2388 }
2389
2390 return (err == 0 ? 0 : -1);
2391 }
2392
2393 static int
2394 get_clones_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
2395 {
2396 nvlist_t *value;
2397 nvpair_t *pair;
2398
2399 value = zfs_get_clones_nvl(zhp);
2400 if (value == NULL || nvlist_empty(value))
2401 return (-1);
2402
2403 propbuf[0] = '\0';
2404 for (pair = nvlist_next_nvpair(value, NULL); pair != NULL;
2405 pair = nvlist_next_nvpair(value, pair)) {
2406 if (propbuf[0] != '\0')
2407 (void) strlcat(propbuf, ",", proplen);
2408 (void) strlcat(propbuf, nvpair_name(pair), proplen);
2409 }
2410
2411 return (0);
2412 }
2413
2414 struct get_clones_arg {
2415 uint64_t numclones;
2416 nvlist_t *value;
2417 const char *origin;
2418 char buf[ZFS_MAX_DATASET_NAME_LEN];
2419 };
2420
2421 static int
2422 get_clones_cb(zfs_handle_t *zhp, void *arg)
2423 {
2424 struct get_clones_arg *gca = arg;
2425
2426 if (gca->numclones == 0) {
2427 zfs_close(zhp);
2428 return (0);
2429 }
2430
2431 if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, gca->buf, sizeof (gca->buf),
2432 NULL, NULL, 0, B_TRUE) != 0)
2433 goto out;
2434 if (strcmp(gca->buf, gca->origin) == 0) {
2435 fnvlist_add_boolean(gca->value, zfs_get_name(zhp));
2436 gca->numclones--;
2437 }
2438
2439 out:
2440 (void) zfs_iter_children(zhp, get_clones_cb, gca);
2441 zfs_close(zhp);
2442 return (0);
2443 }
2444
2445 nvlist_t *
2446 zfs_get_clones_nvl(zfs_handle_t *zhp)
2447 {
2448 nvlist_t *nv, *value;
2449
2450 if (nvlist_lookup_nvlist(zhp->zfs_props,
2451 zfs_prop_to_name(ZFS_PROP_CLONES), &nv) != 0) {
2452 struct get_clones_arg gca;
2453
2454 /*
2455 * if this is a snapshot, then the kernel wasn't able
2456 * to get the clones. Do it by slowly iterating.
2457 */
2458 if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT)
2459 return (NULL);
2460 if (nvlist_alloc(&nv, NV_UNIQUE_NAME, 0) != 0)
2461 return (NULL);
2462 if (nvlist_alloc(&value, NV_UNIQUE_NAME, 0) != 0) {
2463 nvlist_free(nv);
2464 return (NULL);
2465 }
2466
2467 gca.numclones = zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES);
2468 gca.value = value;
2469 gca.origin = zhp->zfs_name;
2470
2471 if (gca.numclones != 0) {
2472 zfs_handle_t *root;
2473 char pool[ZFS_MAX_DATASET_NAME_LEN];
2474 char *cp = pool;
2475
2476 /* get the pool name */
2477 (void) strlcpy(pool, zhp->zfs_name, sizeof (pool));
2478 (void) strsep(&cp, "/@");
2479 root = zfs_open(zhp->zfs_hdl, pool,
2480 ZFS_TYPE_FILESYSTEM);
2481 if (root == NULL) {
2482 nvlist_free(nv);
2483 nvlist_free(value);
2484 return (NULL);
2485 }
2486
2487 (void) get_clones_cb(root, &gca);
2488 }
2489
2490 if (gca.numclones != 0 ||
2491 nvlist_add_nvlist(nv, ZPROP_VALUE, value) != 0 ||
2492 nvlist_add_nvlist(zhp->zfs_props,
2493 zfs_prop_to_name(ZFS_PROP_CLONES), nv) != 0) {
2494 nvlist_free(nv);
2495 nvlist_free(value);
2496 return (NULL);
2497 }
2498 nvlist_free(nv);
2499 nvlist_free(value);
2500 nv = fnvlist_lookup_nvlist(zhp->zfs_props,
2501 zfs_prop_to_name(ZFS_PROP_CLONES));
2502 }
2503
2504 return (fnvlist_lookup_nvlist(nv, ZPROP_VALUE));
2505 }
2506
2507 static int
2508 get_rsnaps_string(zfs_handle_t *zhp, char *propbuf, size_t proplen)
2509 {
2510 nvlist_t *value;
2511 uint64_t *snaps;
2512 uint_t nsnaps;
2513
2514 if (nvlist_lookup_nvlist(zhp->zfs_props,
2515 zfs_prop_to_name(ZFS_PROP_REDACT_SNAPS), &value) != 0)
2516 return (-1);
2517 if (nvlist_lookup_uint64_array(value, ZPROP_VALUE, &snaps,
2518 &nsnaps) != 0)
2519 return (-1);
2520 if (nsnaps == 0) {
2521 /* There's no redaction snapshots; pass a special value back */
2522 (void) snprintf(propbuf, proplen, "none");
2523 return (0);
2524 }
2525 propbuf[0] = '\0';
2526 for (int i = 0; i < nsnaps; i++) {
2527 char buf[128];
2528 if (propbuf[0] != '\0')
2529 (void) strlcat(propbuf, ",", proplen);
2530 (void) snprintf(buf, sizeof (buf), "%llu",
2531 (u_longlong_t)snaps[i]);
2532 (void) strlcat(propbuf, buf, proplen);
2533 }
2534
2535 return (0);
2536 }
2537
2538 /*
2539 * Accepts a property and value and checks that the value
2540 * matches the one found by the channel program. If they are
2541 * not equal, print both of them.
2542 */
2543 static void
2544 zcp_check(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t intval,
2545 const char *strval)
2546 {
2547 if (!zhp->zfs_hdl->libzfs_prop_debug)
2548 return;
2549 int error;
2550 char *poolname = zhp->zpool_hdl->zpool_name;
2551 const char *prop_name = zfs_prop_to_name(prop);
2552 const char *program =
2553 "args = ...\n"
2554 "ds = args['dataset']\n"
2555 "prop = args['property']\n"
2556 "value, setpoint = zfs.get_prop(ds, prop)\n"
2557 "return {value=value, setpoint=setpoint}\n";
2558 nvlist_t *outnvl;
2559 nvlist_t *retnvl;
2560 nvlist_t *argnvl = fnvlist_alloc();
2561
2562 fnvlist_add_string(argnvl, "dataset", zhp->zfs_name);
2563 fnvlist_add_string(argnvl, "property", zfs_prop_to_name(prop));
2564
2565 error = lzc_channel_program_nosync(poolname, program,
2566 10 * 1000 * 1000, 10 * 1024 * 1024, argnvl, &outnvl);
2567
2568 if (error == 0) {
2569 retnvl = fnvlist_lookup_nvlist(outnvl, "return");
2570 if (zfs_prop_get_type(prop) == PROP_TYPE_NUMBER) {
2571 int64_t ans;
2572 error = nvlist_lookup_int64(retnvl, "value", &ans);
2573 if (error != 0) {
2574 (void) fprintf(stderr, "%s: zcp check error: "
2575 "%u\n", prop_name, error);
2576 return;
2577 }
2578 if (ans != intval) {
2579 (void) fprintf(stderr, "%s: zfs found %llu, "
2580 "but zcp found %llu\n", prop_name,
2581 (u_longlong_t)intval, (u_longlong_t)ans);
2582 }
2583 } else {
2584 char *str_ans;
2585 error = nvlist_lookup_string(retnvl, "value", &str_ans);
2586 if (error != 0) {
2587 (void) fprintf(stderr, "%s: zcp check error: "
2588 "%u\n", prop_name, error);
2589 return;
2590 }
2591 if (strcmp(strval, str_ans) != 0) {
2592 (void) fprintf(stderr,
2593 "%s: zfs found '%s', but zcp found '%s'\n",
2594 prop_name, strval, str_ans);
2595 }
2596 }
2597 } else {
2598 (void) fprintf(stderr, "%s: zcp check failed, channel program "
2599 "error: %u\n", prop_name, error);
2600 }
2601 nvlist_free(argnvl);
2602 nvlist_free(outnvl);
2603 }
2604
2605 /*
2606 * Retrieve a property from the given object. If 'literal' is specified, then
2607 * numbers are left as exact values. Otherwise, numbers are converted to a
2608 * human-readable form.
2609 *
2610 * Returns 0 on success, or -1 on error.
2611 */
2612 int
2613 zfs_prop_get(zfs_handle_t *zhp, zfs_prop_t prop, char *propbuf, size_t proplen,
2614 zprop_source_t *src, char *statbuf, size_t statlen, boolean_t literal)
2615 {
2616 char *source = NULL;
2617 uint64_t val;
2618 const char *str;
2619 const char *strval;
2620 boolean_t received = zfs_is_recvd_props_mode(zhp);
2621
2622 /*
2623 * Check to see if this property applies to our object
2624 */
2625 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE))
2626 return (-1);
2627
2628 if (received && zfs_prop_readonly(prop))
2629 return (-1);
2630
2631 if (src)
2632 *src = ZPROP_SRC_NONE;
2633
2634 switch (prop) {
2635 case ZFS_PROP_CREATION:
2636 /*
2637 * 'creation' is a time_t stored in the statistics. We convert
2638 * this into a string unless 'literal' is specified.
2639 */
2640 {
2641 val = getprop_uint64(zhp, prop, &source);
2642 time_t time = (time_t)val;
2643 struct tm t;
2644
2645 if (literal ||
2646 localtime_r(&time, &t) == NULL ||
2647 strftime(propbuf, proplen, "%a %b %e %k:%M %Y",
2648 &t) == 0)
2649 (void) snprintf(propbuf, proplen, "%llu",
2650 (u_longlong_t)val);
2651 }
2652 zcp_check(zhp, prop, val, NULL);
2653 break;
2654
2655 case ZFS_PROP_MOUNTPOINT:
2656 /*
2657 * Getting the precise mountpoint can be tricky.
2658 *
2659 * - for 'none' or 'legacy', return those values.
2660 * - for inherited mountpoints, we want to take everything
2661 * after our ancestor and append it to the inherited value.
2662 *
2663 * If the pool has an alternate root, we want to prepend that
2664 * root to any values we return.
2665 */
2666
2667 str = getprop_string(zhp, prop, &source);
2668
2669 if (str[0] == '/') {
2670 char buf[MAXPATHLEN];
2671 char *root = buf;
2672 const char *relpath;
2673
2674 /*
2675 * If we inherit the mountpoint, even from a dataset
2676 * with a received value, the source will be the path of
2677 * the dataset we inherit from. If source is
2678 * ZPROP_SOURCE_VAL_RECVD, the received value is not
2679 * inherited.
2680 */
2681 if (strcmp(source, ZPROP_SOURCE_VAL_RECVD) == 0) {
2682 relpath = "";
2683 } else {
2684 relpath = zhp->zfs_name + strlen(source);
2685 if (relpath[0] == '/')
2686 relpath++;
2687 }
2688
2689 if ((zpool_get_prop(zhp->zpool_hdl,
2690 ZPOOL_PROP_ALTROOT, buf, MAXPATHLEN, NULL,
2691 B_FALSE)) || (strcmp(root, "-") == 0))
2692 root[0] = '\0';
2693 /*
2694 * Special case an alternate root of '/'. This will
2695 * avoid having multiple leading slashes in the
2696 * mountpoint path.
2697 */
2698 if (strcmp(root, "/") == 0)
2699 root++;
2700
2701 /*
2702 * If the mountpoint is '/' then skip over this
2703 * if we are obtaining either an alternate root or
2704 * an inherited mountpoint.
2705 */
2706 if (str[1] == '\0' && (root[0] != '\0' ||
2707 relpath[0] != '\0'))
2708 str++;
2709
2710 if (relpath[0] == '\0')
2711 (void) snprintf(propbuf, proplen, "%s%s",
2712 root, str);
2713 else
2714 (void) snprintf(propbuf, proplen, "%s%s%s%s",
2715 root, str, relpath[0] == '@' ? "" : "/",
2716 relpath);
2717 } else {
2718 /* 'legacy' or 'none' */
2719 (void) strlcpy(propbuf, str, proplen);
2720 }
2721 zcp_check(zhp, prop, 0, propbuf);
2722 break;
2723
2724 case ZFS_PROP_ORIGIN:
2725 str = getprop_string(zhp, prop, &source);
2726 if (str == NULL)
2727 return (-1);
2728 (void) strlcpy(propbuf, str, proplen);
2729 zcp_check(zhp, prop, 0, str);
2730 break;
2731
2732 case ZFS_PROP_REDACT_SNAPS:
2733 if (get_rsnaps_string(zhp, propbuf, proplen) != 0)
2734 return (-1);
2735 break;
2736
2737 case ZFS_PROP_CLONES:
2738 if (get_clones_string(zhp, propbuf, proplen) != 0)
2739 return (-1);
2740 break;
2741
2742 case ZFS_PROP_QUOTA:
2743 case ZFS_PROP_REFQUOTA:
2744 case ZFS_PROP_RESERVATION:
2745 case ZFS_PROP_REFRESERVATION:
2746
2747 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2748 return (-1);
2749 /*
2750 * If quota or reservation is 0, we translate this into 'none'
2751 * (unless literal is set), and indicate that it's the default
2752 * value. Otherwise, we print the number nicely and indicate
2753 * that its set locally.
2754 */
2755 if (val == 0) {
2756 if (literal)
2757 (void) strlcpy(propbuf, "0", proplen);
2758 else
2759 (void) strlcpy(propbuf, "none", proplen);
2760 } else {
2761 if (literal)
2762 (void) snprintf(propbuf, proplen, "%llu",
2763 (u_longlong_t)val);
2764 else
2765 zfs_nicebytes(val, propbuf, proplen);
2766 }
2767 zcp_check(zhp, prop, val, NULL);
2768 break;
2769
2770 case ZFS_PROP_FILESYSTEM_LIMIT:
2771 case ZFS_PROP_SNAPSHOT_LIMIT:
2772 case ZFS_PROP_FILESYSTEM_COUNT:
2773 case ZFS_PROP_SNAPSHOT_COUNT:
2774
2775 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2776 return (-1);
2777
2778 /*
2779 * If limit is UINT64_MAX, we translate this into 'none', and
2780 * indicate that it's the default value. Otherwise, we print
2781 * the number nicely and indicate that it's set locally.
2782 */
2783 if (val == UINT64_MAX) {
2784 (void) strlcpy(propbuf, "none", proplen);
2785 } else if (literal) {
2786 (void) snprintf(propbuf, proplen, "%llu",
2787 (u_longlong_t)val);
2788 } else {
2789 zfs_nicenum(val, propbuf, proplen);
2790 }
2791
2792 zcp_check(zhp, prop, val, NULL);
2793 break;
2794
2795 case ZFS_PROP_REFRATIO:
2796 case ZFS_PROP_COMPRESSRATIO:
2797 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2798 return (-1);
2799 if (literal)
2800 (void) snprintf(propbuf, proplen, "%llu.%02llu",
2801 (u_longlong_t)(val / 100),
2802 (u_longlong_t)(val % 100));
2803 else
2804 (void) snprintf(propbuf, proplen, "%llu.%02llux",
2805 (u_longlong_t)(val / 100),
2806 (u_longlong_t)(val % 100));
2807 zcp_check(zhp, prop, val, NULL);
2808 break;
2809
2810 case ZFS_PROP_TYPE:
2811 switch (zhp->zfs_type) {
2812 case ZFS_TYPE_FILESYSTEM:
2813 str = "filesystem";
2814 break;
2815 case ZFS_TYPE_VOLUME:
2816 str = "volume";
2817 break;
2818 case ZFS_TYPE_SNAPSHOT:
2819 str = "snapshot";
2820 break;
2821 case ZFS_TYPE_BOOKMARK:
2822 str = "bookmark";
2823 break;
2824 default:
2825 abort();
2826 }
2827 (void) snprintf(propbuf, proplen, "%s", str);
2828 zcp_check(zhp, prop, 0, propbuf);
2829 break;
2830
2831 case ZFS_PROP_MOUNTED:
2832 /*
2833 * The 'mounted' property is a pseudo-property that described
2834 * whether the filesystem is currently mounted. Even though
2835 * it's a boolean value, the typical values of "on" and "off"
2836 * don't make sense, so we translate to "yes" and "no".
2837 */
2838 if (get_numeric_property(zhp, ZFS_PROP_MOUNTED,
2839 src, &source, &val) != 0)
2840 return (-1);
2841 if (val)
2842 (void) strlcpy(propbuf, "yes", proplen);
2843 else
2844 (void) strlcpy(propbuf, "no", proplen);
2845 break;
2846
2847 case ZFS_PROP_NAME:
2848 /*
2849 * The 'name' property is a pseudo-property derived from the
2850 * dataset name. It is presented as a real property to simplify
2851 * consumers.
2852 */
2853 (void) strlcpy(propbuf, zhp->zfs_name, proplen);
2854 zcp_check(zhp, prop, 0, propbuf);
2855 break;
2856
2857 case ZFS_PROP_MLSLABEL:
2858 {
2859 #ifdef HAVE_MLSLABEL
2860 m_label_t *new_sl = NULL;
2861 char *ascii = NULL; /* human readable label */
2862
2863 (void) strlcpy(propbuf,
2864 getprop_string(zhp, prop, &source), proplen);
2865
2866 if (literal || (strcasecmp(propbuf,
2867 ZFS_MLSLABEL_DEFAULT) == 0))
2868 break;
2869
2870 /*
2871 * Try to translate the internal hex string to
2872 * human-readable output. If there are any
2873 * problems just use the hex string.
2874 */
2875
2876 if (str_to_label(propbuf, &new_sl, MAC_LABEL,
2877 L_NO_CORRECTION, NULL) == -1) {
2878 m_label_free(new_sl);
2879 break;
2880 }
2881
2882 if (label_to_str(new_sl, &ascii, M_LABEL,
2883 DEF_NAMES) != 0) {
2884 if (ascii)
2885 free(ascii);
2886 m_label_free(new_sl);
2887 break;
2888 }
2889 m_label_free(new_sl);
2890
2891 (void) strlcpy(propbuf, ascii, proplen);
2892 free(ascii);
2893 #else
2894 (void) strlcpy(propbuf,
2895 getprop_string(zhp, prop, &source), proplen);
2896 #endif /* HAVE_MLSLABEL */
2897 }
2898 break;
2899
2900 case ZFS_PROP_GUID:
2901 case ZFS_PROP_KEY_GUID:
2902 case ZFS_PROP_IVSET_GUID:
2903 case ZFS_PROP_CREATETXG:
2904 case ZFS_PROP_OBJSETID:
2905 case ZFS_PROP_PBKDF2_ITERS:
2906 /*
2907 * These properties are stored as numbers, but they are
2908 * identifiers or counters.
2909 * We don't want them to be pretty printed, because pretty
2910 * printing truncates their values making them useless.
2911 */
2912 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2913 return (-1);
2914 (void) snprintf(propbuf, proplen, "%llu", (u_longlong_t)val);
2915 zcp_check(zhp, prop, val, NULL);
2916 break;
2917
2918 case ZFS_PROP_REFERENCED:
2919 case ZFS_PROP_AVAILABLE:
2920 case ZFS_PROP_USED:
2921 case ZFS_PROP_USEDSNAP:
2922 case ZFS_PROP_USEDDS:
2923 case ZFS_PROP_USEDREFRESERV:
2924 case ZFS_PROP_USEDCHILD:
2925 if (get_numeric_property(zhp, prop, src, &source, &val) != 0)
2926 return (-1);
2927 if (literal) {
2928 (void) snprintf(propbuf, proplen, "%llu",
2929 (u_longlong_t)val);
2930 } else {
2931 zfs_nicebytes(val, propbuf, proplen);
2932 }
2933 zcp_check(zhp, prop, val, NULL);
2934 break;
2935
2936 default:
2937 switch (zfs_prop_get_type(prop)) {
2938 case PROP_TYPE_NUMBER:
2939 if (get_numeric_property(zhp, prop, src,
2940 &source, &val) != 0) {
2941 return (-1);
2942 }
2943
2944 if (literal) {
2945 (void) snprintf(propbuf, proplen, "%llu",
2946 (u_longlong_t)val);
2947 } else {
2948 zfs_nicenum(val, propbuf, proplen);
2949 }
2950 zcp_check(zhp, prop, val, NULL);
2951 break;
2952
2953 case PROP_TYPE_STRING:
2954 str = getprop_string(zhp, prop, &source);
2955 if (str == NULL)
2956 return (-1);
2957
2958 (void) strlcpy(propbuf, str, proplen);
2959 zcp_check(zhp, prop, 0, str);
2960 break;
2961
2962 case PROP_TYPE_INDEX:
2963 if (get_numeric_property(zhp, prop, src,
2964 &source, &val) != 0)
2965 return (-1);
2966 if (zfs_prop_index_to_string(prop, val, &strval) != 0)
2967 return (-1);
2968
2969 (void) strlcpy(propbuf, strval, proplen);
2970 zcp_check(zhp, prop, 0, strval);
2971 break;
2972
2973 default:
2974 abort();
2975 }
2976 }
2977
2978 get_source(zhp, src, source, statbuf, statlen);
2979
2980 return (0);
2981 }
2982
2983 /*
2984 * Utility function to get the given numeric property. Does no validation that
2985 * the given property is the appropriate type; should only be used with
2986 * hard-coded property types.
2987 */
2988 uint64_t
2989 zfs_prop_get_int(zfs_handle_t *zhp, zfs_prop_t prop)
2990 {
2991 char *source;
2992 uint64_t val = 0;
2993
2994 (void) get_numeric_property(zhp, prop, NULL, &source, &val);
2995
2996 return (val);
2997 }
2998
2999 static int
3000 zfs_prop_set_int(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t val)
3001 {
3002 char buf[64];
3003
3004 (void) snprintf(buf, sizeof (buf), "%llu", (longlong_t)val);
3005 return (zfs_prop_set(zhp, zfs_prop_to_name(prop), buf));
3006 }
3007
3008 /*
3009 * Similar to zfs_prop_get(), but returns the value as an integer.
3010 */
3011 int
3012 zfs_prop_get_numeric(zfs_handle_t *zhp, zfs_prop_t prop, uint64_t *value,
3013 zprop_source_t *src, char *statbuf, size_t statlen)
3014 {
3015 char *source;
3016
3017 /*
3018 * Check to see if this property applies to our object
3019 */
3020 if (!zfs_prop_valid_for_type(prop, zhp->zfs_type, B_FALSE)) {
3021 return (zfs_error_fmt(zhp->zfs_hdl, EZFS_PROPTYPE,
3022 dgettext(TEXT_DOMAIN, "cannot get property '%s'"),
3023 zfs_prop_to_name(prop)));
3024 }
3025
3026 if (src)
3027 *src = ZPROP_SRC_NONE;
3028
3029 if (get_numeric_property(zhp, prop, src, &source, value) != 0)
3030 return (-1);
3031
3032 get_source(zhp, src, source, statbuf, statlen);
3033
3034 return (0);
3035 }
3036
3037 #ifdef HAVE_IDMAP
3038 static int
3039 idmap_id_to_numeric_domain_rid(uid_t id, boolean_t isuser,
3040 char **domainp, idmap_rid_t *ridp)
3041 {
3042 idmap_get_handle_t *get_hdl = NULL;
3043 idmap_stat status;
3044 int err = EINVAL;
3045
3046 if (idmap_get_create(&get_hdl) != IDMAP_SUCCESS)
3047 goto out;
3048
3049 if (isuser) {
3050 err = idmap_get_sidbyuid(get_hdl, id,
3051 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
3052 } else {
3053 err = idmap_get_sidbygid(get_hdl, id,
3054 IDMAP_REQ_FLG_USE_CACHE, domainp, ridp, &status);
3055 }
3056 if (err == IDMAP_SUCCESS &&
3057 idmap_get_mappings(get_hdl) == IDMAP_SUCCESS &&
3058 status == IDMAP_SUCCESS)
3059 err = 0;
3060 else
3061 err = EINVAL;
3062 out:
3063 if (get_hdl)
3064 idmap_get_destroy(get_hdl);
3065 return (err);
3066 }
3067 #endif /* HAVE_IDMAP */
3068
3069 /*
3070 * convert the propname into parameters needed by kernel
3071 * Eg: userquota@ahrens -> ZFS_PROP_USERQUOTA, "", 126829
3072 * Eg: userused@matt@domain -> ZFS_PROP_USERUSED, "S-1-123-456", 789
3073 * Eg: groupquota@staff -> ZFS_PROP_GROUPQUOTA, "", 1234
3074 * Eg: groupused@staff -> ZFS_PROP_GROUPUSED, "", 1234
3075 * Eg: projectquota@123 -> ZFS_PROP_PROJECTQUOTA, "", 123
3076 * Eg: projectused@789 -> ZFS_PROP_PROJECTUSED, "", 789
3077 */
3078 static int
3079 userquota_propname_decode(const char *propname, boolean_t zoned,
3080 zfs_userquota_prop_t *typep, char *domain, int domainlen, uint64_t *ridp)
3081 {
3082 zfs_userquota_prop_t type;
3083 char *cp;
3084 boolean_t isuser;
3085 boolean_t isgroup;
3086 boolean_t isproject;
3087 struct passwd *pw;
3088 struct group *gr;
3089
3090 domain[0] = '\0';
3091
3092 /* Figure out the property type ({user|group|project}{quota|space}) */
3093 for (type = 0; type < ZFS_NUM_USERQUOTA_PROPS; type++) {
3094 if (strncmp(propname, zfs_userquota_prop_prefixes[type],
3095 strlen(zfs_userquota_prop_prefixes[type])) == 0)
3096 break;
3097 }
3098 if (type == ZFS_NUM_USERQUOTA_PROPS)
3099 return (EINVAL);
3100 *typep = type;
3101
3102 isuser = (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_USERUSED ||
3103 type == ZFS_PROP_USEROBJQUOTA ||
3104 type == ZFS_PROP_USEROBJUSED);
3105 isgroup = (type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_GROUPUSED ||
3106 type == ZFS_PROP_GROUPOBJQUOTA ||
3107 type == ZFS_PROP_GROUPOBJUSED);
3108 isproject = (type == ZFS_PROP_PROJECTQUOTA ||
3109 type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTOBJQUOTA ||
3110 type == ZFS_PROP_PROJECTOBJUSED);
3111
3112 cp = strchr(propname, '@') + 1;
3113
3114 if (isuser && (pw = getpwnam(cp)) != NULL) {
3115 if (zoned && getzoneid() == GLOBAL_ZONEID)
3116 return (ENOENT);
3117 *ridp = pw->pw_uid;
3118 } else if (isgroup && (gr = getgrnam(cp)) != NULL) {
3119 if (zoned && getzoneid() == GLOBAL_ZONEID)
3120 return (ENOENT);
3121 *ridp = gr->gr_gid;
3122 } else if (!isproject && strchr(cp, '@')) {
3123 #ifdef HAVE_IDMAP
3124 /*
3125 * It's a SID name (eg "user@domain") that needs to be
3126 * turned into S-1-domainID-RID.
3127 */
3128 directory_error_t e;
3129 char *numericsid = NULL;
3130 char *end;
3131
3132 if (zoned && getzoneid() == GLOBAL_ZONEID)
3133 return (ENOENT);
3134 if (isuser) {
3135 e = directory_sid_from_user_name(NULL,
3136 cp, &numericsid);
3137 } else {
3138 e = directory_sid_from_group_name(NULL,
3139 cp, &numericsid);
3140 }
3141 if (e != NULL) {
3142 directory_error_free(e);
3143 return (ENOENT);
3144 }
3145 if (numericsid == NULL)
3146 return (ENOENT);
3147 cp = numericsid;
3148 (void) strlcpy(domain, cp, domainlen);
3149 cp = strrchr(domain, '-');
3150 *cp = '\0';
3151 cp++;
3152
3153 errno = 0;
3154 *ridp = strtoull(cp, &end, 10);
3155 free(numericsid);
3156
3157 if (errno != 0 || *end != '\0')
3158 return (EINVAL);
3159 #else
3160 (void) domainlen;
3161 return (ENOSYS);
3162 #endif /* HAVE_IDMAP */
3163 } else {
3164 /* It's a user/group/project ID (eg "12345"). */
3165 uid_t id;
3166 char *end;
3167 id = strtoul(cp, &end, 10);
3168 if (*end != '\0')
3169 return (EINVAL);
3170 if (id > MAXUID && !isproject) {
3171 #ifdef HAVE_IDMAP
3172 /* It's an ephemeral ID. */
3173 idmap_rid_t rid;
3174 char *mapdomain;
3175
3176 if (idmap_id_to_numeric_domain_rid(id, isuser,
3177 &mapdomain, &rid) != 0)
3178 return (ENOENT);
3179 (void) strlcpy(domain, mapdomain, domainlen);
3180 *ridp = rid;
3181 #else
3182 return (ENOSYS);
3183 #endif /* HAVE_IDMAP */
3184 } else {
3185 *ridp = id;
3186 }
3187 }
3188
3189 return (0);
3190 }
3191
3192 static int
3193 zfs_prop_get_userquota_common(zfs_handle_t *zhp, const char *propname,
3194 uint64_t *propvalue, zfs_userquota_prop_t *typep)
3195 {
3196 int err;
3197 zfs_cmd_t zc = {"\0"};
3198
3199 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3200
3201 err = userquota_propname_decode(propname,
3202 zfs_prop_get_int(zhp, ZFS_PROP_ZONED),
3203 typep, zc.zc_value, sizeof (zc.zc_value), &zc.zc_guid);
3204 zc.zc_objset_type = *typep;
3205 if (err)
3206 return (err);
3207
3208 err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_USERSPACE_ONE, &zc);
3209 if (err)
3210 return (err);
3211
3212 *propvalue = zc.zc_cookie;
3213 return (0);
3214 }
3215
3216 int
3217 zfs_prop_get_userquota_int(zfs_handle_t *zhp, const char *propname,
3218 uint64_t *propvalue)
3219 {
3220 zfs_userquota_prop_t type;
3221
3222 return (zfs_prop_get_userquota_common(zhp, propname, propvalue,
3223 &type));
3224 }
3225
3226 int
3227 zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname,
3228 char *propbuf, int proplen, boolean_t literal)
3229 {
3230 int err;
3231 uint64_t propvalue;
3232 zfs_userquota_prop_t type;
3233
3234 err = zfs_prop_get_userquota_common(zhp, propname, &propvalue,
3235 &type);
3236
3237 if (err)
3238 return (err);
3239
3240 if (literal) {
3241 (void) snprintf(propbuf, proplen, "%llu",
3242 (u_longlong_t)propvalue);
3243 } else if (propvalue == 0 &&
3244 (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3245 type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA ||
3246 type == ZFS_PROP_PROJECTQUOTA ||
3247 type == ZFS_PROP_PROJECTOBJQUOTA)) {
3248 (void) strlcpy(propbuf, "none", proplen);
3249 } else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA ||
3250 type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED ||
3251 type == ZFS_PROP_PROJECTUSED || type == ZFS_PROP_PROJECTQUOTA) {
3252 zfs_nicebytes(propvalue, propbuf, proplen);
3253 } else {
3254 zfs_nicenum(propvalue, propbuf, proplen);
3255 }
3256 return (0);
3257 }
3258
3259 /*
3260 * propname must start with "written@" or "written#".
3261 */
3262 int
3263 zfs_prop_get_written_int(zfs_handle_t *zhp, const char *propname,
3264 uint64_t *propvalue)
3265 {
3266 int err;
3267 zfs_cmd_t zc = {"\0"};
3268 const char *snapname;
3269
3270 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3271
3272 assert(zfs_prop_written(propname));
3273 snapname = propname + strlen("written@");
3274 if (strchr(snapname, '@') != NULL || strchr(snapname, '#') != NULL) {
3275 /* full snapshot or bookmark name specified */
3276 (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value));
3277 } else {
3278 /* snapname is the short name, append it to zhp's fsname */
3279 char *cp;
3280
3281 (void) strlcpy(zc.zc_value, zhp->zfs_name,
3282 sizeof (zc.zc_value));
3283 cp = strchr(zc.zc_value, '@');
3284 if (cp != NULL)
3285 *cp = '\0';
3286 (void) strlcat(zc.zc_value, snapname - 1, sizeof (zc.zc_value));
3287 }
3288
3289 err = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SPACE_WRITTEN, &zc);
3290 if (err)
3291 return (err);
3292
3293 *propvalue = zc.zc_cookie;
3294 return (0);
3295 }
3296
3297 int
3298 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
3299 char *propbuf, int proplen, boolean_t literal)
3300 {
3301 int err;
3302 uint64_t propvalue;
3303
3304 err = zfs_prop_get_written_int(zhp, propname, &propvalue);
3305
3306 if (err)
3307 return (err);
3308
3309 if (literal) {
3310 (void) snprintf(propbuf, proplen, "%llu",
3311 (u_longlong_t)propvalue);
3312 } else {
3313 zfs_nicebytes(propvalue, propbuf, proplen);
3314 }
3315
3316 return (0);
3317 }
3318
3319 /*
3320 * Returns the name of the given zfs handle.
3321 */
3322 const char *
3323 zfs_get_name(const zfs_handle_t *zhp)
3324 {
3325 return (zhp->zfs_name);
3326 }
3327
3328 /*
3329 * Returns the name of the parent pool for the given zfs handle.
3330 */
3331 const char *
3332 zfs_get_pool_name(const zfs_handle_t *zhp)
3333 {
3334 return (zhp->zpool_hdl->zpool_name);
3335 }
3336
3337 /*
3338 * Returns the type of the given zfs handle.
3339 */
3340 zfs_type_t
3341 zfs_get_type(const zfs_handle_t *zhp)
3342 {
3343 return (zhp->zfs_type);
3344 }
3345
3346 /*
3347 * Returns the type of the given zfs handle,
3348 * or, if a snapshot, the type of the snapshotted dataset.
3349 */
3350 zfs_type_t
3351 zfs_get_underlying_type(const zfs_handle_t *zhp)
3352 {
3353 return (zhp->zfs_head_type);
3354 }
3355
3356 /*
3357 * Is one dataset name a child dataset of another?
3358 *
3359 * Needs to handle these cases:
3360 * Dataset 1 "a/foo" "a/foo" "a/foo" "a/foo"
3361 * Dataset 2 "a/fo" "a/foobar" "a/bar/baz" "a/foo/bar"
3362 * Descendant? No. No. No. Yes.
3363 */
3364 static boolean_t
3365 is_descendant(const char *ds1, const char *ds2)
3366 {
3367 size_t d1len = strlen(ds1);
3368
3369 /* ds2 can't be a descendant if it's smaller */
3370 if (strlen(ds2) < d1len)
3371 return (B_FALSE);
3372
3373 /* otherwise, compare strings and verify that there's a '/' char */
3374 return (ds2[d1len] == '/' && (strncmp(ds1, ds2, d1len) == 0));
3375 }
3376
3377 /*
3378 * Given a complete name, return just the portion that refers to the parent.
3379 * Will return -1 if there is no parent (path is just the name of the
3380 * pool).
3381 */
3382 static int
3383 parent_name(const char *path, char *buf, size_t buflen)
3384 {
3385 char *slashp;
3386
3387 (void) strlcpy(buf, path, buflen);
3388
3389 if ((slashp = strrchr(buf, '/')) == NULL)
3390 return (-1);
3391 *slashp = '\0';
3392
3393 return (0);
3394 }
3395
3396 int
3397 zfs_parent_name(zfs_handle_t *zhp, char *buf, size_t buflen)
3398 {
3399 return (parent_name(zfs_get_name(zhp), buf, buflen));
3400 }
3401
3402 /*
3403 * If accept_ancestor is false, then check to make sure that the given path has
3404 * a parent, and that it exists. If accept_ancestor is true, then find the
3405 * closest existing ancestor for the given path. In prefixlen return the
3406 * length of already existing prefix of the given path. We also fetch the
3407 * 'zoned' property, which is used to validate property settings when creating
3408 * new datasets.
3409 */
3410 static int
3411 check_parents(libzfs_handle_t *hdl, const char *path, uint64_t *zoned,
3412 boolean_t accept_ancestor, int *prefixlen)
3413 {
3414 zfs_cmd_t zc = {"\0"};
3415 char parent[ZFS_MAX_DATASET_NAME_LEN];
3416 char *slash;
3417 zfs_handle_t *zhp;
3418 char errbuf[1024];
3419 uint64_t is_zoned;
3420
3421 (void) snprintf(errbuf, sizeof (errbuf),
3422 dgettext(TEXT_DOMAIN, "cannot create '%s'"), path);
3423
3424 /* get parent, and check to see if this is just a pool */
3425 if (parent_name(path, parent, sizeof (parent)) != 0) {
3426 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3427 "missing dataset name"));
3428 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3429 }
3430
3431 /* check to see if the pool exists */
3432 if ((slash = strchr(parent, '/')) == NULL)
3433 slash = parent + strlen(parent);
3434 (void) strncpy(zc.zc_name, parent, slash - parent);
3435 zc.zc_name[slash - parent] = '\0';
3436 if (zfs_ioctl(hdl, ZFS_IOC_OBJSET_STATS, &zc) != 0 &&
3437 errno == ENOENT) {
3438 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3439 "no such pool '%s'"), zc.zc_name);
3440 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3441 }
3442
3443 /* check to see if the parent dataset exists */
3444 while ((zhp = make_dataset_handle(hdl, parent)) == NULL) {
3445 if (errno == ENOENT && accept_ancestor) {
3446 /*
3447 * Go deeper to find an ancestor, give up on top level.
3448 */
3449 if (parent_name(parent, parent, sizeof (parent)) != 0) {
3450 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3451 "no such pool '%s'"), zc.zc_name);
3452 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3453 }
3454 } else if (errno == ENOENT) {
3455 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3456 "parent does not exist"));
3457 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3458 } else
3459 return (zfs_standard_error(hdl, errno, errbuf));
3460 }
3461
3462 is_zoned = zfs_prop_get_int(zhp, ZFS_PROP_ZONED);
3463 if (zoned != NULL)
3464 *zoned = is_zoned;
3465
3466 /* we are in a non-global zone, but parent is in the global zone */
3467 if (getzoneid() != GLOBAL_ZONEID && !is_zoned) {
3468 (void) zfs_standard_error(hdl, EPERM, errbuf);
3469 zfs_close(zhp);
3470 return (-1);
3471 }
3472
3473 /* make sure parent is a filesystem */
3474 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) {
3475 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3476 "parent is not a filesystem"));
3477 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
3478 zfs_close(zhp);
3479 return (-1);
3480 }
3481
3482 zfs_close(zhp);
3483 if (prefixlen != NULL)
3484 *prefixlen = strlen(parent);
3485 return (0);
3486 }
3487
3488 /*
3489 * Finds whether the dataset of the given type(s) exists.
3490 */
3491 boolean_t
3492 zfs_dataset_exists(libzfs_handle_t *hdl, const char *path, zfs_type_t types)
3493 {
3494 zfs_handle_t *zhp;
3495
3496 if (!zfs_validate_name(hdl, path, types, B_FALSE))
3497 return (B_FALSE);
3498
3499 /*
3500 * Try to get stats for the dataset, which will tell us if it exists.
3501 */
3502 if ((zhp = make_dataset_handle(hdl, path)) != NULL) {
3503 int ds_type = zhp->zfs_type;
3504
3505 zfs_close(zhp);
3506 if (types & ds_type)
3507 return (B_TRUE);
3508 }
3509 return (B_FALSE);
3510 }
3511
3512 /*
3513 * Given a path to 'target', create all the ancestors between
3514 * the prefixlen portion of the path, and the target itself.
3515 * Fail if the initial prefixlen-ancestor does not already exist.
3516 */
3517 int
3518 create_parents(libzfs_handle_t *hdl, char *target, int prefixlen)
3519 {
3520 zfs_handle_t *h;
3521 char *cp;
3522 const char *opname;
3523
3524 /* make sure prefix exists */
3525 cp = target + prefixlen;
3526 if (*cp != '/') {
3527 assert(strchr(cp, '/') == NULL);
3528 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3529 } else {
3530 *cp = '\0';
3531 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3532 *cp = '/';
3533 }
3534 if (h == NULL)
3535 return (-1);
3536 zfs_close(h);
3537
3538 /*
3539 * Attempt to create, mount, and share any ancestor filesystems,
3540 * up to the prefixlen-long one.
3541 */
3542 for (cp = target + prefixlen + 1;
3543 (cp = strchr(cp, '/')) != NULL; *cp = '/', cp++) {
3544
3545 *cp = '\0';
3546
3547 h = make_dataset_handle(hdl, target);
3548 if (h) {
3549 /* it already exists, nothing to do here */
3550 zfs_close(h);
3551 continue;
3552 }
3553
3554 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
3555 NULL) != 0) {
3556 opname = dgettext(TEXT_DOMAIN, "create");
3557 goto ancestorerr;
3558 }
3559
3560 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
3561 if (h == NULL) {
3562 opname = dgettext(TEXT_DOMAIN, "open");
3563 goto ancestorerr;
3564 }
3565
3566 if (zfs_mount(h, NULL, 0) != 0) {
3567 opname = dgettext(TEXT_DOMAIN, "mount");
3568 goto ancestorerr;
3569 }
3570
3571 if (zfs_share(h) != 0) {
3572 opname = dgettext(TEXT_DOMAIN, "share");
3573 goto ancestorerr;
3574 }
3575
3576 zfs_close(h);
3577 }
3578 zfs_commit_all_shares();
3579
3580 return (0);
3581
3582 ancestorerr:
3583 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3584 "failed to %s ancestor '%s'"), opname, target);
3585 return (-1);
3586 }
3587
3588 /*
3589 * Creates non-existing ancestors of the given path.
3590 */
3591 int
3592 zfs_create_ancestors(libzfs_handle_t *hdl, const char *path)
3593 {
3594 int prefix;
3595 char *path_copy;
3596 char errbuf[1024];
3597 int rc = 0;
3598
3599 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3600 "cannot create '%s'"), path);
3601
3602 /*
3603 * Check that we are not passing the nesting limit
3604 * before we start creating any ancestors.
3605 */
3606 if (dataset_nestcheck(path) != 0) {
3607 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3608 "maximum name nesting depth exceeded"));
3609 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3610 }
3611
3612 if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
3613 return (-1);
3614
3615 if ((path_copy = strdup(path)) != NULL) {
3616 rc = create_parents(hdl, path_copy, prefix);
3617 free(path_copy);
3618 }
3619 if (path_copy == NULL || rc != 0)
3620 return (-1);
3621
3622 return (0);
3623 }
3624
3625 /*
3626 * Create a new filesystem or volume.
3627 */
3628 int
3629 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
3630 nvlist_t *props)
3631 {
3632 int ret;
3633 uint64_t size = 0;
3634 uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
3635 uint64_t zoned;
3636 enum lzc_dataset_type ost;
3637 zpool_handle_t *zpool_handle;
3638 uint8_t *wkeydata = NULL;
3639 uint_t wkeylen = 0;
3640 char errbuf[1024];
3641 char parent[ZFS_MAX_DATASET_NAME_LEN];
3642
3643 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3644 "cannot create '%s'"), path);
3645
3646 /* validate the path, taking care to note the extended error message */
3647 if (!zfs_validate_name(hdl, path, type, B_TRUE))
3648 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3649
3650 if (dataset_nestcheck(path) != 0) {
3651 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3652 "maximum name nesting depth exceeded"));
3653 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3654 }
3655
3656 /* validate parents exist */
3657 if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
3658 return (-1);
3659
3660 /*
3661 * The failure modes when creating a dataset of a different type over
3662 * one that already exists is a little strange. In particular, if you
3663 * try to create a dataset on top of an existing dataset, the ioctl()
3664 * will return ENOENT, not EEXIST. To prevent this from happening, we
3665 * first try to see if the dataset exists.
3666 */
3667 if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
3668 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3669 "dataset already exists"));
3670 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3671 }
3672
3673 if (type == ZFS_TYPE_VOLUME)
3674 ost = LZC_DATSET_TYPE_ZVOL;
3675 else
3676 ost = LZC_DATSET_TYPE_ZFS;
3677
3678 /* open zpool handle for prop validation */
3679 char pool_path[ZFS_MAX_DATASET_NAME_LEN];
3680 (void) strlcpy(pool_path, path, sizeof (pool_path));
3681
3682 /* truncate pool_path at first slash */
3683 char *p = strchr(pool_path, '/');
3684 if (p != NULL)
3685 *p = '\0';
3686
3687 if ((zpool_handle = zpool_open(hdl, pool_path)) == NULL)
3688 return (-1);
3689
3690 if (props && (props = zfs_valid_proplist(hdl, type, props,
3691 zoned, NULL, zpool_handle, B_TRUE, errbuf)) == 0) {
3692 zpool_close(zpool_handle);
3693 return (-1);
3694 }
3695 zpool_close(zpool_handle);
3696
3697 if (type == ZFS_TYPE_VOLUME) {
3698 /*
3699 * If we are creating a volume, the size and block size must
3700 * satisfy a few restraints. First, the blocksize must be a
3701 * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the
3702 * volsize must be a multiple of the block size, and cannot be
3703 * zero.
3704 */
3705 if (props == NULL || nvlist_lookup_uint64(props,
3706 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
3707 nvlist_free(props);
3708 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3709 "missing volume size"));
3710 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3711 }
3712
3713 if ((ret = nvlist_lookup_uint64(props,
3714 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
3715 &blocksize)) != 0) {
3716 if (ret == ENOENT) {
3717 blocksize = zfs_prop_default_numeric(
3718 ZFS_PROP_VOLBLOCKSIZE);
3719 } else {
3720 nvlist_free(props);
3721 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3722 "missing volume block size"));
3723 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3724 }
3725 }
3726
3727 if (size == 0) {
3728 nvlist_free(props);
3729 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3730 "volume size cannot be zero"));
3731 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3732 }
3733
3734 if (size % blocksize != 0) {
3735 nvlist_free(props);
3736 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3737 "volume size must be a multiple of volume block "
3738 "size"));
3739 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3740 }
3741 }
3742
3743 (void) parent_name(path, parent, sizeof (parent));
3744 if (zfs_crypto_create(hdl, parent, props, NULL, B_TRUE,
3745 &wkeydata, &wkeylen) != 0) {
3746 nvlist_free(props);
3747 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3748 }
3749
3750 /* create the dataset */
3751 ret = lzc_create(path, ost, props, wkeydata, wkeylen);
3752 nvlist_free(props);
3753 if (wkeydata != NULL)
3754 free(wkeydata);
3755
3756 /* check for failure */
3757 if (ret != 0) {
3758 switch (errno) {
3759 case ENOENT:
3760 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3761 "no such parent '%s'"), parent);
3762 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3763
3764 case ENOTSUP:
3765 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3766 "pool must be upgraded to set this "
3767 "property or value"));
3768 return (zfs_error(hdl, EZFS_BADVERSION, errbuf));
3769
3770 case EACCES:
3771 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3772 "encryption root's key is not loaded "
3773 "or provided"));
3774 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3775
3776 case ERANGE:
3777 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3778 "invalid property value(s) specified"));
3779 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3780 #ifdef _ILP32
3781 case EOVERFLOW:
3782 /*
3783 * This platform can't address a volume this big.
3784 */
3785 if (type == ZFS_TYPE_VOLUME)
3786 return (zfs_error(hdl, EZFS_VOLTOOBIG,
3787 errbuf));
3788 zfs_fallthrough;
3789 #endif
3790 default:
3791 return (zfs_standard_error(hdl, errno, errbuf));
3792 }
3793 }
3794
3795 return (0);
3796 }
3797
3798 /*
3799 * Destroys the given dataset. The caller must make sure that the filesystem
3800 * isn't mounted, and that there are no active dependents. If the file system
3801 * does not exist this function does nothing.
3802 */
3803 int
3804 zfs_destroy(zfs_handle_t *zhp, boolean_t defer)
3805 {
3806 int error;
3807
3808 if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT && defer)
3809 return (EINVAL);
3810
3811 if (zhp->zfs_type == ZFS_TYPE_BOOKMARK) {
3812 nvlist_t *nv = fnvlist_alloc();
3813 fnvlist_add_boolean(nv, zhp->zfs_name);
3814 error = lzc_destroy_bookmarks(nv, NULL);
3815 fnvlist_free(nv);
3816 if (error != 0) {
3817 return (zfs_standard_error_fmt(zhp->zfs_hdl, error,
3818 dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3819 zhp->zfs_name));
3820 }
3821 return (0);
3822 }
3823
3824 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
3825 nvlist_t *nv = fnvlist_alloc();
3826 fnvlist_add_boolean(nv, zhp->zfs_name);
3827 error = lzc_destroy_snaps(nv, defer, NULL);
3828 fnvlist_free(nv);
3829 } else {
3830 error = lzc_destroy(zhp->zfs_name);
3831 }
3832
3833 if (error != 0 && error != ENOENT) {
3834 return (zfs_standard_error_fmt(zhp->zfs_hdl, errno,
3835 dgettext(TEXT_DOMAIN, "cannot destroy '%s'"),
3836 zhp->zfs_name));
3837 }
3838
3839 remove_mountpoint(zhp);
3840
3841 return (0);
3842 }
3843
3844 struct destroydata {
3845 nvlist_t *nvl;
3846 const char *snapname;
3847 };
3848
3849 static int
3850 zfs_check_snap_cb(zfs_handle_t *zhp, void *arg)
3851 {
3852 struct destroydata *dd = arg;
3853 char name[ZFS_MAX_DATASET_NAME_LEN];
3854 int rv = 0;
3855
3856 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
3857 dd->snapname) >= sizeof (name))
3858 return (EINVAL);
3859
3860 if (lzc_exists(name))
3861 fnvlist_add_boolean(dd->nvl, name);
3862
3863 rv = zfs_iter_filesystems(zhp, zfs_check_snap_cb, dd);
3864 zfs_close(zhp);
3865 return (rv);
3866 }
3867
3868 /*
3869 * Destroys all snapshots with the given name in zhp & descendants.
3870 */
3871 int
3872 zfs_destroy_snaps(zfs_handle_t *zhp, char *snapname, boolean_t defer)
3873 {
3874 int ret;
3875 struct destroydata dd = { 0 };
3876
3877 dd.snapname = snapname;
3878 dd.nvl = fnvlist_alloc();
3879 (void) zfs_check_snap_cb(zfs_handle_dup(zhp), &dd);
3880
3881 if (nvlist_empty(dd.nvl)) {
3882 ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3883 dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3884 zhp->zfs_name, snapname);
3885 } else {
3886 ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer);
3887 }
3888 fnvlist_free(dd.nvl);
3889 return (ret);
3890 }
3891
3892 /*
3893 * Destroys all the snapshots named in the nvlist.
3894 */
3895 int
3896 zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer)
3897 {
3898 nvlist_t *errlist = NULL;
3899 nvpair_t *pair;
3900
3901 int ret = zfs_destroy_snaps_nvl_os(hdl, snaps);
3902 if (ret != 0)
3903 return (ret);
3904
3905 ret = lzc_destroy_snaps(snaps, defer, &errlist);
3906
3907 if (ret == 0) {
3908 nvlist_free(errlist);
3909 return (0);
3910 }
3911
3912 if (nvlist_empty(errlist)) {
3913 char errbuf[1024];
3914 (void) snprintf(errbuf, sizeof (errbuf),
3915 dgettext(TEXT_DOMAIN, "cannot destroy snapshots"));
3916
3917 ret = zfs_standard_error(hdl, ret, errbuf);
3918 }
3919 for (pair = nvlist_next_nvpair(errlist, NULL);
3920 pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
3921 char errbuf[1024];
3922 (void) snprintf(errbuf, sizeof (errbuf),
3923 dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
3924 nvpair_name(pair));
3925
3926 switch (fnvpair_value_int32(pair)) {
3927 case EEXIST:
3928 zfs_error_aux(hdl,
3929 dgettext(TEXT_DOMAIN, "snapshot is cloned"));
3930 ret = zfs_error(hdl, EZFS_EXISTS, errbuf);
3931 break;
3932 default:
3933 ret = zfs_standard_error(hdl, errno, errbuf);
3934 break;
3935 }
3936 }
3937
3938 nvlist_free(errlist);
3939 return (ret);
3940 }
3941
3942 /*
3943 * Clones the given dataset. The target must be of the same type as the source.
3944 */
3945 int
3946 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3947 {
3948 char parent[ZFS_MAX_DATASET_NAME_LEN];
3949 int ret;
3950 char errbuf[1024];
3951 libzfs_handle_t *hdl = zhp->zfs_hdl;
3952 uint64_t zoned;
3953
3954 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3955
3956 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3957 "cannot create '%s'"), target);
3958
3959 /* validate the target/clone name */
3960 if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3961 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3962
3963 /* validate parents exist */
3964 if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3965 return (-1);
3966
3967 (void) parent_name(target, parent, sizeof (parent));
3968
3969 /* do the clone */
3970
3971 if (props) {
3972 zfs_type_t type = ZFS_TYPE_FILESYSTEM;
3973
3974 if (ZFS_IS_VOLUME(zhp))
3975 type = ZFS_TYPE_VOLUME;
3976 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3977 zhp, zhp->zpool_hdl, B_TRUE, errbuf)) == NULL)
3978 return (-1);
3979 if (zfs_fix_auto_resv(zhp, props) == -1) {
3980 nvlist_free(props);
3981 return (-1);
3982 }
3983 }
3984
3985 if (zfs_crypto_clone_check(hdl, zhp, parent, props) != 0) {
3986 nvlist_free(props);
3987 return (zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf));
3988 }
3989
3990 ret = lzc_clone(target, zhp->zfs_name, props);
3991 nvlist_free(props);
3992
3993 if (ret != 0) {
3994 switch (errno) {
3995
3996 case ENOENT:
3997 /*
3998 * The parent doesn't exist. We should have caught this
3999 * above, but there may a race condition that has since
4000 * destroyed the parent.
4001 *
4002 * At this point, we don't know whether it's the source
4003 * that doesn't exist anymore, or whether the target
4004 * dataset doesn't exist.
4005 */
4006 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4007 "no such parent '%s'"), parent);
4008 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
4009
4010 case EXDEV:
4011 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4012 "source and target pools differ"));
4013 return (zfs_error(zhp->zfs_hdl, EZFS_CROSSTARGET,
4014 errbuf));
4015
4016 default:
4017 return (zfs_standard_error(zhp->zfs_hdl, errno,
4018 errbuf));
4019 }
4020 }
4021
4022 return (ret);
4023 }
4024
4025 /*
4026 * Promotes the given clone fs to be the clone parent.
4027 */
4028 int
4029 zfs_promote(zfs_handle_t *zhp)
4030 {
4031 libzfs_handle_t *hdl = zhp->zfs_hdl;
4032 char snapname[ZFS_MAX_DATASET_NAME_LEN];
4033 int ret;
4034 char errbuf[1024];
4035
4036 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4037 "cannot promote '%s'"), zhp->zfs_name);
4038
4039 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4040 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4041 "snapshots can not be promoted"));
4042 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4043 }
4044
4045 if (zhp->zfs_dmustats.dds_origin[0] == '\0') {
4046 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4047 "not a cloned filesystem"));
4048 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4049 }
4050
4051 if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
4052 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4053
4054 ret = lzc_promote(zhp->zfs_name, snapname, sizeof (snapname));
4055
4056 if (ret != 0) {
4057 switch (ret) {
4058 case EACCES:
4059 /*
4060 * Promoting encrypted dataset outside its
4061 * encryption root.
4062 */
4063 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4064 "cannot promote dataset outside its "
4065 "encryption root"));
4066 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
4067
4068 case EEXIST:
4069 /* There is a conflicting snapshot name. */
4070 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4071 "conflicting snapshot '%s' from parent '%s'"),
4072 snapname, zhp->zfs_dmustats.dds_origin);
4073 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
4074
4075 default:
4076 return (zfs_standard_error(hdl, ret, errbuf));
4077 }
4078 }
4079 return (ret);
4080 }
4081
4082 typedef struct snapdata {
4083 nvlist_t *sd_nvl;
4084 const char *sd_snapname;
4085 } snapdata_t;
4086
4087 static int
4088 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
4089 {
4090 snapdata_t *sd = arg;
4091 char name[ZFS_MAX_DATASET_NAME_LEN];
4092 int rv = 0;
4093
4094 if (zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT) == 0) {
4095 if (snprintf(name, sizeof (name), "%s@%s", zfs_get_name(zhp),
4096 sd->sd_snapname) >= sizeof (name))
4097 return (EINVAL);
4098
4099 fnvlist_add_boolean(sd->sd_nvl, name);
4100
4101 rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
4102 }
4103 zfs_close(zhp);
4104
4105 return (rv);
4106 }
4107
4108 /*
4109 * Creates snapshots. The keys in the snaps nvlist are the snapshots to be
4110 * created.
4111 */
4112 int
4113 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
4114 {
4115 int ret;
4116 char errbuf[1024];
4117 nvpair_t *elem;
4118 nvlist_t *errors;
4119 zpool_handle_t *zpool_hdl;
4120 char pool[ZFS_MAX_DATASET_NAME_LEN];
4121
4122 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4123 "cannot create snapshots "));
4124
4125 elem = NULL;
4126 while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
4127 const char *snapname = nvpair_name(elem);
4128
4129 /* validate the target name */
4130 if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
4131 B_TRUE)) {
4132 (void) snprintf(errbuf, sizeof (errbuf),
4133 dgettext(TEXT_DOMAIN,
4134 "cannot create snapshot '%s'"), snapname);
4135 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4136 }
4137 }
4138
4139 /*
4140 * get pool handle for prop validation. assumes all snaps are in the
4141 * same pool, as does lzc_snapshot (below).
4142 */
4143 elem = nvlist_next_nvpair(snaps, NULL);
4144 (void) strlcpy(pool, nvpair_name(elem), sizeof (pool));
4145 pool[strcspn(pool, "/@")] = '\0';
4146 zpool_hdl = zpool_open(hdl, pool);
4147 if (zpool_hdl == NULL)
4148 return (-1);
4149
4150 if (props != NULL &&
4151 (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
4152 props, B_FALSE, NULL, zpool_hdl, B_FALSE, errbuf)) == NULL) {
4153 zpool_close(zpool_hdl);
4154 return (-1);
4155 }
4156 zpool_close(zpool_hdl);
4157
4158 ret = lzc_snapshot(snaps, props, &errors);
4159
4160 if (ret != 0) {
4161 boolean_t printed = B_FALSE;
4162 for (elem = nvlist_next_nvpair(errors, NULL);
4163 elem != NULL;
4164 elem = nvlist_next_nvpair(errors, elem)) {
4165 (void) snprintf(errbuf, sizeof (errbuf),
4166 dgettext(TEXT_DOMAIN,
4167 "cannot create snapshot '%s'"), nvpair_name(elem));
4168 (void) zfs_standard_error(hdl,
4169 fnvpair_value_int32(elem), errbuf);
4170 printed = B_TRUE;
4171 }
4172 if (!printed) {
4173 switch (ret) {
4174 case EXDEV:
4175 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4176 "multiple snapshots of same "
4177 "fs not allowed"));
4178 (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
4179
4180 break;
4181 default:
4182 (void) zfs_standard_error(hdl, ret, errbuf);
4183 }
4184 }
4185 }
4186
4187 nvlist_free(props);
4188 nvlist_free(errors);
4189 return (ret);
4190 }
4191
4192 int
4193 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
4194 nvlist_t *props)
4195 {
4196 int ret;
4197 snapdata_t sd = { 0 };
4198 char fsname[ZFS_MAX_DATASET_NAME_LEN];
4199 char *cp;
4200 zfs_handle_t *zhp;
4201 char errbuf[1024];
4202
4203 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4204 "cannot snapshot %s"), path);
4205
4206 if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
4207 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4208
4209 (void) strlcpy(fsname, path, sizeof (fsname));
4210 cp = strchr(fsname, '@');
4211 *cp = '\0';
4212 sd.sd_snapname = cp + 1;
4213
4214 if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
4215 ZFS_TYPE_VOLUME)) == NULL) {
4216 return (-1);
4217 }
4218
4219 sd.sd_nvl = fnvlist_alloc();
4220 if (recursive) {
4221 (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
4222 } else {
4223 fnvlist_add_boolean(sd.sd_nvl, path);
4224 }
4225
4226 ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
4227 fnvlist_free(sd.sd_nvl);
4228 zfs_close(zhp);
4229 return (ret);
4230 }
4231
4232 /*
4233 * Destroy any more recent snapshots. We invoke this callback on any dependents
4234 * of the snapshot first. If the 'cb_dependent' member is non-zero, then this
4235 * is a dependent and we should just destroy it without checking the transaction
4236 * group.
4237 */
4238 typedef struct rollback_data {
4239 const char *cb_target; /* the snapshot */
4240 uint64_t cb_create; /* creation time reference */
4241 boolean_t cb_error;
4242 boolean_t cb_force;
4243 } rollback_data_t;
4244
4245 static int
4246 rollback_destroy_dependent(zfs_handle_t *zhp, void *data)
4247 {
4248 rollback_data_t *cbp = data;
4249 prop_changelist_t *clp;
4250
4251 /* We must destroy this clone; first unmount it */
4252 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
4253 cbp->cb_force ? MS_FORCE: 0);
4254 if (clp == NULL || changelist_prefix(clp) != 0) {
4255 cbp->cb_error = B_TRUE;
4256 zfs_close(zhp);
4257 return (0);
4258 }
4259 if (zfs_destroy(zhp, B_FALSE) != 0)
4260 cbp->cb_error = B_TRUE;
4261 else
4262 changelist_remove(clp, zhp->zfs_name);
4263 (void) changelist_postfix(clp);
4264 changelist_free(clp);
4265
4266 zfs_close(zhp);
4267 return (0);
4268 }
4269
4270 static int
4271 rollback_destroy(zfs_handle_t *zhp, void *data)
4272 {
4273 rollback_data_t *cbp = data;
4274
4275 if (zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) > cbp->cb_create) {
4276 cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
4277 rollback_destroy_dependent, cbp);
4278
4279 cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
4280 }
4281
4282 zfs_close(zhp);
4283 return (0);
4284 }
4285
4286 /*
4287 * Given a dataset, rollback to a specific snapshot, discarding any
4288 * data changes since then and making it the active dataset.
4289 *
4290 * Any snapshots and bookmarks more recent than the target are
4291 * destroyed, along with their dependents (i.e. clones).
4292 */
4293 int
4294 zfs_rollback(zfs_handle_t *zhp, zfs_handle_t *snap, boolean_t force)
4295 {
4296 rollback_data_t cb = { 0 };
4297 int err;
4298 boolean_t restore_resv = 0;
4299 uint64_t old_volsize = 0, new_volsize;
4300 zfs_prop_t resv_prop = { 0 };
4301 uint64_t min_txg = 0;
4302
4303 assert(zhp->zfs_type == ZFS_TYPE_FILESYSTEM ||
4304 zhp->zfs_type == ZFS_TYPE_VOLUME);
4305
4306 /*
4307 * Destroy all recent snapshots and their dependents.
4308 */
4309 cb.cb_force = force;
4310 cb.cb_target = snap->zfs_name;
4311 cb.cb_create = zfs_prop_get_int(snap, ZFS_PROP_CREATETXG);
4312
4313 if (cb.cb_create > 0)
4314 min_txg = cb.cb_create;
4315
4316 (void) zfs_iter_snapshots(zhp, B_FALSE, rollback_destroy, &cb,
4317 min_txg, 0);
4318
4319 (void) zfs_iter_bookmarks(zhp, rollback_destroy, &cb);
4320
4321 if (cb.cb_error)
4322 return (-1);
4323
4324 /*
4325 * Now that we have verified that the snapshot is the latest,
4326 * rollback to the given snapshot.
4327 */
4328
4329 if (zhp->zfs_type == ZFS_TYPE_VOLUME) {
4330 if (zfs_which_resv_prop(zhp, &resv_prop) < 0)
4331 return (-1);
4332 old_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4333 restore_resv =
4334 (old_volsize == zfs_prop_get_int(zhp, resv_prop));
4335 }
4336
4337 /*
4338 * Pass both the filesystem and the wanted snapshot names,
4339 * we would get an error back if the snapshot is destroyed or
4340 * a new snapshot is created before this request is processed.
4341 */
4342 err = lzc_rollback_to(zhp->zfs_name, snap->zfs_name);
4343 if (err != 0) {
4344 char errbuf[1024];
4345
4346 (void) snprintf(errbuf, sizeof (errbuf),
4347 dgettext(TEXT_DOMAIN, "cannot rollback '%s'"),
4348 zhp->zfs_name);
4349 switch (err) {
4350 case EEXIST:
4351 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4352 "there is a snapshot or bookmark more recent "
4353 "than '%s'"), snap->zfs_name);
4354 (void) zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf);
4355 break;
4356 case ESRCH:
4357 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
4358 "'%s' is not found among snapshots of '%s'"),
4359 snap->zfs_name, zhp->zfs_name);
4360 (void) zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf);
4361 break;
4362 case EINVAL:
4363 (void) zfs_error(zhp->zfs_hdl, EZFS_BADTYPE, errbuf);
4364 break;
4365 default:
4366 (void) zfs_standard_error(zhp->zfs_hdl, err, errbuf);
4367 }
4368 return (err);
4369 }
4370
4371 /*
4372 * For volumes, if the pre-rollback volsize matched the pre-
4373 * rollback reservation and the volsize has changed then set
4374 * the reservation property to the post-rollback volsize.
4375 * Make a new handle since the rollback closed the dataset.
4376 */
4377 if ((zhp->zfs_type == ZFS_TYPE_VOLUME) &&
4378 (zhp = make_dataset_handle(zhp->zfs_hdl, zhp->zfs_name))) {
4379 if (restore_resv) {
4380 new_volsize = zfs_prop_get_int(zhp, ZFS_PROP_VOLSIZE);
4381 if (old_volsize != new_volsize)
4382 err = zfs_prop_set_int(zhp, resv_prop,
4383 new_volsize);
4384 }
4385 zfs_close(zhp);
4386 }
4387 return (err);
4388 }
4389
4390 /*
4391 * Renames the given dataset.
4392 */
4393 int
4394 zfs_rename(zfs_handle_t *zhp, const char *target, renameflags_t flags)
4395 {
4396 int ret = 0;
4397 zfs_cmd_t zc = {"\0"};
4398 char *delim;
4399 prop_changelist_t *cl = NULL;
4400 char parent[ZFS_MAX_DATASET_NAME_LEN];
4401 char property[ZFS_MAXPROPLEN];
4402 libzfs_handle_t *hdl = zhp->zfs_hdl;
4403 char errbuf[1024];
4404
4405 /* if we have the same exact name, just return success */
4406 if (strcmp(zhp->zfs_name, target) == 0)
4407 return (0);
4408
4409 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4410 "cannot rename to '%s'"), target);
4411
4412 /* make sure source name is valid */
4413 if (!zfs_validate_name(hdl, zhp->zfs_name, zhp->zfs_type, B_TRUE))
4414 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4415
4416 /*
4417 * Make sure the target name is valid
4418 */
4419 if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT) {
4420 if ((strchr(target, '@') == NULL) ||
4421 *target == '@') {
4422 /*
4423 * Snapshot target name is abbreviated,
4424 * reconstruct full dataset name
4425 */
4426 (void) strlcpy(parent, zhp->zfs_name,
4427 sizeof (parent));
4428 delim = strchr(parent, '@');
4429 if (strchr(target, '@') == NULL)
4430 *(++delim) = '\0';
4431 else
4432 *delim = '\0';
4433 (void) strlcat(parent, target, sizeof (parent));
4434 target = parent;
4435 } else {
4436 /*
4437 * Make sure we're renaming within the same dataset.
4438 */
4439 delim = strchr(target, '@');
4440 if (strncmp(zhp->zfs_name, target, delim - target)
4441 != 0 || zhp->zfs_name[delim - target] != '@') {
4442 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4443 "snapshots must be part of same "
4444 "dataset"));
4445 return (zfs_error(hdl, EZFS_CROSSTARGET,
4446 errbuf));
4447 }
4448 }
4449
4450 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4451 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4452 } else {
4453 if (flags.recursive) {
4454 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4455 "recursive rename must be a snapshot"));
4456 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
4457 }
4458
4459 if (!zfs_validate_name(hdl, target, zhp->zfs_type, B_TRUE))
4460 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4461
4462 /* validate parents */
4463 if (check_parents(hdl, target, NULL, B_FALSE, NULL) != 0)
4464 return (-1);
4465
4466 /* make sure we're in the same pool */
4467 verify((delim = strchr(target, '/')) != NULL);
4468 if (strncmp(zhp->zfs_name, target, delim - target) != 0 ||
4469 zhp->zfs_name[delim - target] != '/') {
4470 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4471 "datasets must be within same pool"));
4472 return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
4473 }
4474
4475 /* new name cannot be a child of the current dataset name */
4476 if (is_descendant(zhp->zfs_name, target)) {
4477 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4478 "New dataset name cannot be a descendant of "
4479 "current dataset name"));
4480 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
4481 }
4482 }
4483
4484 (void) snprintf(errbuf, sizeof (errbuf),
4485 dgettext(TEXT_DOMAIN, "cannot rename '%s'"), zhp->zfs_name);
4486
4487 if (getzoneid() == GLOBAL_ZONEID &&
4488 zfs_prop_get_int(zhp, ZFS_PROP_ZONED)) {
4489 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4490 "dataset is used in a non-global zone"));
4491 return (zfs_error(hdl, EZFS_ZONED, errbuf));
4492 }
4493
4494 /*
4495 * Avoid unmounting file systems with mountpoint property set to
4496 * 'legacy' or 'none' even if -u option is not given.
4497 */
4498 if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
4499 !flags.recursive && !flags.nounmount &&
4500 zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, property,
4501 sizeof (property), NULL, NULL, 0, B_FALSE) == 0 &&
4502 (strcmp(property, "legacy") == 0 ||
4503 strcmp(property, "none") == 0)) {
4504 flags.nounmount = B_TRUE;
4505 }
4506 if (flags.recursive) {
4507 char *parentname = zfs_strdup(zhp->zfs_hdl, zhp->zfs_name);
4508 if (parentname == NULL) {
4509 ret = -1;
4510 goto error;
4511 }
4512 delim = strchr(parentname, '@');
4513 *delim = '\0';
4514 zfs_handle_t *zhrp = zfs_open(zhp->zfs_hdl, parentname,
4515 ZFS_TYPE_DATASET);
4516 free(parentname);
4517 if (zhrp == NULL) {
4518 ret = -1;
4519 goto error;
4520 }
4521 zfs_close(zhrp);
4522 } else if (zhp->zfs_type != ZFS_TYPE_SNAPSHOT) {
4523 if ((cl = changelist_gather(zhp, ZFS_PROP_NAME,
4524 flags.nounmount ? CL_GATHER_DONT_UNMOUNT :
4525 CL_GATHER_ITER_MOUNTED,
4526 flags.forceunmount ? MS_FORCE : 0)) == NULL)
4527 return (-1);
4528
4529 if (changelist_haszonedchild(cl)) {
4530 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4531 "child dataset with inherited mountpoint is used "
4532 "in a non-global zone"));
4533 (void) zfs_error(hdl, EZFS_ZONED, errbuf);
4534 ret = -1;
4535 goto error;
4536 }
4537
4538 if ((ret = changelist_prefix(cl)) != 0)
4539 goto error;
4540 }
4541
4542 if (ZFS_IS_VOLUME(zhp))
4543 zc.zc_objset_type = DMU_OST_ZVOL;
4544 else
4545 zc.zc_objset_type = DMU_OST_ZFS;
4546
4547 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4548 (void) strlcpy(zc.zc_value, target, sizeof (zc.zc_value));
4549
4550 zc.zc_cookie = !!flags.recursive;
4551 zc.zc_cookie |= (!!flags.nounmount) << 1;
4552
4553 if ((ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_RENAME, &zc)) != 0) {
4554 /*
4555 * if it was recursive, the one that actually failed will
4556 * be in zc.zc_name
4557 */
4558 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
4559 "cannot rename '%s'"), zc.zc_name);
4560
4561 if (flags.recursive && errno == EEXIST) {
4562 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4563 "a child dataset already has a snapshot "
4564 "with the new name"));
4565 (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
4566 } else if (errno == EACCES) {
4567 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4568 "cannot move encrypted child outside of "
4569 "its encryption root"));
4570 (void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
4571 } else {
4572 (void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
4573 }
4574
4575 /*
4576 * On failure, we still want to remount any filesystems that
4577 * were previously mounted, so we don't alter the system state.
4578 */
4579 if (cl != NULL)
4580 (void) changelist_postfix(cl);
4581 } else {
4582 if (cl != NULL) {
4583 changelist_rename(cl, zfs_get_name(zhp), target);
4584 ret = changelist_postfix(cl);
4585 }
4586 }
4587
4588 error:
4589 if (cl != NULL) {
4590 changelist_free(cl);
4591 }
4592 return (ret);
4593 }
4594
4595 nvlist_t *
4596 zfs_get_all_props(zfs_handle_t *zhp)
4597 {
4598 return (zhp->zfs_props);
4599 }
4600
4601 nvlist_t *
4602 zfs_get_recvd_props(zfs_handle_t *zhp)
4603 {
4604 if (zhp->zfs_recvd_props == NULL)
4605 if (get_recvd_props_ioctl(zhp) != 0)
4606 return (NULL);
4607 return (zhp->zfs_recvd_props);
4608 }
4609
4610 nvlist_t *
4611 zfs_get_user_props(zfs_handle_t *zhp)
4612 {
4613 return (zhp->zfs_user_props);
4614 }
4615
4616 /*
4617 * This function is used by 'zfs list' to determine the exact set of columns to
4618 * display, and their maximum widths. This does two main things:
4619 *
4620 * - If this is a list of all properties, then expand the list to include
4621 * all native properties, and set a flag so that for each dataset we look
4622 * for new unique user properties and add them to the list.
4623 *
4624 * - For non fixed-width properties, keep track of the maximum width seen
4625 * so that we can size the column appropriately. If the user has
4626 * requested received property values, we also need to compute the width
4627 * of the RECEIVED column.
4628 */
4629 int
4630 zfs_expand_proplist(zfs_handle_t *zhp, zprop_list_t **plp, boolean_t received,
4631 boolean_t literal)
4632 {
4633 libzfs_handle_t *hdl = zhp->zfs_hdl;
4634 zprop_list_t *entry;
4635 zprop_list_t **last, **start;
4636 nvlist_t *userprops, *propval;
4637 nvpair_t *elem;
4638 char *strval;
4639 char buf[ZFS_MAXPROPLEN];
4640
4641 if (zprop_expand_list(hdl, plp, ZFS_TYPE_DATASET) != 0)
4642 return (-1);
4643
4644 userprops = zfs_get_user_props(zhp);
4645
4646 entry = *plp;
4647 if (entry->pl_all && nvlist_next_nvpair(userprops, NULL) != NULL) {
4648 /*
4649 * Go through and add any user properties as necessary. We
4650 * start by incrementing our list pointer to the first
4651 * non-native property.
4652 */
4653 start = plp;
4654 while (*start != NULL) {
4655 if ((*start)->pl_prop == ZPROP_INVAL)
4656 break;
4657 start = &(*start)->pl_next;
4658 }
4659
4660 elem = NULL;
4661 while ((elem = nvlist_next_nvpair(userprops, elem)) != NULL) {
4662 /*
4663 * See if we've already found this property in our list.
4664 */
4665 for (last = start; *last != NULL;
4666 last = &(*last)->pl_next) {
4667 if (strcmp((*last)->pl_user_prop,
4668 nvpair_name(elem)) == 0)
4669 break;
4670 }
4671
4672 if (*last == NULL) {
4673 if ((entry = zfs_alloc(hdl,
4674 sizeof (zprop_list_t))) == NULL ||
4675 ((entry->pl_user_prop = zfs_strdup(hdl,
4676 nvpair_name(elem)))) == NULL) {
4677 free(entry);
4678 return (-1);
4679 }
4680
4681 entry->pl_prop = ZPROP_INVAL;
4682 entry->pl_width = strlen(nvpair_name(elem));
4683 entry->pl_all = B_TRUE;
4684 *last = entry;
4685 }
4686 }
4687 }
4688
4689 /*
4690 * Now go through and check the width of any non-fixed columns
4691 */
4692 for (entry = *plp; entry != NULL; entry = entry->pl_next) {
4693 if (entry->pl_fixed && !literal)
4694 continue;
4695
4696 if (entry->pl_prop != ZPROP_INVAL) {
4697 if (zfs_prop_get(zhp, entry->pl_prop,
4698 buf, sizeof (buf), NULL, NULL, 0, literal) == 0) {
4699 if (strlen(buf) > entry->pl_width)
4700 entry->pl_width = strlen(buf);
4701 }
4702 if (received && zfs_prop_get_recvd(zhp,
4703 zfs_prop_to_name(entry->pl_prop),
4704 buf, sizeof (buf), literal) == 0)
4705 if (strlen(buf) > entry->pl_recvd_width)
4706 entry->pl_recvd_width = strlen(buf);
4707 } else {
4708 if (nvlist_lookup_nvlist(userprops, entry->pl_user_prop,
4709 &propval) == 0) {
4710 strval = fnvlist_lookup_string(propval,
4711 ZPROP_VALUE);
4712 if (strlen(strval) > entry->pl_width)
4713 entry->pl_width = strlen(strval);
4714 }
4715 if (received && zfs_prop_get_recvd(zhp,
4716 entry->pl_user_prop,
4717 buf, sizeof (buf), literal) == 0)
4718 if (strlen(buf) > entry->pl_recvd_width)
4719 entry->pl_recvd_width = strlen(buf);
4720 }
4721 }
4722
4723 return (0);
4724 }
4725
4726 void
4727 zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props)
4728 {
4729 nvpair_t *curr;
4730 nvpair_t *next;
4731
4732 /*
4733 * Keep a reference to the props-table against which we prune the
4734 * properties.
4735 */
4736 zhp->zfs_props_table = props;
4737
4738 curr = nvlist_next_nvpair(zhp->zfs_props, NULL);
4739
4740 while (curr) {
4741 zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr));
4742 next = nvlist_next_nvpair(zhp->zfs_props, curr);
4743
4744 /*
4745 * User properties will result in ZPROP_INVAL, and since we
4746 * only know how to prune standard ZFS properties, we always
4747 * leave these in the list. This can also happen if we
4748 * encounter an unknown DSL property (when running older
4749 * software, for example).
4750 */
4751 if (zfs_prop != ZPROP_INVAL && props[zfs_prop] == B_FALSE)
4752 (void) nvlist_remove(zhp->zfs_props,
4753 nvpair_name(curr), nvpair_type(curr));
4754 curr = next;
4755 }
4756 }
4757
4758 static int
4759 zfs_smb_acl_mgmt(libzfs_handle_t *hdl, char *dataset, char *path,
4760 zfs_smb_acl_op_t cmd, char *resource1, char *resource2)
4761 {
4762 zfs_cmd_t zc = {"\0"};
4763 nvlist_t *nvlist = NULL;
4764 int error;
4765
4766 (void) strlcpy(zc.zc_name, dataset, sizeof (zc.zc_name));
4767 (void) strlcpy(zc.zc_value, path, sizeof (zc.zc_value));
4768 zc.zc_cookie = (uint64_t)cmd;
4769
4770 if (cmd == ZFS_SMB_ACL_RENAME) {
4771 if (nvlist_alloc(&nvlist, NV_UNIQUE_NAME, 0) != 0) {
4772 (void) no_memory(hdl);
4773 return (0);
4774 }
4775 }
4776
4777 switch (cmd) {
4778 case ZFS_SMB_ACL_ADD:
4779 case ZFS_SMB_ACL_REMOVE:
4780 (void) strlcpy(zc.zc_string, resource1, sizeof (zc.zc_string));
4781 break;
4782 case ZFS_SMB_ACL_RENAME:
4783 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_SRC,
4784 resource1) != 0) {
4785 (void) no_memory(hdl);
4786 return (-1);
4787 }
4788 if (nvlist_add_string(nvlist, ZFS_SMB_ACL_TARGET,
4789 resource2) != 0) {
4790 (void) no_memory(hdl);
4791 return (-1);
4792 }
4793 if (zcmd_write_src_nvlist(hdl, &zc, nvlist) != 0) {
4794 nvlist_free(nvlist);
4795 return (-1);
4796 }
4797 break;
4798 case ZFS_SMB_ACL_PURGE:
4799 break;
4800 default:
4801 return (-1);
4802 }
4803 error = ioctl(hdl->libzfs_fd, ZFS_IOC_SMB_ACL, &zc);
4804 nvlist_free(nvlist);
4805 return (error);
4806 }
4807
4808 int
4809 zfs_smb_acl_add(libzfs_handle_t *hdl, char *dataset,
4810 char *path, char *resource)
4811 {
4812 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_ADD,
4813 resource, NULL));
4814 }
4815
4816 int
4817 zfs_smb_acl_remove(libzfs_handle_t *hdl, char *dataset,
4818 char *path, char *resource)
4819 {
4820 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_REMOVE,
4821 resource, NULL));
4822 }
4823
4824 int
4825 zfs_smb_acl_purge(libzfs_handle_t *hdl, char *dataset, char *path)
4826 {
4827 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_PURGE,
4828 NULL, NULL));
4829 }
4830
4831 int
4832 zfs_smb_acl_rename(libzfs_handle_t *hdl, char *dataset, char *path,
4833 char *oldname, char *newname)
4834 {
4835 return (zfs_smb_acl_mgmt(hdl, dataset, path, ZFS_SMB_ACL_RENAME,
4836 oldname, newname));
4837 }
4838
4839 int
4840 zfs_userspace(zfs_handle_t *zhp, zfs_userquota_prop_t type,
4841 zfs_userspace_cb_t func, void *arg)
4842 {
4843 zfs_cmd_t zc = {"\0"};
4844 zfs_useracct_t buf[100];
4845 libzfs_handle_t *hdl = zhp->zfs_hdl;
4846 int ret;
4847
4848 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
4849
4850 zc.zc_objset_type = type;
4851 zc.zc_nvlist_dst = (uintptr_t)buf;
4852
4853 for (;;) {
4854 zfs_useracct_t *zua = buf;
4855
4856 zc.zc_nvlist_dst_size = sizeof (buf);
4857 if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) {
4858 if ((errno == ENOTSUP &&
4859 (type == ZFS_PROP_USEROBJUSED ||
4860 type == ZFS_PROP_GROUPOBJUSED ||
4861 type == ZFS_PROP_USEROBJQUOTA ||
4862 type == ZFS_PROP_GROUPOBJQUOTA ||
4863 type == ZFS_PROP_PROJECTOBJUSED ||
4864 type == ZFS_PROP_PROJECTOBJQUOTA ||
4865 type == ZFS_PROP_PROJECTUSED ||
4866 type == ZFS_PROP_PROJECTQUOTA)))
4867 break;
4868
4869 return (zfs_standard_error_fmt(hdl, errno,
4870 dgettext(TEXT_DOMAIN,
4871 "cannot get used/quota for %s"), zc.zc_name));
4872 }
4873 if (zc.zc_nvlist_dst_size == 0)
4874 break;
4875
4876 while (zc.zc_nvlist_dst_size > 0) {
4877 if ((ret = func(arg, zua->zu_domain, zua->zu_rid,
4878 zua->zu_space)) != 0)
4879 return (ret);
4880 zua++;
4881 zc.zc_nvlist_dst_size -= sizeof (zfs_useracct_t);
4882 }
4883 }
4884
4885 return (0);
4886 }
4887
4888 struct holdarg {
4889 nvlist_t *nvl;
4890 const char *snapname;
4891 const char *tag;
4892 boolean_t recursive;
4893 int error;
4894 };
4895
4896 static int
4897 zfs_hold_one(zfs_handle_t *zhp, void *arg)
4898 {
4899 struct holdarg *ha = arg;
4900 char name[ZFS_MAX_DATASET_NAME_LEN];
4901 int rv = 0;
4902
4903 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
4904 ha->snapname) >= sizeof (name))
4905 return (EINVAL);
4906
4907 if (lzc_exists(name))
4908 fnvlist_add_string(ha->nvl, name, ha->tag);
4909
4910 if (ha->recursive)
4911 rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha);
4912 zfs_close(zhp);
4913 return (rv);
4914 }
4915
4916 int
4917 zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag,
4918 boolean_t recursive, int cleanup_fd)
4919 {
4920 int ret;
4921 struct holdarg ha;
4922
4923 ha.nvl = fnvlist_alloc();
4924 ha.snapname = snapname;
4925 ha.tag = tag;
4926 ha.recursive = recursive;
4927 (void) zfs_hold_one(zfs_handle_dup(zhp), &ha);
4928
4929 if (nvlist_empty(ha.nvl)) {
4930 char errbuf[1024];
4931
4932 fnvlist_free(ha.nvl);
4933 ret = ENOENT;
4934 (void) snprintf(errbuf, sizeof (errbuf),
4935 dgettext(TEXT_DOMAIN,
4936 "cannot hold snapshot '%s@%s'"),
4937 zhp->zfs_name, snapname);
4938 (void) zfs_standard_error(zhp->zfs_hdl, ret, errbuf);
4939 return (ret);
4940 }
4941
4942 ret = zfs_hold_nvl(zhp, cleanup_fd, ha.nvl);
4943 fnvlist_free(ha.nvl);
4944
4945 return (ret);
4946 }
4947
4948 int
4949 zfs_hold_nvl(zfs_handle_t *zhp, int cleanup_fd, nvlist_t *holds)
4950 {
4951 int ret;
4952 nvlist_t *errors;
4953 libzfs_handle_t *hdl = zhp->zfs_hdl;
4954 char errbuf[1024];
4955 nvpair_t *elem;
4956
4957 errors = NULL;
4958 ret = lzc_hold(holds, cleanup_fd, &errors);
4959
4960 if (ret == 0) {
4961 /* There may be errors even in the success case. */
4962 fnvlist_free(errors);
4963 return (0);
4964 }
4965
4966 if (nvlist_empty(errors)) {
4967 /* no hold-specific errors */
4968 (void) snprintf(errbuf, sizeof (errbuf),
4969 dgettext(TEXT_DOMAIN, "cannot hold"));
4970 switch (ret) {
4971 case ENOTSUP:
4972 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
4973 "pool must be upgraded"));
4974 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
4975 break;
4976 case EINVAL:
4977 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
4978 break;
4979 default:
4980 (void) zfs_standard_error(hdl, ret, errbuf);
4981 }
4982 }
4983
4984 for (elem = nvlist_next_nvpair(errors, NULL);
4985 elem != NULL;
4986 elem = nvlist_next_nvpair(errors, elem)) {
4987 (void) snprintf(errbuf, sizeof (errbuf),
4988 dgettext(TEXT_DOMAIN,
4989 "cannot hold snapshot '%s'"), nvpair_name(elem));
4990 switch (fnvpair_value_int32(elem)) {
4991 case E2BIG:
4992 /*
4993 * Temporary tags wind up having the ds object id
4994 * prepended. So even if we passed the length check
4995 * above, it's still possible for the tag to wind
4996 * up being slightly too long.
4997 */
4998 (void) zfs_error(hdl, EZFS_TAGTOOLONG, errbuf);
4999 break;
5000 case EINVAL:
5001 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
5002 break;
5003 case EEXIST:
5004 (void) zfs_error(hdl, EZFS_REFTAG_HOLD, errbuf);
5005 break;
5006 default:
5007 (void) zfs_standard_error(hdl,
5008 fnvpair_value_int32(elem), errbuf);
5009 }
5010 }
5011
5012 fnvlist_free(errors);
5013 return (ret);
5014 }
5015
5016 static int
5017 zfs_release_one(zfs_handle_t *zhp, void *arg)
5018 {
5019 struct holdarg *ha = arg;
5020 char name[ZFS_MAX_DATASET_NAME_LEN];
5021 int rv = 0;
5022 nvlist_t *existing_holds;
5023
5024 if (snprintf(name, sizeof (name), "%s@%s", zhp->zfs_name,
5025 ha->snapname) >= sizeof (name)) {
5026 ha->error = EINVAL;
5027 rv = EINVAL;
5028 }
5029
5030 if (lzc_get_holds(name, &existing_holds) != 0) {
5031 ha->error = ENOENT;
5032 } else if (!nvlist_exists(existing_holds, ha->tag)) {
5033 ha->error = ESRCH;
5034 } else {
5035 nvlist_t *torelease = fnvlist_alloc();
5036 fnvlist_add_boolean(torelease, ha->tag);
5037 fnvlist_add_nvlist(ha->nvl, name, torelease);
5038 fnvlist_free(torelease);
5039 }
5040
5041 if (ha->recursive)
5042 rv = zfs_iter_filesystems(zhp, zfs_release_one, ha);
5043 zfs_close(zhp);
5044 return (rv);
5045 }
5046
5047 int
5048 zfs_release(zfs_handle_t *zhp, const char *snapname, const char *tag,
5049 boolean_t recursive)
5050 {
5051 int ret;
5052 struct holdarg ha;
5053 nvlist_t *errors = NULL;
5054 nvpair_t *elem;
5055 libzfs_handle_t *hdl = zhp->zfs_hdl;
5056 char errbuf[1024];
5057
5058 ha.nvl = fnvlist_alloc();
5059 ha.snapname = snapname;
5060 ha.tag = tag;
5061 ha.recursive = recursive;
5062 ha.error = 0;
5063 (void) zfs_release_one(zfs_handle_dup(zhp), &ha);
5064
5065 if (nvlist_empty(ha.nvl)) {
5066 fnvlist_free(ha.nvl);
5067 ret = ha.error;
5068 (void) snprintf(errbuf, sizeof (errbuf),
5069 dgettext(TEXT_DOMAIN,
5070 "cannot release hold from snapshot '%s@%s'"),
5071 zhp->zfs_name, snapname);
5072 if (ret == ESRCH) {
5073 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
5074 } else {
5075 (void) zfs_standard_error(hdl, ret, errbuf);
5076 }
5077 return (ret);
5078 }
5079
5080 ret = lzc_release(ha.nvl, &errors);
5081 fnvlist_free(ha.nvl);
5082
5083 if (ret == 0) {
5084 /* There may be errors even in the success case. */
5085 fnvlist_free(errors);
5086 return (0);
5087 }
5088
5089 if (nvlist_empty(errors)) {
5090 /* no hold-specific errors */
5091 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
5092 "cannot release"));
5093 switch (errno) {
5094 case ENOTSUP:
5095 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5096 "pool must be upgraded"));
5097 (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
5098 break;
5099 default:
5100 (void) zfs_standard_error(hdl, errno, errbuf);
5101 }
5102 }
5103
5104 for (elem = nvlist_next_nvpair(errors, NULL);
5105 elem != NULL;
5106 elem = nvlist_next_nvpair(errors, elem)) {
5107 (void) snprintf(errbuf, sizeof (errbuf),
5108 dgettext(TEXT_DOMAIN,
5109 "cannot release hold from snapshot '%s'"),
5110 nvpair_name(elem));
5111 switch (fnvpair_value_int32(elem)) {
5112 case ESRCH:
5113 (void) zfs_error(hdl, EZFS_REFTAG_RELE, errbuf);
5114 break;
5115 case EINVAL:
5116 (void) zfs_error(hdl, EZFS_BADTYPE, errbuf);
5117 break;
5118 default:
5119 (void) zfs_standard_error(hdl,
5120 fnvpair_value_int32(elem), errbuf);
5121 }
5122 }
5123
5124 fnvlist_free(errors);
5125 return (ret);
5126 }
5127
5128 int
5129 zfs_get_fsacl(zfs_handle_t *zhp, nvlist_t **nvl)
5130 {
5131 zfs_cmd_t zc = {"\0"};
5132 libzfs_handle_t *hdl = zhp->zfs_hdl;
5133 int nvsz = 2048;
5134 void *nvbuf;
5135 int err = 0;
5136 char errbuf[1024];
5137
5138 assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
5139 zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
5140
5141 tryagain:
5142
5143 nvbuf = malloc(nvsz);
5144 if (nvbuf == NULL) {
5145 err = (zfs_error(hdl, EZFS_NOMEM, strerror(errno)));
5146 goto out;
5147 }
5148
5149 zc.zc_nvlist_dst_size = nvsz;
5150 zc.zc_nvlist_dst = (uintptr_t)nvbuf;
5151
5152 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
5153
5154 if (zfs_ioctl(hdl, ZFS_IOC_GET_FSACL, &zc) != 0) {
5155 (void) snprintf(errbuf, sizeof (errbuf),
5156 dgettext(TEXT_DOMAIN, "cannot get permissions on '%s'"),
5157 zc.zc_name);
5158 switch (errno) {
5159 case ENOMEM:
5160 free(nvbuf);
5161 nvsz = zc.zc_nvlist_dst_size;
5162 goto tryagain;
5163
5164 case ENOTSUP:
5165 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5166 "pool must be upgraded"));
5167 err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5168 break;
5169 case EINVAL:
5170 err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5171 break;
5172 case ENOENT:
5173 err = zfs_error(hdl, EZFS_NOENT, errbuf);
5174 break;
5175 default:
5176 err = zfs_standard_error(hdl, errno, errbuf);
5177 break;
5178 }
5179 } else {
5180 /* success */
5181 int rc = nvlist_unpack(nvbuf, zc.zc_nvlist_dst_size, nvl, 0);
5182 if (rc) {
5183 err = zfs_standard_error_fmt(hdl, rc, dgettext(
5184 TEXT_DOMAIN, "cannot get permissions on '%s'"),
5185 zc.zc_name);
5186 }
5187 }
5188
5189 free(nvbuf);
5190 out:
5191 return (err);
5192 }
5193
5194 int
5195 zfs_set_fsacl(zfs_handle_t *zhp, boolean_t un, nvlist_t *nvl)
5196 {
5197 zfs_cmd_t zc = {"\0"};
5198 libzfs_handle_t *hdl = zhp->zfs_hdl;
5199 char *nvbuf;
5200 char errbuf[1024];
5201 size_t nvsz;
5202 int err;
5203
5204 assert(zhp->zfs_type == ZFS_TYPE_VOLUME ||
5205 zhp->zfs_type == ZFS_TYPE_FILESYSTEM);
5206
5207 err = nvlist_size(nvl, &nvsz, NV_ENCODE_NATIVE);
5208 assert(err == 0);
5209
5210 nvbuf = malloc(nvsz);
5211
5212 err = nvlist_pack(nvl, &nvbuf, &nvsz, NV_ENCODE_NATIVE, 0);
5213 assert(err == 0);
5214
5215 zc.zc_nvlist_src_size = nvsz;
5216 zc.zc_nvlist_src = (uintptr_t)nvbuf;
5217 zc.zc_perm_action = un;
5218
5219 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
5220
5221 if (zfs_ioctl(hdl, ZFS_IOC_SET_FSACL, &zc) != 0) {
5222 (void) snprintf(errbuf, sizeof (errbuf),
5223 dgettext(TEXT_DOMAIN, "cannot set permissions on '%s'"),
5224 zc.zc_name);
5225 switch (errno) {
5226 case ENOTSUP:
5227 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5228 "pool must be upgraded"));
5229 err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5230 break;
5231 case EINVAL:
5232 err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5233 break;
5234 case ENOENT:
5235 err = zfs_error(hdl, EZFS_NOENT, errbuf);
5236 break;
5237 default:
5238 err = zfs_standard_error(hdl, errno, errbuf);
5239 break;
5240 }
5241 }
5242
5243 free(nvbuf);
5244
5245 return (err);
5246 }
5247
5248 int
5249 zfs_get_holds(zfs_handle_t *zhp, nvlist_t **nvl)
5250 {
5251 int err;
5252 char errbuf[1024];
5253
5254 err = lzc_get_holds(zhp->zfs_name, nvl);
5255
5256 if (err != 0) {
5257 libzfs_handle_t *hdl = zhp->zfs_hdl;
5258
5259 (void) snprintf(errbuf, sizeof (errbuf),
5260 dgettext(TEXT_DOMAIN, "cannot get holds for '%s'"),
5261 zhp->zfs_name);
5262 switch (err) {
5263 case ENOTSUP:
5264 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
5265 "pool must be upgraded"));
5266 err = zfs_error(hdl, EZFS_BADVERSION, errbuf);
5267 break;
5268 case EINVAL:
5269 err = zfs_error(hdl, EZFS_BADTYPE, errbuf);
5270 break;
5271 case ENOENT:
5272 err = zfs_error(hdl, EZFS_NOENT, errbuf);
5273 break;
5274 default:
5275 err = zfs_standard_error(hdl, errno, errbuf);
5276 break;
5277 }
5278 }
5279
5280 return (err);
5281 }
5282
5283 /*
5284 * The theory of raidz space accounting
5285 *
5286 * The "referenced" property of RAIDZ vdevs is scaled such that a 128KB block
5287 * will "reference" 128KB, even though it allocates more than that, to store the
5288 * parity information (and perhaps skip sectors). This concept of the
5289 * "referenced" (and other DMU space accounting) being lower than the allocated
5290 * space by a constant factor is called "raidz deflation."
5291 *
5292 * As mentioned above, the constant factor for raidz deflation assumes a 128KB
5293 * block size. However, zvols typically have a much smaller block size (default
5294 * 8KB). These smaller blocks may require proportionally much more parity
5295 * information (and perhaps skip sectors). In this case, the change to the
5296 * "referenced" property may be much more than the logical block size.
5297 *
5298 * Suppose a raidz vdev has 5 disks with ashift=12. A 128k block may be written
5299 * as follows.
5300 *
5301 * +-------+-------+-------+-------+-------+
5302 * | disk1 | disk2 | disk3 | disk4 | disk5 |
5303 * +-------+-------+-------+-------+-------+
5304 * | P0 | D0 | D8 | D16 | D24 |
5305 * | P1 | D1 | D9 | D17 | D25 |
5306 * | P2 | D2 | D10 | D18 | D26 |
5307 * | P3 | D3 | D11 | D19 | D27 |
5308 * | P4 | D4 | D12 | D20 | D28 |
5309 * | P5 | D5 | D13 | D21 | D29 |
5310 * | P6 | D6 | D14 | D22 | D30 |
5311 * | P7 | D7 | D15 | D23 | D31 |
5312 * +-------+-------+-------+-------+-------+
5313 *
5314 * Above, notice that 160k was allocated: 8 x 4k parity sectors + 32 x 4k data
5315 * sectors. The dataset's referenced will increase by 128k and the pool's
5316 * allocated and free properties will be adjusted by 160k.
5317 *
5318 * A 4k block written to the same raidz vdev will require two 4k sectors. The
5319 * blank cells represent unallocated space.
5320 *
5321 * +-------+-------+-------+-------+-------+
5322 * | disk1 | disk2 | disk3 | disk4 | disk5 |
5323 * +-------+-------+-------+-------+-------+
5324 * | P0 | D0 | | | |
5325 * +-------+-------+-------+-------+-------+
5326 *
5327 * Above, notice that the 4k block required one sector for parity and another
5328 * for data. vdev_raidz_asize() will return 8k and as such the pool's allocated
5329 * and free properties will be adjusted by 8k. The dataset will not be charged
5330 * 8k. Rather, it will be charged a value that is scaled according to the
5331 * overhead of the 128k block on the same vdev. This 8k allocation will be
5332 * charged 8k * 128k / 160k. 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as
5333 * calculated in the 128k block example above.
5334 *
5335 * Every raidz allocation is sized to be a multiple of nparity+1 sectors. That
5336 * is, every raidz1 allocation will be a multiple of 2 sectors, raidz2
5337 * allocations are a multiple of 3 sectors, and raidz3 allocations are a
5338 * multiple of of 4 sectors. When a block does not fill the required number of
5339 * sectors, skip blocks (sectors) are used.
5340 *
5341 * An 8k block being written to a raidz vdev may be written as follows:
5342 *
5343 * +-------+-------+-------+-------+-------+
5344 * | disk1 | disk2 | disk3 | disk4 | disk5 |
5345 * +-------+-------+-------+-------+-------+
5346 * | P0 | D0 | D1 | S0 | |
5347 * +-------+-------+-------+-------+-------+
5348 *
5349 * In order to maintain the nparity+1 allocation size, a skip block (S0) was
5350 * added. For this 8k block, the pool's allocated and free properties are
5351 * adjusted by 16k and the dataset's referenced is increased by 16k * 128k /
5352 * 160k. Again, 128k is from SPA_OLD_MAXBLOCKSIZE and 160k is as calculated in
5353 * the 128k block example above.
5354 *
5355 * The situation is slightly different for dRAID since the minimum allocation
5356 * size is the full group width. The same 8K block above would be written as
5357 * follows in a dRAID group:
5358 *
5359 * +-------+-------+-------+-------+-------+
5360 * | disk1 | disk2 | disk3 | disk4 | disk5 |
5361 * +-------+-------+-------+-------+-------+
5362 * | P0 | D0 | D1 | S0 | S1 |
5363 * +-------+-------+-------+-------+-------+
5364 *
5365 * Compression may lead to a variety of block sizes being written for the same
5366 * volume or file. There is no clear way to reserve just the amount of space
5367 * that will be required, so the worst case (no compression) is assumed.
5368 * Note that metadata blocks will typically be compressed, so the reservation
5369 * size returned by zvol_volsize_to_reservation() will generally be slightly
5370 * larger than the maximum that the volume can reference.
5371 */
5372
5373 /*
5374 * Derived from function of same name in module/zfs/vdev_raidz.c. Returns the
5375 * amount of space (in bytes) that will be allocated for the specified block
5376 * size. Note that the "referenced" space accounted will be less than this, but
5377 * not necessarily equal to "blksize", due to RAIDZ deflation.
5378 */
5379 static uint64_t
5380 vdev_raidz_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
5381 uint64_t blksize)
5382 {
5383 uint64_t asize, ndata;
5384
5385 ASSERT3U(ndisks, >, nparity);
5386 ndata = ndisks - nparity;
5387 asize = ((blksize - 1) >> ashift) + 1;
5388 asize += nparity * ((asize + ndata - 1) / ndata);
5389 asize = roundup(asize, nparity + 1) << ashift;
5390
5391 return (asize);
5392 }
5393
5394 /*
5395 * Derived from function of same name in module/zfs/vdev_draid.c. Returns the
5396 * amount of space (in bytes) that will be allocated for the specified block
5397 * size.
5398 */
5399 static uint64_t
5400 vdev_draid_asize(uint64_t ndisks, uint64_t nparity, uint64_t ashift,
5401 uint64_t blksize)
5402 {
5403 ASSERT3U(ndisks, >, nparity);
5404 uint64_t ndata = ndisks - nparity;
5405 uint64_t rows = ((blksize - 1) / (ndata << ashift)) + 1;
5406 uint64_t asize = (rows * ndisks) << ashift;
5407
5408 return (asize);
5409 }
5410
5411 /*
5412 * Determine how much space will be allocated if it lands on the most space-
5413 * inefficient top-level vdev. Returns the size in bytes required to store one
5414 * copy of the volume data. See theory comment above.
5415 */
5416 static uint64_t
5417 volsize_from_vdevs(zpool_handle_t *zhp, uint64_t nblocks, uint64_t blksize)
5418 {
5419 nvlist_t *config, *tree, **vdevs;
5420 uint_t nvdevs;
5421 uint64_t ret = 0;
5422
5423 config = zpool_get_config(zhp, NULL);
5424 if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &tree) != 0 ||
5425 nvlist_lookup_nvlist_array(tree, ZPOOL_CONFIG_CHILDREN,
5426 &vdevs, &nvdevs) != 0) {
5427 return (nblocks * blksize);
5428 }
5429
5430 for (int v = 0; v < nvdevs; v++) {
5431 char *type;
5432 uint64_t nparity, ashift, asize, tsize;
5433 uint64_t volsize;
5434
5435 if (nvlist_lookup_string(vdevs[v], ZPOOL_CONFIG_TYPE,
5436 &type) != 0)
5437 continue;
5438
5439 if (strcmp(type, VDEV_TYPE_RAIDZ) != 0 &&
5440 strcmp(type, VDEV_TYPE_DRAID) != 0)
5441 continue;
5442
5443 if (nvlist_lookup_uint64(vdevs[v],
5444 ZPOOL_CONFIG_NPARITY, &nparity) != 0)
5445 continue;
5446
5447 if (nvlist_lookup_uint64(vdevs[v],
5448 ZPOOL_CONFIG_ASHIFT, &ashift) != 0)
5449 continue;
5450
5451 if (strcmp(type, VDEV_TYPE_RAIDZ) == 0) {
5452 nvlist_t **disks;
5453 uint_t ndisks;
5454
5455 if (nvlist_lookup_nvlist_array(vdevs[v],
5456 ZPOOL_CONFIG_CHILDREN, &disks, &ndisks) != 0)
5457 continue;
5458
5459 /* allocation size for the "typical" 128k block */
5460 tsize = vdev_raidz_asize(ndisks, nparity, ashift,
5461 SPA_OLD_MAXBLOCKSIZE);
5462
5463 /* allocation size for the blksize block */
5464 asize = vdev_raidz_asize(ndisks, nparity, ashift,
5465 blksize);
5466 } else {
5467 uint64_t ndata;
5468
5469 if (nvlist_lookup_uint64(vdevs[v],
5470 ZPOOL_CONFIG_DRAID_NDATA, &ndata) != 0)
5471 continue;
5472
5473 /* allocation size for the "typical" 128k block */
5474 tsize = vdev_draid_asize(ndata + nparity, nparity,
5475 ashift, SPA_OLD_MAXBLOCKSIZE);
5476
5477 /* allocation size for the blksize block */
5478 asize = vdev_draid_asize(ndata + nparity, nparity,
5479 ashift, blksize);
5480 }
5481
5482 /*
5483 * Scale this size down as a ratio of 128k / tsize.
5484 * See theory statement above.
5485 */
5486 volsize = nblocks * asize * SPA_OLD_MAXBLOCKSIZE / tsize;
5487 if (volsize > ret) {
5488 ret = volsize;
5489 }
5490 }
5491
5492 if (ret == 0) {
5493 ret = nblocks * blksize;
5494 }
5495
5496 return (ret);
5497 }
5498
5499 /*
5500 * Convert the zvol's volume size to an appropriate reservation. See theory
5501 * comment above.
5502 *
5503 * Note: If this routine is updated, it is necessary to update the ZFS test
5504 * suite's shell version in reservation.shlib.
5505 */
5506 uint64_t
5507 zvol_volsize_to_reservation(zpool_handle_t *zph, uint64_t volsize,
5508 nvlist_t *props)
5509 {
5510 uint64_t numdb;
5511 uint64_t nblocks, volblocksize;
5512 int ncopies;
5513 char *strval;
5514
5515 if (nvlist_lookup_string(props,
5516 zfs_prop_to_name(ZFS_PROP_COPIES), &strval) == 0)
5517 ncopies = atoi(strval);
5518 else
5519 ncopies = 1;
5520 if (nvlist_lookup_uint64(props,
5521 zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
5522 &volblocksize) != 0)
5523 volblocksize = ZVOL_DEFAULT_BLOCKSIZE;
5524
5525 nblocks = volsize / volblocksize;
5526 /*
5527 * Metadata defaults to using 128k blocks, not volblocksize blocks. For
5528 * this reason, only the data blocks are scaled based on vdev config.
5529 */
5530 volsize = volsize_from_vdevs(zph, nblocks, volblocksize);
5531
5532 /* start with metadnode L0-L6 */
5533 numdb = 7;
5534 /* calculate number of indirects */
5535 while (nblocks > 1) {
5536 nblocks += DNODES_PER_LEVEL - 1;
5537 nblocks /= DNODES_PER_LEVEL;
5538 numdb += nblocks;
5539 }
5540 numdb *= MIN(SPA_DVAS_PER_BP, ncopies + 1);
5541 volsize *= ncopies;
5542 /*
5543 * this is exactly DN_MAX_INDBLKSHIFT when metadata isn't
5544 * compressed, but in practice they compress down to about
5545 * 1100 bytes
5546 */
5547 numdb *= 1ULL << DN_MAX_INDBLKSHIFT;
5548 volsize += numdb;
5549 return (volsize);
5550 }
5551
5552 /*
5553 * Wait for the given activity and return the status of the wait (whether or not
5554 * any waiting was done) in the 'waited' parameter. Non-existent fses are
5555 * reported via the 'missing' parameter, rather than by printing an error
5556 * message. This is convenient when this function is called in a loop over a
5557 * long period of time (as it is, for example, by zfs's wait cmd). In that
5558 * scenario, a fs being exported or destroyed should be considered a normal
5559 * event, so we don't want to print an error when we find that the fs doesn't
5560 * exist.
5561 */
5562 int
5563 zfs_wait_status(zfs_handle_t *zhp, zfs_wait_activity_t activity,
5564 boolean_t *missing, boolean_t *waited)
5565 {
5566 int error = lzc_wait_fs(zhp->zfs_name, activity, waited);
5567 *missing = (error == ENOENT);
5568 if (*missing)
5569 return (0);
5570
5571 if (error != 0) {
5572 (void) zfs_standard_error_fmt(zhp->zfs_hdl, error,
5573 dgettext(TEXT_DOMAIN, "error waiting in fs '%s'"),
5574 zhp->zfs_name);
5575 }
5576
5577 return (error);
5578 }