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