2897 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
2898 const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
2899 dmu_replay_record_t *drr_noswap, const char *sendfs,
2900 avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
2901 uint64_t *action_handlep, const char *finalsnap)
2902 {
2903 zfs_cmd_t zc = { 0 };
2904 time_t begin_time;
2905 int ioctl_err, ioctl_errno, err;
2906 char *cp;
2907 struct drr_begin *drrb = &drr->drr_u.drr_begin;
2908 char errbuf[1024];
2909 char prop_errbuf[1024];
2910 const char *chopprefix;
2911 boolean_t newfs = B_FALSE;
2912 boolean_t stream_wantsnewfs;
2913 uint64_t parent_snapguid = 0;
2914 prop_changelist_t *clp = NULL;
2915 nvlist_t *snapprops_nvlist = NULL;
2916 zprop_errflags_t prop_errflags;
2917
2918 begin_time = time(NULL);
2919
2920 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2921 "cannot receive"));
2922
2923 if (stream_avl != NULL) {
2924 char *snapname;
2925 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
2926 &snapname);
2927 nvlist_t *props;
2928 int ret;
2929 boolean_t is_finalsnap;
2930
2931 VERIFY(fs != NULL);
2932 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
2933 &parent_snapguid);
2934 /*
2935 * Can safely use strcmp because at least "snapname" has been
2936 * verified.
2937 */
2938 is_finalsnap = (strcmp(snapname, finalsnap) == 0);
2939
2940 if (is_finalsnap)
2941 err = nvlist_lookup_nvlist(fs, "props", &props);
2942 if (!is_finalsnap || err)
2943 VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
2944
2945 if (flags->canmountoff) {
2946 VERIFY(0 == nvlist_add_uint64(props,
2947 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
2948 }
2949 ret = zcmd_write_src_nvlist(hdl, &zc, props);
2950 if (!is_finalsnap || err)
2951 nvlist_free(props);
2952
2953 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
2954 VERIFY(0 == nvlist_lookup_nvlist(props,
2955 snapname, &snapprops_nvlist));
2956 }
2957
2958 if (ret != 0)
2959 return (-1);
2960 }
2961
2962 cp = NULL;
2963
2964 /*
2965 * Determine how much of the snapshot name stored in the stream
2966 * we are going to tack on to the name they specified on the
2967 * command line, and how much we are going to chop off.
2968 *
2969 * If they specified a snapshot, chop the entire name stored in
2970 * the stream.
3260
3261 if (err == 0) {
3262 nvlist_t *prop_errors;
3263 VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
3264 zc.zc_nvlist_dst_size, &prop_errors, 0));
3265
3266 nvpair_t *prop_err = NULL;
3267
3268 while ((prop_err = nvlist_next_nvpair(prop_errors,
3269 prop_err)) != NULL) {
3270 char tbuf[1024];
3271 zfs_prop_t prop;
3272 int intval;
3273
3274 prop = zfs_name_to_prop(nvpair_name(prop_err));
3275 (void) nvpair_value_int32(prop_err, &intval);
3276 if (strcmp(nvpair_name(prop_err),
3277 ZPROP_N_MORE_ERRORS) == 0) {
3278 trunc_prop_errs(intval);
3279 break;
3280 } else {
3281 (void) snprintf(tbuf, sizeof (tbuf),
3282 dgettext(TEXT_DOMAIN,
3283 "cannot receive %s property on %s"),
3284 nvpair_name(prop_err), zc.zc_name);
3285 zfs_setprop_error(hdl, prop, intval, tbuf);
3286 }
3287 }
3288 nvlist_free(prop_errors);
3289 }
3290
3291 zc.zc_nvlist_dst = 0;
3292 zc.zc_nvlist_dst_size = 0;
3293 zcmd_free_nvlists(&zc);
3294
3295 if (err == 0 && snapprops_nvlist) {
3296 zfs_cmd_t zc2 = { 0 };
3297
3298 (void) strcpy(zc2.zc_name, zc.zc_value);
3299 zc2.zc_cookie = B_TRUE; /* received */
3300 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
|
2897 zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
2898 const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
2899 dmu_replay_record_t *drr_noswap, const char *sendfs,
2900 avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
2901 uint64_t *action_handlep, const char *finalsnap)
2902 {
2903 zfs_cmd_t zc = { 0 };
2904 time_t begin_time;
2905 int ioctl_err, ioctl_errno, err;
2906 char *cp;
2907 struct drr_begin *drrb = &drr->drr_u.drr_begin;
2908 char errbuf[1024];
2909 char prop_errbuf[1024];
2910 const char *chopprefix;
2911 boolean_t newfs = B_FALSE;
2912 boolean_t stream_wantsnewfs;
2913 uint64_t parent_snapguid = 0;
2914 prop_changelist_t *clp = NULL;
2915 nvlist_t *snapprops_nvlist = NULL;
2916 zprop_errflags_t prop_errflags;
2917 char *snapname = NULL;
2918
2919 begin_time = time(NULL);
2920
2921 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2922 "cannot receive"));
2923
2924 if (stream_avl != NULL) {
2925 nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
2926 &snapname);
2927 nvlist_t *props;
2928 int ret;
2929
2930 (void) nvlist_lookup_uint64(fs, "parentfromsnap",
2931 &parent_snapguid);
2932 err = nvlist_lookup_nvlist(fs, "props", &props);
2933 if (err)
2934 VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
2935
2936 if (flags->canmountoff) {
2937 VERIFY(0 == nvlist_add_uint64(props,
2938 zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
2939 }
2940 ret = zcmd_write_src_nvlist(hdl, &zc, props);
2941 if (err)
2942 nvlist_free(props);
2943
2944 if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
2945 VERIFY(0 == nvlist_lookup_nvlist(props,
2946 snapname, &snapprops_nvlist));
2947 }
2948
2949 if (ret != 0)
2950 return (-1);
2951 }
2952
2953 cp = NULL;
2954
2955 /*
2956 * Determine how much of the snapshot name stored in the stream
2957 * we are going to tack on to the name they specified on the
2958 * command line, and how much we are going to chop off.
2959 *
2960 * If they specified a snapshot, chop the entire name stored in
2961 * the stream.
3251
3252 if (err == 0) {
3253 nvlist_t *prop_errors;
3254 VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
3255 zc.zc_nvlist_dst_size, &prop_errors, 0));
3256
3257 nvpair_t *prop_err = NULL;
3258
3259 while ((prop_err = nvlist_next_nvpair(prop_errors,
3260 prop_err)) != NULL) {
3261 char tbuf[1024];
3262 zfs_prop_t prop;
3263 int intval;
3264
3265 prop = zfs_name_to_prop(nvpair_name(prop_err));
3266 (void) nvpair_value_int32(prop_err, &intval);
3267 if (strcmp(nvpair_name(prop_err),
3268 ZPROP_N_MORE_ERRORS) == 0) {
3269 trunc_prop_errs(intval);
3270 break;
3271 } else if (snapname == NULL || finalsnap == NULL ||
3272 strcmp(finalsnap, snapname) == 0 ||
3273 strcmp(nvpair_name(prop_err),
3274 zfs_prop_to_name(ZFS_PROP_REFQUOTA)) != 0) {
3275 /*
3276 * Skip the special case of, for example,
3277 * "refquota", errors on intermediate
3278 * snapshots leading up to a final one.
3279 * That's why we have all of the checks above.
3280 *
3281 * See zfs_ioctl.c's extract_delay_props() for
3282 * a list of props which can fail on
3283 * intermediate snapshots, but shouldn't
3284 * affect the overall receive.
3285 */
3286 (void) snprintf(tbuf, sizeof (tbuf),
3287 dgettext(TEXT_DOMAIN,
3288 "cannot receive %s property on %s"),
3289 nvpair_name(prop_err), zc.zc_name);
3290 zfs_setprop_error(hdl, prop, intval, tbuf);
3291 }
3292 }
3293 nvlist_free(prop_errors);
3294 }
3295
3296 zc.zc_nvlist_dst = 0;
3297 zc.zc_nvlist_dst_size = 0;
3298 zcmd_free_nvlists(&zc);
3299
3300 if (err == 0 && snapprops_nvlist) {
3301 zfs_cmd_t zc2 = { 0 };
3302
3303 (void) strcpy(zc2.zc_name, zc.zc_value);
3304 zc2.zc_cookie = B_TRUE; /* received */
3305 if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
|