1390 #endif
1391 /* FALLTHROUGH */
1392 default:
1393 (void) zfs_standard_error(hdl, err, errbuf);
1394 }
1395 }
1396
1397 /*
1398 * Given a property name and value, set the property for the given dataset.
1399 */
1400 int
1401 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1402 {
1403 zfs_cmd_t zc = { 0 };
1404 int ret = -1;
1405 prop_changelist_t *cl = NULL;
1406 char errbuf[1024];
1407 libzfs_handle_t *hdl = zhp->zfs_hdl;
1408 nvlist_t *nvl = NULL, *realprops;
1409 zfs_prop_t prop;
1410 boolean_t do_prefix;
1411 uint64_t idx;
1412 int added_resv;
1413
1414 (void) snprintf(errbuf, sizeof (errbuf),
1415 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1416 zhp->zfs_name);
1417
1418 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1419 nvlist_add_string(nvl, propname, propval) != 0) {
1420 (void) no_memory(hdl);
1421 goto error;
1422 }
1423
1424 if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
1425 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1426 goto error;
1427
1428 nvlist_free(nvl);
1429 nvl = realprops;
1430
1431 prop = zfs_name_to_prop(propname);
1432
1433 if (prop == ZFS_PROP_VOLSIZE) {
1434 if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
1435 goto error;
1436 }
1437
1438 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1439 goto error;
1440
1441 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1442 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1443 "child dataset with inherited mountpoint is used "
1444 "in a non-global zone"));
1445 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1446 goto error;
1447 }
1448
1449 /*
1450 * If the dataset's canmount property is being set to noauto,
1451 * then we want to prevent unmounting & remounting it.
1452 */
1453 do_prefix = !((prop == ZFS_PROP_CANMOUNT) &&
1454 (zprop_string_to_index(prop, propval, &idx,
1455 ZFS_TYPE_DATASET) == 0) && (idx == ZFS_CANMOUNT_NOAUTO));
1456
1457 if (do_prefix && (ret = changelist_prefix(cl)) != 0)
1458 goto error;
1459
1460 /*
1461 * Execute the corresponding ioctl() to set this property.
1462 */
1463 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1464
1465 if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1466 goto error;
1467
1468 ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1469
1470 if (ret != 0) {
1471 zfs_setprop_error(hdl, prop, errno, errbuf);
1472 if (added_resv && errno == ENOSPC) {
1473 /* clean up the volsize property we tried to set */
1474 uint64_t old_volsize = zfs_prop_get_int(zhp,
1475 ZFS_PROP_VOLSIZE);
2624 int
2625 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
2626 char *propbuf, int proplen, boolean_t literal)
2627 {
2628 int err;
2629 uint64_t propvalue;
2630
2631 err = zfs_prop_get_written_int(zhp, propname, &propvalue);
2632
2633 if (err)
2634 return (err);
2635
2636 if (literal) {
2637 (void) snprintf(propbuf, proplen, "%llu", propvalue);
2638 } else {
2639 zfs_nicenum(propvalue, propbuf, proplen);
2640 }
2641 return (0);
2642 }
2643
2644 int
2645 zfs_get_snapused_int(zfs_handle_t *firstsnap, zfs_handle_t *lastsnap,
2646 uint64_t *usedp)
2647 {
2648 int err;
2649 zfs_cmd_t zc = { 0 };
2650
2651 (void) strlcpy(zc.zc_name, lastsnap->zfs_name, sizeof (zc.zc_name));
2652 (void) strlcpy(zc.zc_value, firstsnap->zfs_name, sizeof (zc.zc_value));
2653
2654 err = ioctl(lastsnap->zfs_hdl->libzfs_fd, ZFS_IOC_SPACE_SNAPS, &zc);
2655 if (err)
2656 return (err);
2657
2658 *usedp = zc.zc_cookie;
2659
2660 return (0);
2661 }
2662
2663 /*
2664 * Returns the name of the given zfs handle.
2665 */
2666 const char *
2667 zfs_get_name(const zfs_handle_t *zhp)
2668 {
2669 return (zhp->zfs_name);
2670 }
2671
2672 /*
2673 * Returns the type of the given zfs handle.
2674 */
2675 zfs_type_t
2676 zfs_get_type(const zfs_handle_t *zhp)
2677 {
2678 return (zhp->zfs_type);
2679 }
2680
2681 /*
2682 * Is one dataset name a child dataset of another?
2843 /* make sure prefix exists */
2844 cp = target + prefixlen;
2845 if (*cp != '/') {
2846 assert(strchr(cp, '/') == NULL);
2847 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2848 } else {
2849 *cp = '\0';
2850 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2851 *cp = '/';
2852 }
2853 if (h == NULL)
2854 return (-1);
2855 zfs_close(h);
2856
2857 /*
2858 * Attempt to create, mount, and share any ancestor filesystems,
2859 * up to the prefixlen-long one.
2860 */
2861 for (cp = target + prefixlen + 1;
2862 cp = strchr(cp, '/'); *cp = '/', cp++) {
2863 char *logstr;
2864
2865 *cp = '\0';
2866
2867 h = make_dataset_handle(hdl, target);
2868 if (h) {
2869 /* it already exists, nothing to do here */
2870 zfs_close(h);
2871 continue;
2872 }
2873
2874 logstr = hdl->libzfs_log_str;
2875 hdl->libzfs_log_str = NULL;
2876 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2877 NULL) != 0) {
2878 hdl->libzfs_log_str = logstr;
2879 opname = dgettext(TEXT_DOMAIN, "create");
2880 goto ancestorerr;
2881 }
2882
2883 hdl->libzfs_log_str = logstr;
2884 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2885 if (h == NULL) {
2886 opname = dgettext(TEXT_DOMAIN, "open");
2887 goto ancestorerr;
2888 }
2889
2890 if (zfs_mount(h, NULL, 0) != 0) {
2891 opname = dgettext(TEXT_DOMAIN, "mount");
2892 goto ancestorerr;
2893 }
2894
2895 if (zfs_share(h) != 0) {
2896 opname = dgettext(TEXT_DOMAIN, "share");
2897 goto ancestorerr;
2898 }
2899
2900 zfs_close(h);
2901 }
2902
2903 return (0);
2921 if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
2922 return (-1);
2923
2924 if ((path_copy = strdup(path)) != NULL) {
2925 rc = create_parents(hdl, path_copy, prefix);
2926 free(path_copy);
2927 }
2928 if (path_copy == NULL || rc != 0)
2929 return (-1);
2930
2931 return (0);
2932 }
2933
2934 /*
2935 * Create a new filesystem or volume.
2936 */
2937 int
2938 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2939 nvlist_t *props)
2940 {
2941 zfs_cmd_t zc = { 0 };
2942 int ret;
2943 uint64_t size = 0;
2944 uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2945 char errbuf[1024];
2946 uint64_t zoned;
2947
2948 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2949 "cannot create '%s'"), path);
2950
2951 /* validate the path, taking care to note the extended error message */
2952 if (!zfs_validate_name(hdl, path, type, B_TRUE))
2953 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2954
2955 /* validate parents exist */
2956 if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
2957 return (-1);
2958
2959 /*
2960 * The failure modes when creating a dataset of a different type over
2961 * one that already exists is a little strange. In particular, if you
2962 * try to create a dataset on top of an existing dataset, the ioctl()
2963 * will return ENOENT, not EEXIST. To prevent this from happening, we
2964 * first try to see if the dataset exists.
2965 */
2966 (void) strlcpy(zc.zc_name, path, sizeof (zc.zc_name));
2967 if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
2968 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2969 "dataset already exists"));
2970 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2971 }
2972
2973 if (type == ZFS_TYPE_VOLUME)
2974 zc.zc_objset_type = DMU_OST_ZVOL;
2975 else
2976 zc.zc_objset_type = DMU_OST_ZFS;
2977
2978 if (props && (props = zfs_valid_proplist(hdl, type, props,
2979 zoned, NULL, errbuf)) == 0)
2980 return (-1);
2981
2982 if (type == ZFS_TYPE_VOLUME) {
2983 /*
2984 * If we are creating a volume, the size and block size must
2985 * satisfy a few restraints. First, the blocksize must be a
2986 * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the
2987 * volsize must be a multiple of the block size, and cannot be
2988 * zero.
2989 */
2990 if (props == NULL || nvlist_lookup_uint64(props,
2991 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
2992 nvlist_free(props);
2993 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2994 "missing volume size"));
2995 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2996 }
3008 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3009 }
3010 }
3011
3012 if (size == 0) {
3013 nvlist_free(props);
3014 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3015 "volume size cannot be zero"));
3016 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3017 }
3018
3019 if (size % blocksize != 0) {
3020 nvlist_free(props);
3021 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3022 "volume size must be a multiple of volume block "
3023 "size"));
3024 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3025 }
3026 }
3027
3028 if (props && zcmd_write_src_nvlist(hdl, &zc, props) != 0)
3029 return (-1);
3030 nvlist_free(props);
3031
3032 /* create the dataset */
3033 ret = zfs_ioctl(hdl, ZFS_IOC_CREATE, &zc);
3034
3035 zcmd_free_nvlists(&zc);
3036
3037 /* check for failure */
3038 if (ret != 0) {
3039 char parent[ZFS_MAXNAMELEN];
3040 (void) parent_name(path, parent, sizeof (parent));
3041
3042 switch (errno) {
3043 case ENOENT:
3044 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3045 "no such parent '%s'"), parent);
3046 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3047
3048 case EINVAL:
3049 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3050 "parent '%s' is not a filesystem"), parent);
3051 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3052
3053 case EDOM:
3054 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3055 "volume block size must be power of 2 from "
3153
3154 if (nvlist_next_nvpair(dd.nvl, NULL) == NULL) {
3155 ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3156 dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3157 zhp->zfs_name, snapname);
3158 } else {
3159 ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer);
3160 }
3161 nvlist_free(dd.nvl);
3162 return (ret);
3163 }
3164
3165 /*
3166 * Destroys all the snapshots named in the nvlist. They must be underneath
3167 * the zhp (either snapshots of it, or snapshots of its descendants).
3168 */
3169 int
3170 zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
3171 {
3172 int ret;
3173 zfs_cmd_t zc = { 0 };
3174
3175 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3176 if (zcmd_write_src_nvlist(zhp->zfs_hdl, &zc, snaps) != 0)
3177 return (-1);
3178 zc.zc_defer_destroy = defer;
3179
3180 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_DESTROY_SNAPS_NVL, &zc);
3181 if (ret != 0) {
3182 char errbuf[1024];
3183
3184 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3185 "cannot destroy snapshots in %s"), zc.zc_name);
3186
3187 switch (errno) {
3188 case EEXIST:
3189 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3190 "snapshot is cloned"));
3191 return (zfs_error(zhp->zfs_hdl, EZFS_EXISTS, errbuf));
3192
3193 default:
3194 return (zfs_standard_error(zhp->zfs_hdl, errno,
3195 errbuf));
3196 }
3197 }
3198
3199 return (0);
3200 }
3201
3202 /*
3203 * Clones the given dataset. The target must be of the same type as the source.
3204 */
3205 int
3206 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3207 {
3208 zfs_cmd_t zc = { 0 };
3209 char parent[ZFS_MAXNAMELEN];
3210 int ret;
3211 char errbuf[1024];
3212 libzfs_handle_t *hdl = zhp->zfs_hdl;
3213 zfs_type_t type;
3214 uint64_t zoned;
3215
3216 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3217
3218 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3219 "cannot create '%s'"), target);
3220
3221 /* validate the target/clone name */
3222 if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3223 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3224
3225 /* validate parents exist */
3226 if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3227 return (-1);
3228
3229 (void) parent_name(target, parent, sizeof (parent));
3230
3231 /* do the clone */
3232 if (ZFS_IS_VOLUME(zhp)) {
3233 zc.zc_objset_type = DMU_OST_ZVOL;
3234 type = ZFS_TYPE_VOLUME;
3235 } else {
3236 zc.zc_objset_type = DMU_OST_ZFS;
3237 type = ZFS_TYPE_FILESYSTEM;
3238 }
3239
3240 if (props) {
3241 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3242 zhp, errbuf)) == NULL)
3243 return (-1);
3244
3245 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3246 nvlist_free(props);
3247 return (-1);
3248 }
3249
3250 nvlist_free(props);
3251 }
3252
3253 (void) strlcpy(zc.zc_name, target, sizeof (zc.zc_name));
3254 (void) strlcpy(zc.zc_value, zhp->zfs_name, sizeof (zc.zc_value));
3255 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_CREATE, &zc);
3256
3257 zcmd_free_nvlists(&zc);
3258
3259 if (ret != 0) {
3260 switch (errno) {
3261
3262 case ENOENT:
3263 /*
3264 * The parent doesn't exist. We should have caught this
3265 * above, but there may a race condition that has since
3266 * destroyed the parent.
3267 *
3268 * At this point, we don't know whether it's the source
3269 * that doesn't exist anymore, or whether the target
3270 * dataset doesn't exist.
3271 */
3272 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3273 "no such parent '%s'"), parent);
3274 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3275
3276 case EXDEV:
3277 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3322 ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
3323
3324 if (ret != 0) {
3325 int save_errno = errno;
3326
3327 switch (save_errno) {
3328 case EEXIST:
3329 /* There is a conflicting snapshot name. */
3330 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3331 "conflicting snapshot '%s' from parent '%s'"),
3332 zc.zc_string, parent);
3333 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3334
3335 default:
3336 return (zfs_standard_error(hdl, save_errno, errbuf));
3337 }
3338 }
3339 return (ret);
3340 }
3341
3342 /*
3343 * Takes a snapshot of the given dataset.
3344 */
3345 int
3346 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3347 nvlist_t *props)
3348 {
3349 const char *delim;
3350 char parent[ZFS_MAXNAMELEN];
3351 zfs_handle_t *zhp;
3352 zfs_cmd_t zc = { 0 };
3353 int ret;
3354 char errbuf[1024];
3355
3356 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3357 "cannot snapshot '%s'"), path);
3358
3359 /* validate the target name */
3360 if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3361 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3362
3363 if (props) {
3364 if ((props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3365 props, B_FALSE, NULL, errbuf)) == NULL)
3366 return (-1);
3367
3368 if (zcmd_write_src_nvlist(hdl, &zc, props) != 0) {
3369 nvlist_free(props);
3370 return (-1);
3371 }
3372
3373 nvlist_free(props);
3374 }
3375
3376 /* make sure the parent exists and is of the appropriate type */
3377 delim = strchr(path, '@');
3378 (void) strncpy(parent, path, delim - path);
3379 parent[delim - path] = '\0';
3380
3381 if ((zhp = zfs_open(hdl, parent, ZFS_TYPE_FILESYSTEM |
3382 ZFS_TYPE_VOLUME)) == NULL) {
3383 zcmd_free_nvlists(&zc);
3384 return (-1);
3385 }
3386
3387 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
3388 (void) strlcpy(zc.zc_value, delim+1, sizeof (zc.zc_value));
3389 if (ZFS_IS_VOLUME(zhp))
3390 zc.zc_objset_type = DMU_OST_ZVOL;
3391 else
3392 zc.zc_objset_type = DMU_OST_ZFS;
3393 zc.zc_cookie = recursive;
3394 ret = zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SNAPSHOT, &zc);
3395
3396 zcmd_free_nvlists(&zc);
3397
3398 /*
3399 * if it was recursive, the one that actually failed will be in
3400 * zc.zc_name.
3401 */
3402 if (ret != 0) {
3403 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3404 "cannot create snapshot '%s@%s'"), zc.zc_name, zc.zc_value);
3405 (void) zfs_standard_error(hdl, errno, errbuf);
3406 }
3407
3408 zfs_close(zhp);
3409
3410 return (ret);
3411 }
3412
3413 /*
3414 * Destroy any more recent snapshots. We invoke this callback on any dependents
3415 * of the snapshot first. If the 'cb_dependent' member is non-zero, then this
3416 * is a dependent and we should just destroy it without checking the transaction
3417 * group.
3418 */
3419 typedef struct rollback_data {
3420 const char *cb_target; /* the snapshot */
3421 uint64_t cb_create; /* creation time reference */
3422 boolean_t cb_error;
3423 boolean_t cb_dependent;
3424 boolean_t cb_force;
3425 } rollback_data_t;
3426
3427 static int
3428 rollback_destroy(zfs_handle_t *zhp, void *data)
3429 {
3430 rollback_data_t *cbp = data;
3431
3432 if (!cbp->cb_dependent) {
3433 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
3434 zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
3435 zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
3436 cbp->cb_create) {
3437 char *logstr;
3438
3439 cbp->cb_dependent = B_TRUE;
3440 cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3441 rollback_destroy, cbp);
3442 cbp->cb_dependent = B_FALSE;
3443
3444 logstr = zhp->zfs_hdl->libzfs_log_str;
3445 zhp->zfs_hdl->libzfs_log_str = NULL;
3446 cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
3447 zhp->zfs_hdl->libzfs_log_str = logstr;
3448 }
3449 } else {
3450 /* We must destroy this clone; first unmount it */
3451 prop_changelist_t *clp;
3452
3453 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3454 cbp->cb_force ? MS_FORCE: 0);
3455 if (clp == NULL || changelist_prefix(clp) != 0) {
3456 cbp->cb_error = B_TRUE;
3457 zfs_close(zhp);
3458 return (0);
3459 }
3460 if (zfs_destroy(zhp, B_FALSE) != 0)
3461 cbp->cb_error = B_TRUE;
3462 else
3463 changelist_remove(clp, zhp->zfs_name);
3464 (void) changelist_postfix(clp);
3465 changelist_free(clp);
3466 }
3467
|
1390 #endif
1391 /* FALLTHROUGH */
1392 default:
1393 (void) zfs_standard_error(hdl, err, errbuf);
1394 }
1395 }
1396
1397 /*
1398 * Given a property name and value, set the property for the given dataset.
1399 */
1400 int
1401 zfs_prop_set(zfs_handle_t *zhp, const char *propname, const char *propval)
1402 {
1403 zfs_cmd_t zc = { 0 };
1404 int ret = -1;
1405 prop_changelist_t *cl = NULL;
1406 char errbuf[1024];
1407 libzfs_handle_t *hdl = zhp->zfs_hdl;
1408 nvlist_t *nvl = NULL, *realprops;
1409 zfs_prop_t prop;
1410 boolean_t do_prefix = B_TRUE;
1411 int added_resv;
1412
1413 (void) snprintf(errbuf, sizeof (errbuf),
1414 dgettext(TEXT_DOMAIN, "cannot set property for '%s'"),
1415 zhp->zfs_name);
1416
1417 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0 ||
1418 nvlist_add_string(nvl, propname, propval) != 0) {
1419 (void) no_memory(hdl);
1420 goto error;
1421 }
1422
1423 if ((realprops = zfs_valid_proplist(hdl, zhp->zfs_type, nvl,
1424 zfs_prop_get_int(zhp, ZFS_PROP_ZONED), zhp, errbuf)) == NULL)
1425 goto error;
1426
1427 nvlist_free(nvl);
1428 nvl = realprops;
1429
1430 prop = zfs_name_to_prop(propname);
1431
1432 if (prop == ZFS_PROP_VOLSIZE) {
1433 if ((added_resv = zfs_add_synthetic_resv(zhp, nvl)) == -1)
1434 goto error;
1435 }
1436
1437 if ((cl = changelist_gather(zhp, prop, 0, 0)) == NULL)
1438 goto error;
1439
1440 if (prop == ZFS_PROP_MOUNTPOINT && changelist_haszonedchild(cl)) {
1441 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1442 "child dataset with inherited mountpoint is used "
1443 "in a non-global zone"));
1444 ret = zfs_error(hdl, EZFS_ZONED, errbuf);
1445 goto error;
1446 }
1447
1448 /*
1449 * We don't want to unmount & remount the dataset when changing
1450 * its canmount property to 'on' or 'noauto'. We only use
1451 * the changelist logic to unmount when setting canmount=off.
1452 */
1453 if (prop == ZFS_PROP_CANMOUNT) {
1454 uint64_t idx;
1455 int err = zprop_string_to_index(prop, propval, &idx,
1456 ZFS_TYPE_DATASET);
1457 if (err == 0 && idx != ZFS_CANMOUNT_OFF)
1458 do_prefix = B_FALSE;
1459 }
1460
1461 if (do_prefix && (ret = changelist_prefix(cl)) != 0)
1462 goto error;
1463
1464 /*
1465 * Execute the corresponding ioctl() to set this property.
1466 */
1467 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1468
1469 if (zcmd_write_src_nvlist(hdl, &zc, nvl) != 0)
1470 goto error;
1471
1472 ret = zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc);
1473
1474 if (ret != 0) {
1475 zfs_setprop_error(hdl, prop, errno, errbuf);
1476 if (added_resv && errno == ENOSPC) {
1477 /* clean up the volsize property we tried to set */
1478 uint64_t old_volsize = zfs_prop_get_int(zhp,
1479 ZFS_PROP_VOLSIZE);
2628 int
2629 zfs_prop_get_written(zfs_handle_t *zhp, const char *propname,
2630 char *propbuf, int proplen, boolean_t literal)
2631 {
2632 int err;
2633 uint64_t propvalue;
2634
2635 err = zfs_prop_get_written_int(zhp, propname, &propvalue);
2636
2637 if (err)
2638 return (err);
2639
2640 if (literal) {
2641 (void) snprintf(propbuf, proplen, "%llu", propvalue);
2642 } else {
2643 zfs_nicenum(propvalue, propbuf, proplen);
2644 }
2645 return (0);
2646 }
2647
2648 /*
2649 * Returns the name of the given zfs handle.
2650 */
2651 const char *
2652 zfs_get_name(const zfs_handle_t *zhp)
2653 {
2654 return (zhp->zfs_name);
2655 }
2656
2657 /*
2658 * Returns the type of the given zfs handle.
2659 */
2660 zfs_type_t
2661 zfs_get_type(const zfs_handle_t *zhp)
2662 {
2663 return (zhp->zfs_type);
2664 }
2665
2666 /*
2667 * Is one dataset name a child dataset of another?
2828 /* make sure prefix exists */
2829 cp = target + prefixlen;
2830 if (*cp != '/') {
2831 assert(strchr(cp, '/') == NULL);
2832 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2833 } else {
2834 *cp = '\0';
2835 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2836 *cp = '/';
2837 }
2838 if (h == NULL)
2839 return (-1);
2840 zfs_close(h);
2841
2842 /*
2843 * Attempt to create, mount, and share any ancestor filesystems,
2844 * up to the prefixlen-long one.
2845 */
2846 for (cp = target + prefixlen + 1;
2847 cp = strchr(cp, '/'); *cp = '/', cp++) {
2848
2849 *cp = '\0';
2850
2851 h = make_dataset_handle(hdl, target);
2852 if (h) {
2853 /* it already exists, nothing to do here */
2854 zfs_close(h);
2855 continue;
2856 }
2857
2858 if (zfs_create(hdl, target, ZFS_TYPE_FILESYSTEM,
2859 NULL) != 0) {
2860 opname = dgettext(TEXT_DOMAIN, "create");
2861 goto ancestorerr;
2862 }
2863
2864 h = zfs_open(hdl, target, ZFS_TYPE_FILESYSTEM);
2865 if (h == NULL) {
2866 opname = dgettext(TEXT_DOMAIN, "open");
2867 goto ancestorerr;
2868 }
2869
2870 if (zfs_mount(h, NULL, 0) != 0) {
2871 opname = dgettext(TEXT_DOMAIN, "mount");
2872 goto ancestorerr;
2873 }
2874
2875 if (zfs_share(h) != 0) {
2876 opname = dgettext(TEXT_DOMAIN, "share");
2877 goto ancestorerr;
2878 }
2879
2880 zfs_close(h);
2881 }
2882
2883 return (0);
2901 if (check_parents(hdl, path, NULL, B_TRUE, &prefix) != 0)
2902 return (-1);
2903
2904 if ((path_copy = strdup(path)) != NULL) {
2905 rc = create_parents(hdl, path_copy, prefix);
2906 free(path_copy);
2907 }
2908 if (path_copy == NULL || rc != 0)
2909 return (-1);
2910
2911 return (0);
2912 }
2913
2914 /*
2915 * Create a new filesystem or volume.
2916 */
2917 int
2918 zfs_create(libzfs_handle_t *hdl, const char *path, zfs_type_t type,
2919 nvlist_t *props)
2920 {
2921 int ret;
2922 uint64_t size = 0;
2923 uint64_t blocksize = zfs_prop_default_numeric(ZFS_PROP_VOLBLOCKSIZE);
2924 char errbuf[1024];
2925 uint64_t zoned;
2926 dmu_objset_type_t ost;
2927
2928 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2929 "cannot create '%s'"), path);
2930
2931 /* validate the path, taking care to note the extended error message */
2932 if (!zfs_validate_name(hdl, path, type, B_TRUE))
2933 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2934
2935 /* validate parents exist */
2936 if (check_parents(hdl, path, &zoned, B_FALSE, NULL) != 0)
2937 return (-1);
2938
2939 /*
2940 * The failure modes when creating a dataset of a different type over
2941 * one that already exists is a little strange. In particular, if you
2942 * try to create a dataset on top of an existing dataset, the ioctl()
2943 * will return ENOENT, not EEXIST. To prevent this from happening, we
2944 * first try to see if the dataset exists.
2945 */
2946 if (zfs_dataset_exists(hdl, path, ZFS_TYPE_DATASET)) {
2947 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2948 "dataset already exists"));
2949 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
2950 }
2951
2952 if (type == ZFS_TYPE_VOLUME)
2953 ost = DMU_OST_ZVOL;
2954 else
2955 ost = DMU_OST_ZFS;
2956
2957 if (props && (props = zfs_valid_proplist(hdl, type, props,
2958 zoned, NULL, errbuf)) == 0)
2959 return (-1);
2960
2961 if (type == ZFS_TYPE_VOLUME) {
2962 /*
2963 * If we are creating a volume, the size and block size must
2964 * satisfy a few restraints. First, the blocksize must be a
2965 * valid block size between SPA_{MIN,MAX}BLOCKSIZE. Second, the
2966 * volsize must be a multiple of the block size, and cannot be
2967 * zero.
2968 */
2969 if (props == NULL || nvlist_lookup_uint64(props,
2970 zfs_prop_to_name(ZFS_PROP_VOLSIZE), &size) != 0) {
2971 nvlist_free(props);
2972 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2973 "missing volume size"));
2974 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2975 }
2987 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2988 }
2989 }
2990
2991 if (size == 0) {
2992 nvlist_free(props);
2993 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2994 "volume size cannot be zero"));
2995 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
2996 }
2997
2998 if (size % blocksize != 0) {
2999 nvlist_free(props);
3000 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3001 "volume size must be a multiple of volume block "
3002 "size"));
3003 return (zfs_error(hdl, EZFS_BADPROP, errbuf));
3004 }
3005 }
3006
3007 /* create the dataset */
3008 ret = lzc_create(path, ost, props);
3009 nvlist_free(props);
3010
3011 /* check for failure */
3012 if (ret != 0) {
3013 char parent[ZFS_MAXNAMELEN];
3014 (void) parent_name(path, parent, sizeof (parent));
3015
3016 switch (errno) {
3017 case ENOENT:
3018 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3019 "no such parent '%s'"), parent);
3020 return (zfs_error(hdl, EZFS_NOENT, errbuf));
3021
3022 case EINVAL:
3023 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3024 "parent '%s' is not a filesystem"), parent);
3025 return (zfs_error(hdl, EZFS_BADTYPE, errbuf));
3026
3027 case EDOM:
3028 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3029 "volume block size must be power of 2 from "
3127
3128 if (nvlist_next_nvpair(dd.nvl, NULL) == NULL) {
3129 ret = zfs_standard_error_fmt(zhp->zfs_hdl, ENOENT,
3130 dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"),
3131 zhp->zfs_name, snapname);
3132 } else {
3133 ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer);
3134 }
3135 nvlist_free(dd.nvl);
3136 return (ret);
3137 }
3138
3139 /*
3140 * Destroys all the snapshots named in the nvlist. They must be underneath
3141 * the zhp (either snapshots of it, or snapshots of its descendants).
3142 */
3143 int
3144 zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer)
3145 {
3146 int ret;
3147 nvlist_t *errlist;
3148
3149 ret = lzc_destroy_snaps(snaps, defer, &errlist);
3150
3151 if (ret != 0) {
3152 for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL);
3153 pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) {
3154 char errbuf[1024];
3155 (void) snprintf(errbuf, sizeof (errbuf),
3156 dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"),
3157 nvpair_name(pair));
3158
3159 switch (fnvpair_value_int32(pair)) {
3160 case EEXIST:
3161 zfs_error_aux(zhp->zfs_hdl,
3162 dgettext(TEXT_DOMAIN,
3163 "snapshot is cloned"));
3164 ret = zfs_error(zhp->zfs_hdl, EZFS_EXISTS,
3165 errbuf);
3166 break;
3167 default:
3168 ret = zfs_standard_error(zhp->zfs_hdl, errno,
3169 errbuf);
3170 break;
3171 }
3172 }
3173 }
3174
3175 return (ret);
3176 }
3177
3178 /*
3179 * Clones the given dataset. The target must be of the same type as the source.
3180 */
3181 int
3182 zfs_clone(zfs_handle_t *zhp, const char *target, nvlist_t *props)
3183 {
3184 char parent[ZFS_MAXNAMELEN];
3185 int ret;
3186 char errbuf[1024];
3187 libzfs_handle_t *hdl = zhp->zfs_hdl;
3188 uint64_t zoned;
3189
3190 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
3191
3192 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3193 "cannot create '%s'"), target);
3194
3195 /* validate the target/clone name */
3196 if (!zfs_validate_name(hdl, target, ZFS_TYPE_FILESYSTEM, B_TRUE))
3197 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3198
3199 /* validate parents exist */
3200 if (check_parents(hdl, target, &zoned, B_FALSE, NULL) != 0)
3201 return (-1);
3202
3203 (void) parent_name(target, parent, sizeof (parent));
3204
3205 /* do the clone */
3206
3207 if (props) {
3208 zfs_type_t type;
3209 if (ZFS_IS_VOLUME(zhp)) {
3210 type = ZFS_TYPE_VOLUME;
3211 } else {
3212 type = ZFS_TYPE_FILESYSTEM;
3213 }
3214 if ((props = zfs_valid_proplist(hdl, type, props, zoned,
3215 zhp, errbuf)) == NULL)
3216 return (-1);
3217 }
3218
3219 ret = lzc_clone(target, zhp->zfs_name, props);
3220 nvlist_free(props);
3221
3222 if (ret != 0) {
3223 switch (errno) {
3224
3225 case ENOENT:
3226 /*
3227 * The parent doesn't exist. We should have caught this
3228 * above, but there may a race condition that has since
3229 * destroyed the parent.
3230 *
3231 * At this point, we don't know whether it's the source
3232 * that doesn't exist anymore, or whether the target
3233 * dataset doesn't exist.
3234 */
3235 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3236 "no such parent '%s'"), parent);
3237 return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
3238
3239 case EXDEV:
3240 zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
3285 ret = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
3286
3287 if (ret != 0) {
3288 int save_errno = errno;
3289
3290 switch (save_errno) {
3291 case EEXIST:
3292 /* There is a conflicting snapshot name. */
3293 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3294 "conflicting snapshot '%s' from parent '%s'"),
3295 zc.zc_string, parent);
3296 return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3297
3298 default:
3299 return (zfs_standard_error(hdl, save_errno, errbuf));
3300 }
3301 }
3302 return (ret);
3303 }
3304
3305 typedef struct snapdata {
3306 nvlist_t *sd_nvl;
3307 const char *sd_snapname;
3308 } snapdata_t;
3309
3310 static int
3311 zfs_snapshot_cb(zfs_handle_t *zhp, void *arg)
3312 {
3313 snapdata_t *sd = arg;
3314 char name[ZFS_MAXNAMELEN];
3315 int rv = 0;
3316
3317 (void) snprintf(name, sizeof (name),
3318 "%s@%s", zfs_get_name(zhp), sd->sd_snapname);
3319
3320 fnvlist_add_boolean(sd->sd_nvl, name);
3321
3322 rv = zfs_iter_filesystems(zhp, zfs_snapshot_cb, sd);
3323 zfs_close(zhp);
3324 return (rv);
3325 }
3326
3327 /*
3328 * Creates snapshots. The keys in the snaps nvlist are the snapshots to be
3329 * created.
3330 */
3331 int
3332 zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, nvlist_t *props)
3333 {
3334 int ret;
3335 char errbuf[1024];
3336 nvpair_t *elem;
3337 nvlist_t *errors;
3338
3339 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3340 "cannot create snapshots "));
3341
3342 elem = NULL;
3343 while ((elem = nvlist_next_nvpair(snaps, elem)) != NULL) {
3344 const char *snapname = nvpair_name(elem);
3345
3346 /* validate the target name */
3347 if (!zfs_validate_name(hdl, snapname, ZFS_TYPE_SNAPSHOT,
3348 B_TRUE)) {
3349 (void) snprintf(errbuf, sizeof (errbuf),
3350 dgettext(TEXT_DOMAIN,
3351 "cannot create snapshot '%s'"), snapname);
3352 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3353 }
3354 }
3355
3356 if (props != NULL &&
3357 (props = zfs_valid_proplist(hdl, ZFS_TYPE_SNAPSHOT,
3358 props, B_FALSE, NULL, errbuf)) == NULL) {
3359 return (-1);
3360 }
3361
3362 ret = lzc_snapshot(snaps, props, &errors);
3363
3364 if (ret != 0) {
3365 boolean_t printed = B_FALSE;
3366 for (elem = nvlist_next_nvpair(errors, NULL);
3367 elem != NULL;
3368 elem = nvlist_next_nvpair(errors, elem)) {
3369 (void) snprintf(errbuf, sizeof (errbuf),
3370 dgettext(TEXT_DOMAIN,
3371 "cannot create snapshot '%s'"), nvpair_name(elem));
3372 (void) zfs_standard_error(hdl,
3373 fnvpair_value_int32(elem), errbuf);
3374 printed = B_TRUE;
3375 }
3376 if (!printed) {
3377 switch (ret) {
3378 case EXDEV:
3379 zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3380 "multiple snapshots of same "
3381 "fs not allowed"));
3382 (void) zfs_error(hdl, EZFS_EXISTS, errbuf);
3383
3384 break;
3385 default:
3386 (void) zfs_standard_error(hdl, ret, errbuf);
3387 }
3388 }
3389 }
3390
3391 nvlist_free(props);
3392 nvlist_free(errors);
3393 return (ret);
3394 }
3395
3396 int
3397 zfs_snapshot(libzfs_handle_t *hdl, const char *path, boolean_t recursive,
3398 nvlist_t *props)
3399 {
3400 int ret;
3401 snapdata_t sd = { 0 };
3402 char fsname[ZFS_MAXNAMELEN];
3403 char *cp;
3404 zfs_handle_t *zhp;
3405 char errbuf[1024];
3406
3407 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3408 "cannot snapshot %s"), path);
3409
3410 if (!zfs_validate_name(hdl, path, ZFS_TYPE_SNAPSHOT, B_TRUE))
3411 return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3412
3413 (void) strlcpy(fsname, path, sizeof (fsname));
3414 cp = strchr(fsname, '@');
3415 *cp = '\0';
3416 sd.sd_snapname = cp + 1;
3417
3418 if ((zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM |
3419 ZFS_TYPE_VOLUME)) == NULL) {
3420 return (-1);
3421 }
3422
3423 verify(nvlist_alloc(&sd.sd_nvl, NV_UNIQUE_NAME, 0) == 0);
3424 if (recursive) {
3425 (void) zfs_snapshot_cb(zfs_handle_dup(zhp), &sd);
3426 } else {
3427 fnvlist_add_boolean(sd.sd_nvl, path);
3428 }
3429
3430 ret = zfs_snapshot_nvl(hdl, sd.sd_nvl, props);
3431 nvlist_free(sd.sd_nvl);
3432 zfs_close(zhp);
3433 return (ret);
3434 }
3435
3436 /*
3437 * Destroy any more recent snapshots. We invoke this callback on any dependents
3438 * of the snapshot first. If the 'cb_dependent' member is non-zero, then this
3439 * is a dependent and we should just destroy it without checking the transaction
3440 * group.
3441 */
3442 typedef struct rollback_data {
3443 const char *cb_target; /* the snapshot */
3444 uint64_t cb_create; /* creation time reference */
3445 boolean_t cb_error;
3446 boolean_t cb_dependent;
3447 boolean_t cb_force;
3448 } rollback_data_t;
3449
3450 static int
3451 rollback_destroy(zfs_handle_t *zhp, void *data)
3452 {
3453 rollback_data_t *cbp = data;
3454
3455 if (!cbp->cb_dependent) {
3456 if (strcmp(zhp->zfs_name, cbp->cb_target) != 0 &&
3457 zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
3458 zfs_prop_get_int(zhp, ZFS_PROP_CREATETXG) >
3459 cbp->cb_create) {
3460
3461 cbp->cb_dependent = B_TRUE;
3462 cbp->cb_error |= zfs_iter_dependents(zhp, B_FALSE,
3463 rollback_destroy, cbp);
3464 cbp->cb_dependent = B_FALSE;
3465
3466 cbp->cb_error |= zfs_destroy(zhp, B_FALSE);
3467 }
3468 } else {
3469 /* We must destroy this clone; first unmount it */
3470 prop_changelist_t *clp;
3471
3472 clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
3473 cbp->cb_force ? MS_FORCE: 0);
3474 if (clp == NULL || changelist_prefix(clp) != 0) {
3475 cbp->cb_error = B_TRUE;
3476 zfs_close(zhp);
3477 return (0);
3478 }
3479 if (zfs_destroy(zhp, B_FALSE) != 0)
3480 cbp->cb_error = B_TRUE;
3481 else
3482 changelist_remove(clp, zhp->zfs_name);
3483 (void) changelist_postfix(clp);
3484 changelist_free(clp);
3485 }
3486
|