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) {
 
 |