Print this page
    
Code review fixes
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libzfs/common/libzfs_sendrecv.c
          +++ new/usr/src/lib/libzfs/common/libzfs_sendrecv.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  25   25   * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  26   26   * Copyright (c) 2013 Steven Hartland. All rights reserved.
  27   27   * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  28   28   */
  29   29  
  30   30  #include <assert.h>
  31   31  #include <ctype.h>
  32   32  #include <errno.h>
  33   33  #include <libintl.h>
  34   34  #include <stdio.h>
  35   35  #include <stdlib.h>
  36   36  #include <strings.h>
  37   37  #include <unistd.h>
  38   38  #include <stddef.h>
  39   39  #include <fcntl.h>
  40   40  #include <sys/mount.h>
  41   41  #include <pthread.h>
  42   42  #include <umem.h>
  43   43  #include <time.h>
  44   44  
  45   45  #include <libzfs.h>
  46   46  #include <libzfs_core.h>
  47   47  
  48   48  #include "zfs_namecheck.h"
  49   49  #include "zfs_prop.h"
  50   50  #include "zfs_fletcher.h"
  51   51  #include "libzfs_impl.h"
  52   52  #include <zlib.h>
  53   53  #include <sha2.h>
  54   54  #include <sys/zio_checksum.h>
  55   55  #include <sys/ddt.h>
  56   56  
  57   57  /* in libzfs_dataset.c */
  58   58  extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
  59   59  
  60   60  static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
  61   61      recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
  62   62      uint64_t *, const char *);
  63   63  static int guid_to_name(libzfs_handle_t *, const char *,
  64   64      uint64_t, boolean_t, char *);
  65   65  
  66   66  static const zio_cksum_t zero_cksum = { 0 };
  67   67  
  68   68  typedef struct dedup_arg {
  69   69          int     inputfd;
  70   70          int     outputfd;
  71   71          libzfs_handle_t  *dedup_hdl;
  72   72  } dedup_arg_t;
  73   73  
  74   74  typedef struct progress_arg {
  75   75          zfs_handle_t *pa_zhp;
  76   76          int pa_fd;
  77   77          boolean_t pa_parsable;
  78   78  } progress_arg_t;
  79   79  
  80   80  typedef struct dataref {
  81   81          uint64_t ref_guid;
  82   82          uint64_t ref_object;
  83   83          uint64_t ref_offset;
  84   84  } dataref_t;
  85   85  
  86   86  typedef struct dedup_entry {
  87   87          struct dedup_entry      *dde_next;
  88   88          zio_cksum_t dde_chksum;
  89   89          uint64_t dde_prop;
  90   90          dataref_t dde_ref;
  91   91  } dedup_entry_t;
  92   92  
  93   93  #define MAX_DDT_PHYSMEM_PERCENT         20
  94   94  #define SMALLEST_POSSIBLE_MAX_DDT_MB            128
  95   95  
  96   96  typedef struct dedup_table {
  97   97          dedup_entry_t   **dedup_hash_array;
  98   98          umem_cache_t    *ddecache;
  99   99          uint64_t        max_ddt_size;  /* max dedup table size in bytes */
 100  100          uint64_t        cur_ddt_size;  /* current dedup table size in bytes */
 101  101          uint64_t        ddt_count;
 102  102          int             numhashbits;
 103  103          boolean_t       ddt_full;
 104  104  } dedup_table_t;
 105  105  
 106  106  static int
 107  107  high_order_bit(uint64_t n)
 108  108  {
 109  109          int count;
 110  110  
 111  111          for (count = 0; n != 0; count++)
 112  112                  n >>= 1;
 113  113          return (count);
 114  114  }
 115  115  
 116  116  static size_t
 117  117  ssread(void *buf, size_t len, FILE *stream)
 118  118  {
 119  119          size_t outlen;
 120  120  
 121  121          if ((outlen = fread(buf, len, 1, stream)) == 0)
 122  122                  return (0);
 123  123  
 124  124          return (outlen);
 125  125  }
 126  126  
 127  127  static void
 128  128  ddt_hash_append(libzfs_handle_t *hdl, dedup_table_t *ddt, dedup_entry_t **ddepp,
 129  129      zio_cksum_t *cs, uint64_t prop, dataref_t *dr)
 130  130  {
 131  131          dedup_entry_t   *dde;
 132  132  
 133  133          if (ddt->cur_ddt_size >= ddt->max_ddt_size) {
 134  134                  if (ddt->ddt_full == B_FALSE) {
 135  135                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 136  136                              "Dedup table full.  Deduplication will continue "
 137  137                              "with existing table entries"));
 138  138                          ddt->ddt_full = B_TRUE;
 139  139                  }
 140  140                  return;
 141  141          }
 142  142  
 143  143          if ((dde = umem_cache_alloc(ddt->ddecache, UMEM_DEFAULT))
 144  144              != NULL) {
 145  145                  assert(*ddepp == NULL);
 146  146                  dde->dde_next = NULL;
 147  147                  dde->dde_chksum = *cs;
 148  148                  dde->dde_prop = prop;
 149  149                  dde->dde_ref = *dr;
 150  150                  *ddepp = dde;
 151  151                  ddt->cur_ddt_size += sizeof (dedup_entry_t);
 152  152                  ddt->ddt_count++;
 153  153          }
 154  154  }
 155  155  
 156  156  /*
 157  157   * Using the specified dedup table, do a lookup for an entry with
 158  158   * the checksum cs.  If found, return the block's reference info
 159  159   * in *dr. Otherwise, insert a new entry in the dedup table, using
 160  160   * the reference information specified by *dr.
 161  161   *
 162  162   * return value:  true - entry was found
 163  163   *                false - entry was not found
 164  164   */
 165  165  static boolean_t
 166  166  ddt_update(libzfs_handle_t *hdl, dedup_table_t *ddt, zio_cksum_t *cs,
 167  167      uint64_t prop, dataref_t *dr)
 168  168  {
 169  169          uint32_t hashcode;
 170  170          dedup_entry_t **ddepp;
 171  171  
 172  172          hashcode = BF64_GET(cs->zc_word[0], 0, ddt->numhashbits);
 173  173  
 174  174          for (ddepp = &(ddt->dedup_hash_array[hashcode]); *ddepp != NULL;
 175  175              ddepp = &((*ddepp)->dde_next)) {
 176  176                  if (ZIO_CHECKSUM_EQUAL(((*ddepp)->dde_chksum), *cs) &&
 177  177                      (*ddepp)->dde_prop == prop) {
 178  178                          *dr = (*ddepp)->dde_ref;
 179  179                          return (B_TRUE);
 180  180                  }
 181  181          }
 182  182          ddt_hash_append(hdl, ddt, ddepp, cs, prop, dr);
 183  183          return (B_FALSE);
 184  184  }
 185  185  
 186  186  static int
 187  187  dump_record(dmu_replay_record_t *drr, void *payload, int payload_len,
 188  188      zio_cksum_t *zc, int outfd)
 189  189  {
 190  190          ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
 191  191              ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
 192  192          fletcher_4_incremental_native(drr,
 193  193              offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
 194  194          if (drr->drr_type != DRR_BEGIN) {
 195  195                  ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
 196  196                      drr_checksum.drr_checksum));
 197  197                  drr->drr_u.drr_checksum.drr_checksum = *zc;
 198  198          }
 199  199          fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
 200  200              sizeof (zio_cksum_t), zc);
 201  201          if (write(outfd, drr, sizeof (*drr)) == -1)
 202  202                  return (errno);
 203  203          if (payload_len != 0) {
 204  204                  fletcher_4_incremental_native(payload, payload_len, zc);
 205  205                  if (write(outfd, payload, payload_len) == -1)
 206  206                          return (errno);
 207  207          }
 208  208          return (0);
 209  209  }
 210  210  
 211  211  /*
 212  212   * This function is started in a separate thread when the dedup option
 213  213   * has been requested.  The main send thread determines the list of
 214  214   * snapshots to be included in the send stream and makes the ioctl calls
 215  215   * for each one.  But instead of having the ioctl send the output to the
 216  216   * the output fd specified by the caller of zfs_send()), the
 217  217   * ioctl is told to direct the output to a pipe, which is read by the
 218  218   * alternate thread running THIS function.  This function does the
 219  219   * dedup'ing by:
 220  220   *  1. building a dedup table (the DDT)
 221  221   *  2. doing checksums on each data block and inserting a record in the DDT
 222  222   *  3. looking for matching checksums, and
 223  223   *  4.  sending a DRR_WRITE_BYREF record instead of a write record whenever
 224  224   *      a duplicate block is found.
 225  225   * The output of this function then goes to the output fd requested
 226  226   * by the caller of zfs_send().
 227  227   */
 228  228  static void *
 229  229  cksummer(void *arg)
 230  230  {
 231  231          dedup_arg_t *dda = arg;
 232  232          char *buf = zfs_alloc(dda->dedup_hdl, SPA_MAXBLOCKSIZE);
 233  233          dmu_replay_record_t thedrr;
 234  234          dmu_replay_record_t *drr = &thedrr;
 235  235          FILE *ofp;
 236  236          int outfd;
 237  237          dedup_table_t ddt;
 238  238          zio_cksum_t stream_cksum;
 239  239          uint64_t physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE);
 240  240          uint64_t numbuckets;
 241  241  
 242  242          ddt.max_ddt_size =
 243  243              MAX((physmem * MAX_DDT_PHYSMEM_PERCENT) / 100,
 244  244              SMALLEST_POSSIBLE_MAX_DDT_MB << 20);
 245  245  
 246  246          numbuckets = ddt.max_ddt_size / (sizeof (dedup_entry_t));
 247  247  
 248  248          /*
 249  249           * numbuckets must be a power of 2.  Increase number to
 250  250           * a power of 2 if necessary.
 251  251           */
 252  252          if (!ISP2(numbuckets))
 253  253                  numbuckets = 1 << high_order_bit(numbuckets);
 254  254  
 255  255          ddt.dedup_hash_array = calloc(numbuckets, sizeof (dedup_entry_t *));
 256  256          ddt.ddecache = umem_cache_create("dde", sizeof (dedup_entry_t), 0,
 257  257              NULL, NULL, NULL, NULL, NULL, 0);
 258  258          ddt.cur_ddt_size = numbuckets * sizeof (dedup_entry_t *);
 259  259          ddt.numhashbits = high_order_bit(numbuckets) - 1;
 260  260          ddt.ddt_full = B_FALSE;
 261  261  
 262  262          outfd = dda->outputfd;
 263  263          ofp = fdopen(dda->inputfd, "r");
 264  264          while (ssread(drr, sizeof (*drr), ofp) != 0) {
 265  265  
 266  266                  switch (drr->drr_type) {
 267  267                  case DRR_BEGIN:
 268  268                  {
 269  269                          struct drr_begin *drrb = &drr->drr_u.drr_begin;
 270  270                          int fflags;
 271  271                          int sz = 0;
 272  272                          ZIO_SET_CHECKSUM(&stream_cksum, 0, 0, 0, 0);
 273  273  
 274  274                          ASSERT3U(drrb->drr_magic, ==, DMU_BACKUP_MAGIC);
 275  275  
 276  276                          /* set the DEDUP feature flag for this stream */
 277  277                          fflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
 278  278                          fflags |= (DMU_BACKUP_FEATURE_DEDUP |
 279  279                              DMU_BACKUP_FEATURE_DEDUPPROPS);
 280  280                          DMU_SET_FEATUREFLAGS(drrb->drr_versioninfo, fflags);
 281  281  
 282  282                          if (drr->drr_payloadlen != 0) {
 283  283                                  sz = drr->drr_payloadlen;
 284  284  
 285  285                                  if (sz > SPA_MAXBLOCKSIZE) {
 286  286                                          buf = zfs_realloc(dda->dedup_hdl, buf,
 287  287                                              SPA_MAXBLOCKSIZE, sz);
 288  288                                  }
 289  289                                  (void) ssread(buf, sz, ofp);
 290  290                                  if (ferror(stdin))
 291  291                                          perror("fread");
 292  292                          }
 293  293                          if (dump_record(drr, buf, sz, &stream_cksum,
 294  294                              outfd) != 0)
 295  295                                  goto out;
 296  296                          break;
 297  297                  }
 298  298  
 299  299                  case DRR_END:
 300  300                  {
 301  301                          struct drr_end *drre = &drr->drr_u.drr_end;
 302  302                          /* use the recalculated checksum */
 303  303                          drre->drr_checksum = stream_cksum;
 304  304                          if (dump_record(drr, NULL, 0, &stream_cksum,
 305  305                              outfd) != 0)
 306  306                                  goto out;
 307  307                          break;
 308  308                  }
 309  309  
 310  310                  case DRR_OBJECT:
 311  311                  {
 312  312                          struct drr_object *drro = &drr->drr_u.drr_object;
 313  313                          if (drro->drr_bonuslen > 0) {
 314  314                                  (void) ssread(buf,
 315  315                                      P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
 316  316                                      ofp);
 317  317                          }
 318  318                          if (dump_record(drr, buf,
 319  319                              P2ROUNDUP((uint64_t)drro->drr_bonuslen, 8),
 320  320                              &stream_cksum, outfd) != 0)
 321  321                                  goto out;
 322  322                          break;
 323  323                  }
 324  324  
 325  325                  case DRR_SPILL:
 326  326                  {
 327  327                          struct drr_spill *drrs = &drr->drr_u.drr_spill;
 328  328                          (void) ssread(buf, drrs->drr_length, ofp);
 329  329                          if (dump_record(drr, buf, drrs->drr_length,
 330  330                              &stream_cksum, outfd) != 0)
 331  331                                  goto out;
 332  332                          break;
 333  333                  }
 334  334  
 335  335                  case DRR_FREEOBJECTS:
 336  336                  {
 337  337                          if (dump_record(drr, NULL, 0, &stream_cksum,
 338  338                              outfd) != 0)
 339  339                                  goto out;
 340  340                          break;
 341  341                  }
 342  342  
 343  343                  case DRR_WRITE:
 344  344                  {
 345  345                          struct drr_write *drrw = &drr->drr_u.drr_write;
 346  346                          dataref_t       dataref;
 347  347  
 348  348                          (void) ssread(buf, drrw->drr_length, ofp);
 349  349  
 350  350                          /*
 351  351                           * Use the existing checksum if it's dedup-capable,
 352  352                           * else calculate a SHA256 checksum for it.
 353  353                           */
 354  354  
 355  355                          if (ZIO_CHECKSUM_EQUAL(drrw->drr_key.ddk_cksum,
 356  356                              zero_cksum) ||
 357  357                              !DRR_IS_DEDUP_CAPABLE(drrw->drr_checksumflags)) {
 358  358                                  SHA256_CTX      ctx;
 359  359                                  zio_cksum_t     tmpsha256;
 360  360  
 361  361                                  SHA256Init(&ctx);
 362  362                                  SHA256Update(&ctx, buf, drrw->drr_length);
 363  363                                  SHA256Final(&tmpsha256, &ctx);
 364  364                                  drrw->drr_key.ddk_cksum.zc_word[0] =
 365  365                                      BE_64(tmpsha256.zc_word[0]);
 366  366                                  drrw->drr_key.ddk_cksum.zc_word[1] =
 367  367                                      BE_64(tmpsha256.zc_word[1]);
 368  368                                  drrw->drr_key.ddk_cksum.zc_word[2] =
 369  369                                      BE_64(tmpsha256.zc_word[2]);
 370  370                                  drrw->drr_key.ddk_cksum.zc_word[3] =
 371  371                                      BE_64(tmpsha256.zc_word[3]);
 372  372                                  drrw->drr_checksumtype = ZIO_CHECKSUM_SHA256;
 373  373                                  drrw->drr_checksumflags = DRR_CHECKSUM_DEDUP;
 374  374                          }
 375  375  
 376  376                          dataref.ref_guid = drrw->drr_toguid;
 377  377                          dataref.ref_object = drrw->drr_object;
 378  378                          dataref.ref_offset = drrw->drr_offset;
 379  379  
 380  380                          if (ddt_update(dda->dedup_hdl, &ddt,
 381  381                              &drrw->drr_key.ddk_cksum, drrw->drr_key.ddk_prop,
 382  382                              &dataref)) {
 383  383                                  dmu_replay_record_t wbr_drr = {0};
 384  384                                  struct drr_write_byref *wbr_drrr =
 385  385                                      &wbr_drr.drr_u.drr_write_byref;
 386  386  
 387  387                                  /* block already present in stream */
 388  388                                  wbr_drr.drr_type = DRR_WRITE_BYREF;
 389  389  
 390  390                                  wbr_drrr->drr_object = drrw->drr_object;
 391  391                                  wbr_drrr->drr_offset = drrw->drr_offset;
 392  392                                  wbr_drrr->drr_length = drrw->drr_length;
 393  393                                  wbr_drrr->drr_toguid = drrw->drr_toguid;
 394  394                                  wbr_drrr->drr_refguid = dataref.ref_guid;
 395  395                                  wbr_drrr->drr_refobject =
 396  396                                      dataref.ref_object;
 397  397                                  wbr_drrr->drr_refoffset =
 398  398                                      dataref.ref_offset;
 399  399  
 400  400                                  wbr_drrr->drr_checksumtype =
 401  401                                      drrw->drr_checksumtype;
 402  402                                  wbr_drrr->drr_checksumflags =
 403  403                                      drrw->drr_checksumtype;
 404  404                                  wbr_drrr->drr_key.ddk_cksum =
 405  405                                      drrw->drr_key.ddk_cksum;
 406  406                                  wbr_drrr->drr_key.ddk_prop =
 407  407                                      drrw->drr_key.ddk_prop;
 408  408  
 409  409                                  if (dump_record(&wbr_drr, NULL, 0,
 410  410                                      &stream_cksum, outfd) != 0)
 411  411                                          goto out;
 412  412                          } else {
 413  413                                  /* block not previously seen */
 414  414                                  if (dump_record(drr, buf, drrw->drr_length,
 415  415                                      &stream_cksum, outfd) != 0)
 416  416                                          goto out;
 417  417                          }
 418  418                          break;
 419  419                  }
 420  420  
 421  421                  case DRR_WRITE_EMBEDDED:
 422  422                  {
 423  423                          struct drr_write_embedded *drrwe =
 424  424                              &drr->drr_u.drr_write_embedded;
 425  425                          (void) ssread(buf,
 426  426                              P2ROUNDUP((uint64_t)drrwe->drr_psize, 8), ofp);
 427  427                          if (dump_record(drr, buf,
 428  428                              P2ROUNDUP((uint64_t)drrwe->drr_psize, 8),
 429  429                              &stream_cksum, outfd) != 0)
 430  430                                  goto out;
 431  431                          break;
 432  432                  }
 433  433  
 434  434                  case DRR_FREE:
 435  435                  {
 436  436                          if (dump_record(drr, NULL, 0, &stream_cksum,
 437  437                              outfd) != 0)
 438  438                                  goto out;
 439  439                          break;
 440  440                  }
 441  441  
 442  442                  default:
 443  443                          (void) fprintf(stderr, "INVALID record type 0x%x\n",
 444  444                              drr->drr_type);
 445  445                          /* should never happen, so assert */
 446  446                          assert(B_FALSE);
 447  447                  }
 448  448          }
 449  449  out:
 450  450          umem_cache_destroy(ddt.ddecache);
 451  451          free(ddt.dedup_hash_array);
 452  452          free(buf);
 453  453          (void) fclose(ofp);
 454  454  
 455  455          return (NULL);
 456  456  }
 457  457  
 458  458  /*
 459  459   * Routines for dealing with the AVL tree of fs-nvlists
 460  460   */
 461  461  typedef struct fsavl_node {
 462  462          avl_node_t fn_node;
 463  463          nvlist_t *fn_nvfs;
 464  464          char *fn_snapname;
 465  465          uint64_t fn_guid;
 466  466  } fsavl_node_t;
 467  467  
 468  468  static int
 469  469  fsavl_compare(const void *arg1, const void *arg2)
 470  470  {
 471  471          const fsavl_node_t *fn1 = arg1;
 472  472          const fsavl_node_t *fn2 = arg2;
 473  473  
 474  474          if (fn1->fn_guid > fn2->fn_guid)
 475  475                  return (+1);
 476  476          else if (fn1->fn_guid < fn2->fn_guid)
 477  477                  return (-1);
 478  478          else
 479  479                  return (0);
 480  480  }
 481  481  
 482  482  /*
 483  483   * Given the GUID of a snapshot, find its containing filesystem and
 484  484   * (optionally) name.
 485  485   */
 486  486  static nvlist_t *
 487  487  fsavl_find(avl_tree_t *avl, uint64_t snapguid, char **snapname)
 488  488  {
 489  489          fsavl_node_t fn_find;
 490  490          fsavl_node_t *fn;
 491  491  
 492  492          fn_find.fn_guid = snapguid;
 493  493  
 494  494          fn = avl_find(avl, &fn_find, NULL);
 495  495          if (fn) {
 496  496                  if (snapname)
 497  497                          *snapname = fn->fn_snapname;
 498  498                  return (fn->fn_nvfs);
 499  499          }
 500  500          return (NULL);
 501  501  }
 502  502  
 503  503  static void
 504  504  fsavl_destroy(avl_tree_t *avl)
 505  505  {
 506  506          fsavl_node_t *fn;
 507  507          void *cookie;
 508  508  
 509  509          if (avl == NULL)
 510  510                  return;
 511  511  
 512  512          cookie = NULL;
 513  513          while ((fn = avl_destroy_nodes(avl, &cookie)) != NULL)
 514  514                  free(fn);
 515  515          avl_destroy(avl);
 516  516          free(avl);
 517  517  }
 518  518  
 519  519  /*
 520  520   * Given an nvlist, produce an avl tree of snapshots, ordered by guid
 521  521   */
 522  522  static avl_tree_t *
 523  523  fsavl_create(nvlist_t *fss)
 524  524  {
 525  525          avl_tree_t *fsavl;
 526  526          nvpair_t *fselem = NULL;
 527  527  
 528  528          if ((fsavl = malloc(sizeof (avl_tree_t))) == NULL)
 529  529                  return (NULL);
 530  530  
 531  531          avl_create(fsavl, fsavl_compare, sizeof (fsavl_node_t),
 532  532              offsetof(fsavl_node_t, fn_node));
 533  533  
 534  534          while ((fselem = nvlist_next_nvpair(fss, fselem)) != NULL) {
 535  535                  nvlist_t *nvfs, *snaps;
 536  536                  nvpair_t *snapelem = NULL;
 537  537  
 538  538                  VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
 539  539                  VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
 540  540  
 541  541                  while ((snapelem =
 542  542                      nvlist_next_nvpair(snaps, snapelem)) != NULL) {
 543  543                          fsavl_node_t *fn;
 544  544                          uint64_t guid;
 545  545  
 546  546                          VERIFY(0 == nvpair_value_uint64(snapelem, &guid));
 547  547                          if ((fn = malloc(sizeof (fsavl_node_t))) == NULL) {
 548  548                                  fsavl_destroy(fsavl);
 549  549                                  return (NULL);
 550  550                          }
 551  551                          fn->fn_nvfs = nvfs;
 552  552                          fn->fn_snapname = nvpair_name(snapelem);
 553  553                          fn->fn_guid = guid;
 554  554  
 555  555                          /*
 556  556                           * Note: if there are multiple snaps with the
 557  557                           * same GUID, we ignore all but one.
 558  558                           */
 559  559                          if (avl_find(fsavl, fn, NULL) == NULL)
 560  560                                  avl_add(fsavl, fn);
 561  561                          else
 562  562                                  free(fn);
 563  563                  }
 564  564          }
 565  565  
 566  566          return (fsavl);
 567  567  }
 568  568  
 569  569  /*
 570  570   * Routines for dealing with the giant nvlist of fs-nvlists, etc.
 571  571   */
 572  572  typedef struct send_data {
 573  573          uint64_t parent_fromsnap_guid;
 574  574          nvlist_t *parent_snaps;
 575  575          nvlist_t *fss;
 576  576          nvlist_t *snapprops;
 577  577          const char *fromsnap;
 578  578          const char *tosnap;
 579  579          boolean_t recursive;
 580  580  
 581  581          /*
 582  582           * The header nvlist is of the following format:
 583  583           * {
 584  584           *   "tosnap" -> string
 585  585           *   "fromsnap" -> string (if incremental)
 586  586           *   "fss" -> {
 587  587           *      id -> {
 588  588           *
 589  589           *       "name" -> string (full name; for debugging)
 590  590           *       "parentfromsnap" -> number (guid of fromsnap in parent)
 591  591           *
 592  592           *       "props" -> { name -> value (only if set here) }
 593  593           *       "snaps" -> { name (lastname) -> number (guid) }
 594  594           *       "snapprops" -> { name (lastname) -> { name -> value } }
 595  595           *
 596  596           *       "origin" -> number (guid) (if clone)
 597  597           *       "sent" -> boolean (not on-disk)
 598  598           *      }
 599  599           *   }
 600  600           * }
 601  601           *
 602  602           */
 603  603  } send_data_t;
 604  604  
 605  605  static void send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv);
 606  606  
 607  607  static int
 608  608  send_iterate_snap(zfs_handle_t *zhp, void *arg)
 609  609  {
 610  610          send_data_t *sd = arg;
 611  611          uint64_t guid = zhp->zfs_dmustats.dds_guid;
 612  612          char *snapname;
 613  613          nvlist_t *nv;
 614  614  
 615  615          snapname = strrchr(zhp->zfs_name, '@')+1;
 616  616  
 617  617          VERIFY(0 == nvlist_add_uint64(sd->parent_snaps, snapname, guid));
 618  618          /*
 619  619           * NB: if there is no fromsnap here (it's a newly created fs in
 620  620           * an incremental replication), we will substitute the tosnap.
 621  621           */
 622  622          if ((sd->fromsnap && strcmp(snapname, sd->fromsnap) == 0) ||
 623  623              (sd->parent_fromsnap_guid == 0 && sd->tosnap &&
 624  624              strcmp(snapname, sd->tosnap) == 0)) {
 625  625                  sd->parent_fromsnap_guid = guid;
 626  626          }
 627  627  
 628  628          VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
 629  629          send_iterate_prop(zhp, nv);
 630  630          VERIFY(0 == nvlist_add_nvlist(sd->snapprops, snapname, nv));
 631  631          nvlist_free(nv);
 632  632  
 633  633          zfs_close(zhp);
 634  634          return (0);
 635  635  }
 636  636  
 637  637  static void
 638  638  send_iterate_prop(zfs_handle_t *zhp, nvlist_t *nv)
 639  639  {
 640  640          nvpair_t *elem = NULL;
 641  641  
 642  642          while ((elem = nvlist_next_nvpair(zhp->zfs_props, elem)) != NULL) {
 643  643                  char *propname = nvpair_name(elem);
 644  644                  zfs_prop_t prop = zfs_name_to_prop(propname);
 645  645                  nvlist_t *propnv;
 646  646  
 647  647                  if (!zfs_prop_user(propname)) {
 648  648                          /*
 649  649                           * Realistically, this should never happen.  However,
 650  650                           * we want the ability to add DSL properties without
 651  651                           * needing to make incompatible version changes.  We
 652  652                           * need to ignore unknown properties to allow older
 653  653                           * software to still send datasets containing these
 654  654                           * properties, with the unknown properties elided.
 655  655                           */
 656  656                          if (prop == ZPROP_INVAL)
 657  657                                  continue;
 658  658  
 659  659                          if (zfs_prop_readonly(prop))
 660  660                                  continue;
 661  661                  }
 662  662  
 663  663                  verify(nvpair_value_nvlist(elem, &propnv) == 0);
 664  664                  if (prop == ZFS_PROP_QUOTA || prop == ZFS_PROP_RESERVATION ||
 665  665                      prop == ZFS_PROP_REFQUOTA ||
 666  666                      prop == ZFS_PROP_REFRESERVATION) {
 667  667                          char *source;
 668  668                          uint64_t value;
 669  669                          verify(nvlist_lookup_uint64(propnv,
 670  670                              ZPROP_VALUE, &value) == 0);
 671  671                          if (zhp->zfs_type == ZFS_TYPE_SNAPSHOT)
 672  672                                  continue;
 673  673                          /*
 674  674                           * May have no source before SPA_VERSION_RECVD_PROPS,
 675  675                           * but is still modifiable.
 676  676                           */
 677  677                          if (nvlist_lookup_string(propnv,
 678  678                              ZPROP_SOURCE, &source) == 0) {
 679  679                                  if ((strcmp(source, zhp->zfs_name) != 0) &&
 680  680                                      (strcmp(source,
 681  681                                      ZPROP_SOURCE_VAL_RECVD) != 0))
 682  682                                          continue;
 683  683                          }
 684  684                  } else {
 685  685                          char *source;
 686  686                          if (nvlist_lookup_string(propnv,
 687  687                              ZPROP_SOURCE, &source) != 0)
 688  688                                  continue;
 689  689                          if ((strcmp(source, zhp->zfs_name) != 0) &&
 690  690                              (strcmp(source, ZPROP_SOURCE_VAL_RECVD) != 0))
 691  691                                  continue;
 692  692                  }
 693  693  
 694  694                  if (zfs_prop_user(propname) ||
 695  695                      zfs_prop_get_type(prop) == PROP_TYPE_STRING) {
 696  696                          char *value;
 697  697                          verify(nvlist_lookup_string(propnv,
 698  698                              ZPROP_VALUE, &value) == 0);
 699  699                          VERIFY(0 == nvlist_add_string(nv, propname, value));
 700  700                  } else {
 701  701                          uint64_t value;
 702  702                          verify(nvlist_lookup_uint64(propnv,
 703  703                              ZPROP_VALUE, &value) == 0);
 704  704                          VERIFY(0 == nvlist_add_uint64(nv, propname, value));
 705  705                  }
 706  706          }
 707  707  }
 708  708  
 709  709  /*
 710  710   * recursively generate nvlists describing datasets.  See comment
 711  711   * for the data structure send_data_t above for description of contents
 712  712   * of the nvlist.
 713  713   */
 714  714  static int
 715  715  send_iterate_fs(zfs_handle_t *zhp, void *arg)
 716  716  {
 717  717          send_data_t *sd = arg;
 718  718          nvlist_t *nvfs, *nv;
 719  719          int rv = 0;
 720  720          uint64_t parent_fromsnap_guid_save = sd->parent_fromsnap_guid;
 721  721          uint64_t guid = zhp->zfs_dmustats.dds_guid;
 722  722          char guidstring[64];
 723  723  
 724  724          VERIFY(0 == nvlist_alloc(&nvfs, NV_UNIQUE_NAME, 0));
 725  725          VERIFY(0 == nvlist_add_string(nvfs, "name", zhp->zfs_name));
 726  726          VERIFY(0 == nvlist_add_uint64(nvfs, "parentfromsnap",
 727  727              sd->parent_fromsnap_guid));
 728  728  
 729  729          if (zhp->zfs_dmustats.dds_origin[0]) {
 730  730                  zfs_handle_t *origin = zfs_open(zhp->zfs_hdl,
 731  731                      zhp->zfs_dmustats.dds_origin, ZFS_TYPE_SNAPSHOT);
 732  732                  if (origin == NULL)
 733  733                          return (-1);
 734  734                  VERIFY(0 == nvlist_add_uint64(nvfs, "origin",
 735  735                      origin->zfs_dmustats.dds_guid));
 736  736          }
 737  737  
 738  738          /* iterate over props */
 739  739          VERIFY(0 == nvlist_alloc(&nv, NV_UNIQUE_NAME, 0));
 740  740          send_iterate_prop(zhp, nv);
 741  741          VERIFY(0 == nvlist_add_nvlist(nvfs, "props", nv));
 742  742          nvlist_free(nv);
 743  743  
 744  744          /* iterate over snaps, and set sd->parent_fromsnap_guid */
 745  745          sd->parent_fromsnap_guid = 0;
 746  746          VERIFY(0 == nvlist_alloc(&sd->parent_snaps, NV_UNIQUE_NAME, 0));
 747  747          VERIFY(0 == nvlist_alloc(&sd->snapprops, NV_UNIQUE_NAME, 0));
 748  748          (void) zfs_iter_snapshots(zhp, send_iterate_snap, sd);
 749  749          VERIFY(0 == nvlist_add_nvlist(nvfs, "snaps", sd->parent_snaps));
 750  750          VERIFY(0 == nvlist_add_nvlist(nvfs, "snapprops", sd->snapprops));
 751  751          nvlist_free(sd->parent_snaps);
 752  752          nvlist_free(sd->snapprops);
 753  753  
 754  754          /* add this fs to nvlist */
 755  755          (void) snprintf(guidstring, sizeof (guidstring),
 756  756              "0x%llx", (longlong_t)guid);
 757  757          VERIFY(0 == nvlist_add_nvlist(sd->fss, guidstring, nvfs));
 758  758          nvlist_free(nvfs);
 759  759  
 760  760          /* iterate over children */
 761  761          if (sd->recursive)
 762  762                  rv = zfs_iter_filesystems(zhp, send_iterate_fs, sd);
 763  763  
 764  764          sd->parent_fromsnap_guid = parent_fromsnap_guid_save;
 765  765  
 766  766          zfs_close(zhp);
 767  767          return (rv);
 768  768  }
 769  769  
 770  770  static int
 771  771  gather_nvlist(libzfs_handle_t *hdl, const char *fsname, const char *fromsnap,
 772  772      const char *tosnap, boolean_t recursive, nvlist_t **nvlp, avl_tree_t **avlp)
 773  773  {
 774  774          zfs_handle_t *zhp;
 775  775          send_data_t sd = { 0 };
 776  776          int error;
 777  777  
 778  778          zhp = zfs_open(hdl, fsname, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
 779  779          if (zhp == NULL)
 780  780                  return (EZFS_BADTYPE);
 781  781  
 782  782          VERIFY(0 == nvlist_alloc(&sd.fss, NV_UNIQUE_NAME, 0));
 783  783          sd.fromsnap = fromsnap;
 784  784          sd.tosnap = tosnap;
 785  785          sd.recursive = recursive;
 786  786  
 787  787          if ((error = send_iterate_fs(zhp, &sd)) != 0) {
 788  788                  nvlist_free(sd.fss);
 789  789                  if (avlp != NULL)
 790  790                          *avlp = NULL;
 791  791                  *nvlp = NULL;
 792  792                  return (error);
 793  793          }
 794  794  
 795  795          if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
 796  796                  nvlist_free(sd.fss);
 797  797                  *nvlp = NULL;
 798  798                  return (EZFS_NOMEM);
 799  799          }
 800  800  
 801  801          *nvlp = sd.fss;
 802  802          return (0);
 803  803  }
 804  804  
 805  805  /*
 806  806   * Routines specific to "zfs send"
 807  807   */
 808  808  typedef struct send_dump_data {
 809  809          /* these are all just the short snapname (the part after the @) */
 810  810          const char *fromsnap;
 811  811          const char *tosnap;
 812  812          char prevsnap[ZFS_MAXNAMELEN];
 813  813          uint64_t prevsnap_obj;
 814  814          boolean_t seenfrom, seento, replicate, doall, fromorigin;
 815  815          boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
 816  816          boolean_t large_block;
 817  817          int outfd;
 818  818          boolean_t err;
 819  819          nvlist_t *fss;
 820  820          nvlist_t *snapholds;
 821  821          avl_tree_t *fsavl;
 822  822          snapfilter_cb_t *filter_cb;
 823  823          void *filter_cb_arg;
 824  824          nvlist_t *debugnv;
 825  825          char holdtag[ZFS_MAXNAMELEN];
 826  826          int cleanup_fd;
 827  827          uint64_t size;
 828  828  } send_dump_data_t;
 829  829  
 830  830  static int
 831  831  estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
 832  832      boolean_t fromorigin, uint64_t *sizep)
 833  833  {
 834  834          zfs_cmd_t zc = { 0 };
 835  835          libzfs_handle_t *hdl = zhp->zfs_hdl;
 836  836  
 837  837          assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
 838  838          assert(fromsnap_obj == 0 || !fromorigin);
 839  839  
 840  840          (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 841  841          zc.zc_obj = fromorigin;
 842  842          zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
 843  843          zc.zc_fromobj = fromsnap_obj;
 844  844          zc.zc_guid = 1;  /* estimate flag */
 845  845  
 846  846          if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
 847  847                  char errbuf[1024];
 848  848                  (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 849  849                      "warning: cannot estimate space for '%s'"), zhp->zfs_name);
 850  850  
 851  851                  switch (errno) {
 852  852                  case EXDEV:
 853  853                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 854  854                              "not an earlier snapshot from the same fs"));
 855  855                          return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
 856  856  
 857  857                  case ENOENT:
 858  858                          if (zfs_dataset_exists(hdl, zc.zc_name,
 859  859                              ZFS_TYPE_SNAPSHOT)) {
 860  860                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 861  861                                      "incremental source (@%s) does not exist"),
 862  862                                      zc.zc_value);
 863  863                          }
 864  864                          return (zfs_error(hdl, EZFS_NOENT, errbuf));
 865  865  
 866  866                  case EDQUOT:
 867  867                  case EFBIG:
 868  868                  case EIO:
 869  869                  case ENOLINK:
 870  870                  case ENOSPC:
 871  871                  case ENOSTR:
 872  872                  case ENXIO:
 873  873                  case EPIPE:
 874  874                  case ERANGE:
 875  875                  case EFAULT:
 876  876                  case EROFS:
 877  877                          zfs_error_aux(hdl, strerror(errno));
 878  878                          return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
 879  879  
 880  880                  default:
 881  881                          return (zfs_standard_error(hdl, errno, errbuf));
 882  882                  }
 883  883          }
 884  884  
 885  885          *sizep = zc.zc_objset_type;
 886  886  
 887  887          return (0);
 888  888  }
 889  889  
 890  890  /*
 891  891   * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
 892  892   * NULL) to the file descriptor specified by outfd.
 893  893   */
 894  894  static int
 895  895  dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
 896  896      boolean_t fromorigin, int outfd, enum lzc_send_flags flags,
 897  897      nvlist_t *debugnv)
 898  898  {
 899  899          zfs_cmd_t zc = { 0 };
 900  900          libzfs_handle_t *hdl = zhp->zfs_hdl;
 901  901          nvlist_t *thisdbg;
 902  902  
 903  903          assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
 904  904          assert(fromsnap_obj == 0 || !fromorigin);
 905  905  
 906  906          (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
 907  907          zc.zc_cookie = outfd;
 908  908          zc.zc_obj = fromorigin;
 909  909          zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
 910  910          zc.zc_fromobj = fromsnap_obj;
 911  911          zc.zc_flags = flags;
 912  912  
 913  913          VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
 914  914          if (fromsnap && fromsnap[0] != '\0') {
 915  915                  VERIFY(0 == nvlist_add_string(thisdbg,
 916  916                      "fromsnap", fromsnap));
 917  917          }
 918  918  
 919  919          if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
 920  920                  char errbuf[1024];
 921  921                  (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
 922  922                      "warning: cannot send '%s'"), zhp->zfs_name);
 923  923  
 924  924                  VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
 925  925                  if (debugnv) {
 926  926                          VERIFY(0 == nvlist_add_nvlist(debugnv,
 927  927                              zhp->zfs_name, thisdbg));
 928  928                  }
 929  929                  nvlist_free(thisdbg);
 930  930  
 931  931                  switch (errno) {
 932  932                  case EXDEV:
 933  933                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 934  934                              "not an earlier snapshot from the same fs"));
 935  935                          return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
 936  936  
 937  937                  case ENOENT:
 938  938                          if (zfs_dataset_exists(hdl, zc.zc_name,
 939  939                              ZFS_TYPE_SNAPSHOT)) {
 940  940                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 941  941                                      "incremental source (@%s) does not exist"),
 942  942                                      zc.zc_value);
 943  943                          }
 944  944                          return (zfs_error(hdl, EZFS_NOENT, errbuf));
 945  945  
 946  946                  case EDQUOT:
 947  947                  case EFBIG:
 948  948                  case EIO:
 949  949                  case ENOLINK:
 950  950                  case ENOSPC:
 951  951                  case ENOSTR:
 952  952                  case ENXIO:
 953  953                  case EPIPE:
 954  954                  case ERANGE:
 955  955                  case EFAULT:
 956  956                  case EROFS:
 957  957                          zfs_error_aux(hdl, strerror(errno));
 958  958                          return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
 959  959  
 960  960                  default:
 961  961                          return (zfs_standard_error(hdl, errno, errbuf));
 962  962                  }
 963  963          }
 964  964  
 965  965          if (debugnv)
 966  966                  VERIFY(0 == nvlist_add_nvlist(debugnv, zhp->zfs_name, thisdbg));
 967  967          nvlist_free(thisdbg);
 968  968  
 969  969          return (0);
 970  970  }
 971  971  
 972  972  static void
 973  973  gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
 974  974  {
 975  975          assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
 976  976  
 977  977          /*
 978  978           * zfs_send() only sets snapholds for sends that need them,
 979  979           * e.g. replication and doall.
 980  980           */
 981  981          if (sdd->snapholds == NULL)
 982  982                  return;
 983  983  
 984  984          fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
 985  985  }
 986  986  
 987  987  static void *
 988  988  send_progress_thread(void *arg)
 989  989  {
 990  990          progress_arg_t *pa = arg;
 991  991          zfs_cmd_t zc = { 0 };
 992  992          zfs_handle_t *zhp = pa->pa_zhp;
 993  993          libzfs_handle_t *hdl = zhp->zfs_hdl;
 994  994          unsigned long long bytes;
 995  995          char buf[16];
 996  996          time_t t;
 997  997          struct tm *tm;
 998  998  
 999  999          (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
1000 1000  
1001 1001          if (!pa->pa_parsable)
1002 1002                  (void) fprintf(stderr, "TIME        SENT   SNAPSHOT\n");
1003 1003  
1004 1004          /*
1005 1005           * Print the progress from ZFS_IOC_SEND_PROGRESS every second.
1006 1006           */
1007 1007          for (;;) {
1008 1008                  (void) sleep(1);
1009 1009  
1010 1010                  zc.zc_cookie = pa->pa_fd;
1011 1011                  if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
1012 1012                          return ((void *)-1);
1013 1013  
1014 1014                  (void) time(&t);
1015 1015                  tm = localtime(&t);
1016 1016                  bytes = zc.zc_cookie;
1017 1017  
1018 1018                  if (pa->pa_parsable) {
1019 1019                          (void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
1020 1020                              tm->tm_hour, tm->tm_min, tm->tm_sec,
1021 1021                              bytes, zhp->zfs_name);
1022 1022                  } else {
1023 1023                          zfs_nicenum(bytes, buf, sizeof (buf));
1024 1024                          (void) fprintf(stderr, "%02d:%02d:%02d   %5s   %s\n",
1025 1025                              tm->tm_hour, tm->tm_min, tm->tm_sec,
1026 1026                              buf, zhp->zfs_name);
1027 1027                  }
1028 1028          }
1029 1029  }
1030 1030  
1031 1031  static void
1032 1032  send_print_verbose(FILE *fout, const char *tosnap, const char *fromsnap,
1033 1033      uint64_t size, boolean_t parsable)
1034 1034  {
1035 1035          if (parsable) {
1036 1036                  if (fromsnap != NULL) {
1037 1037                          (void) fprintf(fout, "incremental\t%s\t%s",
1038 1038                              fromsnap, tosnap);
1039 1039                  } else {
1040 1040                          (void) fprintf(fout, "full\t%s",
1041 1041                              tosnap);
1042 1042                  }
1043 1043          } else {
1044 1044                  if (fromsnap != NULL) {
1045 1045                          if (strchr(fromsnap, '@') == NULL &&
1046 1046                              strchr(fromsnap, '#') == NULL) {
1047 1047                                  (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1048 1048                                      "send from @%s to %s"),
1049 1049                                      fromsnap, tosnap);
1050 1050                          } else {
1051 1051                                  (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1052 1052                                      "send from %s to %s"),
1053 1053                                      fromsnap, tosnap);
1054 1054                          }
1055 1055                  } else {
1056 1056                          (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1057 1057                              "full send of %s"),
1058 1058                              tosnap);
1059 1059                  }
1060 1060          }
1061 1061  
1062 1062          if (size != 0) {
1063 1063                  if (parsable) {
1064 1064                          (void) fprintf(fout, "\t%llu",
1065 1065                              (longlong_t)size);
1066 1066                  } else {
1067 1067                          char buf[16];
1068 1068                          zfs_nicenum(size, buf, sizeof (buf));
1069 1069                          (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1070 1070                              " estimated size is %s"), buf);
1071 1071                  }
1072 1072          }
1073 1073          (void) fprintf(fout, "\n");
1074 1074  }
1075 1075  
1076 1076  static int
1077 1077  dump_snapshot(zfs_handle_t *zhp, void *arg)
1078 1078  {
1079 1079          send_dump_data_t *sdd = arg;
1080 1080          progress_arg_t pa = { 0 };
1081 1081          pthread_t tid;
1082 1082          char *thissnap;
1083 1083          int err;
1084 1084          boolean_t isfromsnap, istosnap, fromorigin;
1085 1085          boolean_t exclude = B_FALSE;
1086 1086          FILE *fout = sdd->std_out ? stdout : stderr;
1087 1087  
1088 1088          err = 0;
1089 1089          thissnap = strchr(zhp->zfs_name, '@') + 1;
1090 1090          isfromsnap = (sdd->fromsnap != NULL &&
1091 1091              strcmp(sdd->fromsnap, thissnap) == 0);
1092 1092  
1093 1093          if (!sdd->seenfrom && isfromsnap) {
1094 1094                  gather_holds(zhp, sdd);
1095 1095                  sdd->seenfrom = B_TRUE;
1096 1096                  (void) strcpy(sdd->prevsnap, thissnap);
1097 1097                  sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1098 1098                  zfs_close(zhp);
1099 1099                  return (0);
1100 1100          }
1101 1101  
1102 1102          if (sdd->seento || !sdd->seenfrom) {
1103 1103                  zfs_close(zhp);
1104 1104                  return (0);
1105 1105          }
1106 1106  
1107 1107          istosnap = (strcmp(sdd->tosnap, thissnap) == 0);
1108 1108          if (istosnap)
1109 1109                  sdd->seento = B_TRUE;
1110 1110  
1111 1111          if (!sdd->doall && !isfromsnap && !istosnap) {
1112 1112                  if (sdd->replicate) {
1113 1113                          char *snapname;
1114 1114                          nvlist_t *snapprops;
1115 1115                          /*
1116 1116                           * Filter out all intermediate snapshots except origin
1117 1117                           * snapshots needed to replicate clones.
1118 1118                           */
1119 1119                          nvlist_t *nvfs = fsavl_find(sdd->fsavl,
1120 1120                              zhp->zfs_dmustats.dds_guid, &snapname);
1121 1121  
1122 1122                          VERIFY(0 == nvlist_lookup_nvlist(nvfs,
1123 1123                              "snapprops", &snapprops));
1124 1124                          VERIFY(0 == nvlist_lookup_nvlist(snapprops,
1125 1125                              thissnap, &snapprops));
1126 1126                          exclude = !nvlist_exists(snapprops, "is_clone_origin");
1127 1127                  } else {
1128 1128                          exclude = B_TRUE;
1129 1129                  }
1130 1130          }
1131 1131  
1132 1132          /*
1133 1133           * If a filter function exists, call it to determine whether
1134 1134           * this snapshot will be sent.
1135 1135           */
1136 1136          if (exclude || (sdd->filter_cb != NULL &&
1137 1137              sdd->filter_cb(zhp, sdd->filter_cb_arg) == B_FALSE)) {
1138 1138                  /*
1139 1139                   * This snapshot is filtered out.  Don't send it, and don't
1140 1140                   * set prevsnap_obj, so it will be as if this snapshot didn't
1141 1141                   * exist, and the next accepted snapshot will be sent as
1142 1142                   * an incremental from the last accepted one, or as the
1143 1143                   * first (and full) snapshot in the case of a replication,
1144 1144                   * non-incremental send.
1145 1145                   */
1146 1146                  zfs_close(zhp);
1147 1147                  return (0);
1148 1148          }
1149 1149  
1150 1150          gather_holds(zhp, sdd);
1151 1151          fromorigin = sdd->prevsnap[0] == '\0' &&
1152 1152              (sdd->fromorigin || sdd->replicate);
1153 1153  
1154 1154          if (sdd->verbose) {
1155 1155                  uint64_t size = 0;
1156 1156                  (void) estimate_ioctl(zhp, sdd->prevsnap_obj,
1157 1157                      fromorigin, &size);
1158 1158  
1159 1159                  send_print_verbose(fout, zhp->zfs_name,
1160 1160                      sdd->prevsnap[0] ? sdd->prevsnap : NULL,
1161 1161                      size, sdd->parsable);
1162 1162                  sdd->size += size;
1163 1163          }
1164 1164  
1165 1165          if (!sdd->dryrun) {
1166 1166                  /*
1167 1167                   * If progress reporting is requested, spawn a new thread to
1168 1168                   * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1169 1169                   */
1170 1170                  if (sdd->progress) {
1171 1171                          pa.pa_zhp = zhp;
1172 1172                          pa.pa_fd = sdd->outfd;
1173 1173                          pa.pa_parsable = sdd->parsable;
1174 1174  
1175 1175                          if (err = pthread_create(&tid, NULL,
1176 1176                              send_progress_thread, &pa)) {
1177 1177                                  zfs_close(zhp);
1178 1178                                  return (err);
1179 1179                          }
1180 1180                  }
1181 1181  
1182 1182                  enum lzc_send_flags flags = 0;
1183 1183                  if (sdd->large_block)
1184 1184                          flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1185 1185                  if (sdd->embed_data)
1186 1186                          flags |= LZC_SEND_FLAG_EMBED_DATA;
1187 1187  
1188 1188                  err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
1189 1189                      fromorigin, sdd->outfd, flags, sdd->debugnv);
1190 1190  
1191 1191                  if (sdd->progress) {
1192 1192                          (void) pthread_cancel(tid);
1193 1193                          (void) pthread_join(tid, NULL);
1194 1194                  }
1195 1195          }
1196 1196  
1197 1197          (void) strcpy(sdd->prevsnap, thissnap);
1198 1198          sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1199 1199          zfs_close(zhp);
1200 1200          return (err);
1201 1201  }
1202 1202  
1203 1203  static int
1204 1204  dump_filesystem(zfs_handle_t *zhp, void *arg)
1205 1205  {
1206 1206          int rv = 0;
1207 1207          send_dump_data_t *sdd = arg;
1208 1208          boolean_t missingfrom = B_FALSE;
1209 1209          zfs_cmd_t zc = { 0 };
1210 1210  
1211 1211          (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
1212 1212              zhp->zfs_name, sdd->tosnap);
1213 1213          if (ioctl(zhp->zfs_hdl->libzfs_fd, ZFS_IOC_OBJSET_STATS, &zc) != 0) {
1214 1214                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1215 1215                      "WARNING: could not send %s@%s: does not exist\n"),
1216 1216                      zhp->zfs_name, sdd->tosnap);
1217 1217                  sdd->err = B_TRUE;
1218 1218                  return (0);
1219 1219          }
1220 1220  
1221 1221          if (sdd->replicate && sdd->fromsnap) {
1222 1222                  /*
1223 1223                   * If this fs does not have fromsnap, and we're doing
1224 1224                   * recursive, we need to send a full stream from the
1225 1225                   * beginning (or an incremental from the origin if this
1226 1226                   * is a clone).  If we're doing non-recursive, then let
1227 1227                   * them get the error.
1228 1228                   */
1229 1229                  (void) snprintf(zc.zc_name, sizeof (zc.zc_name), "%s@%s",
1230 1230                      zhp->zfs_name, sdd->fromsnap);
1231 1231                  if (ioctl(zhp->zfs_hdl->libzfs_fd,
1232 1232                      ZFS_IOC_OBJSET_STATS, &zc) != 0) {
1233 1233                          missingfrom = B_TRUE;
1234 1234                  }
1235 1235          }
1236 1236  
1237 1237          sdd->seenfrom = sdd->seento = sdd->prevsnap[0] = 0;
1238 1238          sdd->prevsnap_obj = 0;
1239 1239          if (sdd->fromsnap == NULL || missingfrom)
1240 1240                  sdd->seenfrom = B_TRUE;
1241 1241  
1242 1242          rv = zfs_iter_snapshots_sorted(zhp, dump_snapshot, arg);
1243 1243          if (!sdd->seenfrom) {
1244 1244                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1245 1245                      "WARNING: could not send %s@%s:\n"
1246 1246                      "incremental source (%s@%s) does not exist\n"),
1247 1247                      zhp->zfs_name, sdd->tosnap,
1248 1248                      zhp->zfs_name, sdd->fromsnap);
1249 1249                  sdd->err = B_TRUE;
1250 1250          } else if (!sdd->seento) {
1251 1251                  if (sdd->fromsnap) {
1252 1252                          (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1253 1253                              "WARNING: could not send %s@%s:\n"
1254 1254                              "incremental source (%s@%s) "
1255 1255                              "is not earlier than it\n"),
1256 1256                              zhp->zfs_name, sdd->tosnap,
1257 1257                              zhp->zfs_name, sdd->fromsnap);
1258 1258                  } else {
1259 1259                          (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1260 1260                              "WARNING: "
1261 1261                              "could not send %s@%s: does not exist\n"),
1262 1262                              zhp->zfs_name, sdd->tosnap);
1263 1263                  }
1264 1264                  sdd->err = B_TRUE;
1265 1265          }
1266 1266  
1267 1267          return (rv);
1268 1268  }
1269 1269  
1270 1270  static int
1271 1271  dump_filesystems(zfs_handle_t *rzhp, void *arg)
1272 1272  {
1273 1273          send_dump_data_t *sdd = arg;
1274 1274          nvpair_t *fspair;
1275 1275          boolean_t needagain, progress;
1276 1276  
1277 1277          if (!sdd->replicate)
1278 1278                  return (dump_filesystem(rzhp, sdd));
1279 1279  
1280 1280          /* Mark the clone origin snapshots. */
1281 1281          for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1282 1282              fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
1283 1283                  nvlist_t *nvfs;
1284 1284                  uint64_t origin_guid = 0;
1285 1285  
1286 1286                  VERIFY(0 == nvpair_value_nvlist(fspair, &nvfs));
1287 1287                  (void) nvlist_lookup_uint64(nvfs, "origin", &origin_guid);
1288 1288                  if (origin_guid != 0) {
1289 1289                          char *snapname;
1290 1290                          nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
1291 1291                              origin_guid, &snapname);
1292 1292                          if (origin_nv != NULL) {
1293 1293                                  nvlist_t *snapprops;
1294 1294                                  VERIFY(0 == nvlist_lookup_nvlist(origin_nv,
1295 1295                                      "snapprops", &snapprops));
1296 1296                                  VERIFY(0 == nvlist_lookup_nvlist(snapprops,
1297 1297                                      snapname, &snapprops));
1298 1298                                  VERIFY(0 == nvlist_add_boolean(
1299 1299                                      snapprops, "is_clone_origin"));
1300 1300                          }
1301 1301                  }
1302 1302          }
1303 1303  again:
1304 1304          needagain = progress = B_FALSE;
1305 1305          for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1306 1306              fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
1307 1307                  nvlist_t *fslist, *parent_nv;
1308 1308                  char *fsname;
1309 1309                  zfs_handle_t *zhp;
1310 1310                  int err;
1311 1311                  uint64_t origin_guid = 0;
1312 1312                  uint64_t parent_guid = 0;
1313 1313  
1314 1314                  VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
1315 1315                  if (nvlist_lookup_boolean(fslist, "sent") == 0)
1316 1316                          continue;
1317 1317  
1318 1318                  VERIFY(nvlist_lookup_string(fslist, "name", &fsname) == 0);
1319 1319                  (void) nvlist_lookup_uint64(fslist, "origin", &origin_guid);
1320 1320                  (void) nvlist_lookup_uint64(fslist, "parentfromsnap",
1321 1321                      &parent_guid);
1322 1322  
1323 1323                  if (parent_guid != 0) {
1324 1324                          parent_nv = fsavl_find(sdd->fsavl, parent_guid, NULL);
1325 1325                          if (!nvlist_exists(parent_nv, "sent")) {
1326 1326                                  /* parent has not been sent; skip this one */
1327 1327                                  needagain = B_TRUE;
1328 1328                                  continue;
1329 1329                          }
1330 1330                  }
1331 1331  
1332 1332                  if (origin_guid != 0) {
1333 1333                          nvlist_t *origin_nv = fsavl_find(sdd->fsavl,
1334 1334                              origin_guid, NULL);
1335 1335                          if (origin_nv != NULL &&
1336 1336                              !nvlist_exists(origin_nv, "sent")) {
1337 1337                                  /*
1338 1338                                   * origin has not been sent yet;
1339 1339                                   * skip this clone.
1340 1340                                   */
1341 1341                                  needagain = B_TRUE;
1342 1342                                  continue;
1343 1343                          }
1344 1344                  }
1345 1345  
1346 1346                  zhp = zfs_open(rzhp->zfs_hdl, fsname, ZFS_TYPE_DATASET);
1347 1347                  if (zhp == NULL)
1348 1348                          return (-1);
1349 1349                  err = dump_filesystem(zhp, sdd);
1350 1350                  VERIFY(nvlist_add_boolean(fslist, "sent") == 0);
1351 1351                  progress = B_TRUE;
1352 1352                  zfs_close(zhp);
1353 1353                  if (err)
1354 1354                          return (err);
1355 1355          }
1356 1356          if (needagain) {
1357 1357                  assert(progress);
1358 1358                  goto again;
1359 1359          }
1360 1360  
1361 1361          /* clean out the sent flags in case we reuse this fss */
1362 1362          for (fspair = nvlist_next_nvpair(sdd->fss, NULL); fspair;
1363 1363              fspair = nvlist_next_nvpair(sdd->fss, fspair)) {
1364 1364                  nvlist_t *fslist;
1365 1365  
1366 1366                  VERIFY(nvpair_value_nvlist(fspair, &fslist) == 0);
1367 1367                  (void) nvlist_remove_all(fslist, "sent");
1368 1368          }
1369 1369  
1370 1370          return (0);
1371 1371  }
1372 1372  
1373 1373  nvlist_t *
1374 1374  zfs_send_resume_token_to_nvlist(libzfs_handle_t *hdl, const char *token)
1375 1375  {
1376 1376          unsigned int version;
1377 1377          int nread;
1378 1378          unsigned long long checksum, packed_len;
1379 1379  
1380 1380          /*
1381 1381           * Decode token header, which is:
1382 1382           *   <token version>-<checksum of payload>-<uncompressed payload length>
1383 1383           * Note that the only supported token version is 1.
1384 1384           */
1385 1385          nread = sscanf(token, "%u-%llx-%llx-",
1386 1386              &version, &checksum, &packed_len);
1387 1387          if (nread != 3) {
1388 1388                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1389 1389                      "resume token is corrupt (invalid format)"));
1390 1390                  return (NULL);
1391 1391          }
1392 1392  
1393 1393          if (version != ZFS_SEND_RESUME_TOKEN_VERSION) {
1394 1394                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1395 1395                      "resume token is corrupt (invalid version %u)"),
1396 1396                      version);
1397 1397                  return (NULL);
1398 1398          }
1399 1399  
1400 1400          /* convert hexadecimal representation to binary */
1401 1401          token = strrchr(token, '-') + 1;
1402 1402          int len = strlen(token) / 2;
1403 1403          unsigned char *compressed = zfs_alloc(hdl, len);
1404 1404          for (int i = 0; i < len; i++) {
1405 1405                  nread = sscanf(token + i * 2, "%2hhx", compressed + i);
1406 1406                  if (nread != 1) {
1407 1407                          free(compressed);
1408 1408                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1409 1409                              "resume token is corrupt "
1410 1410                              "(payload is not hex-encoded)"));
1411 1411                          return (NULL);
1412 1412                  }
1413 1413          }
1414 1414  
1415 1415          /* verify checksum */
1416 1416          zio_cksum_t cksum;
1417 1417          fletcher_4_native(compressed, len, NULL, &cksum);
1418 1418          if (cksum.zc_word[0] != checksum) {
1419 1419                  free(compressed);
1420 1420                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1421 1421                      "resume token is corrupt (incorrect checksum)"));
1422 1422                  return (NULL);
1423 1423          }
1424 1424  
1425 1425          /* uncompress */
1426 1426          void *packed = zfs_alloc(hdl, packed_len);
1427 1427          uLongf packed_len_long = packed_len;
1428 1428          if (uncompress(packed, &packed_len_long, compressed, len) != Z_OK ||
1429 1429              packed_len_long != packed_len) {
1430 1430                  free(packed);
1431 1431                  free(compressed);
1432 1432                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1433 1433                      "resume token is corrupt (decompression failed)"));
1434 1434                  return (NULL);
1435 1435          }
1436 1436  
1437 1437          /* unpack nvlist */
1438 1438          nvlist_t *nv;
1439 1439          int error = nvlist_unpack(packed, packed_len, &nv, KM_SLEEP);
1440 1440          free(packed);
1441 1441          free(compressed);
1442 1442          if (error != 0) {
1443 1443                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1444 1444                      "resume token is corrupt (nvlist_unpack failed)"));
1445 1445                  return (NULL);
1446 1446          }
1447 1447          return (nv);
1448 1448  }
1449 1449  
1450 1450  int
1451 1451  zfs_send_resume(libzfs_handle_t *hdl, sendflags_t *flags, int outfd,
1452 1452      const char *resume_token)
1453 1453  {
1454 1454          char errbuf[1024];
1455 1455          char *toname;
1456 1456          char *fromname = NULL;
1457 1457          uint64_t resumeobj, resumeoff, toguid, fromguid, bytes;
1458 1458          zfs_handle_t *zhp;
1459 1459          int error = 0;
1460 1460          char name[ZFS_MAXNAMELEN];
1461 1461          enum lzc_send_flags lzc_flags = 0;
1462 1462  
1463 1463          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1464 1464              "cannot resume send"));
1465 1465  
1466 1466          nvlist_t *resume_nvl =
1467 1467              zfs_send_resume_token_to_nvlist(hdl, resume_token);
1468 1468          if (resume_nvl == NULL) {
1469 1469                  /*
1470 1470                   * zfs_error_aux has already been set by
1471 1471                   * zfs_send_resume_token_to_nvlist
1472 1472                   */
1473 1473                  return (zfs_error(hdl, EZFS_FAULT, errbuf));
1474 1474          }
1475 1475          if (flags->verbose) {
1476 1476                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1477 1477                      "resume token contents:\n"));
1478 1478                  nvlist_print(stderr, resume_nvl);
1479 1479          }
1480 1480  
1481 1481          if (nvlist_lookup_string(resume_nvl, "toname", &toname) != 0 ||
1482 1482              nvlist_lookup_uint64(resume_nvl, "object", &resumeobj) != 0 ||
1483 1483              nvlist_lookup_uint64(resume_nvl, "offset", &resumeoff) != 0 ||
1484 1484              nvlist_lookup_uint64(resume_nvl, "bytes", &bytes) != 0 ||
1485 1485              nvlist_lookup_uint64(resume_nvl, "toguid", &toguid) != 0) {
1486 1486                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1487 1487                      "resume token is corrupt"));
1488 1488                  return (zfs_error(hdl, EZFS_FAULT, errbuf));
1489 1489          }
1490 1490          fromguid = 0;
1491 1491          (void) nvlist_lookup_uint64(resume_nvl, "fromguid", &fromguid);
1492 1492  
1493 1493          if (flags->embed_data || nvlist_exists(resume_nvl, "embedok"))
1494 1494                  lzc_flags |= LZC_SEND_FLAG_EMBED_DATA;
1495 1495  
1496 1496          if (guid_to_name(hdl, toname, toguid, B_FALSE, name) != 0) {
1497 1497                  if (zfs_dataset_exists(hdl, toname, ZFS_TYPE_DATASET)) {
1498 1498                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1499 1499                              "'%s' is no longer the same snapshot used in "
1500 1500                              "the initial send"), toname);
1501 1501                  } else {
1502 1502                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1503 1503                              "'%s' used in the initial send no longer exists"),
1504 1504                              toname);
1505 1505                  }
1506 1506                  return (zfs_error(hdl, EZFS_BADPATH, errbuf));
1507 1507          }
1508 1508          zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
1509 1509          if (zhp == NULL) {
1510 1510                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1511 1511                      "unable to access '%s'"), name);
1512 1512                  return (zfs_error(hdl, EZFS_BADPATH, errbuf));
1513 1513          }
1514 1514  
1515 1515          if (fromguid != 0) {
1516 1516                  if (guid_to_name(hdl, toname, fromguid, B_TRUE, name) != 0) {
1517 1517                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1518 1518                              "incremental source %#llx no longer exists"),
1519 1519                              (longlong_t)fromguid);
1520 1520                          return (zfs_error(hdl, EZFS_BADPATH, errbuf));
1521 1521                  }
1522 1522                  fromname = name;
1523 1523          }
1524 1524  
1525 1525          if (flags->verbose) {
1526 1526                  uint64_t size = 0;
1527 1527                  error = lzc_send_space(zhp->zfs_name, fromname, &size);
1528 1528                  if (error == 0)
1529 1529                          size = MAX(0, (int64_t)(size - bytes));
1530 1530                  send_print_verbose(stderr, zhp->zfs_name, fromname,
1531 1531                      size, flags->parsable);
1532 1532          }
1533 1533  
1534 1534          if (!flags->dryrun) {
1535 1535                  progress_arg_t pa = { 0 };
1536 1536                  pthread_t tid;
1537 1537                  /*
1538 1538                   * If progress reporting is requested, spawn a new thread to
1539 1539                   * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1540 1540                   */
1541 1541                  if (flags->progress) {
1542 1542                          pa.pa_zhp = zhp;
1543 1543                          pa.pa_fd = outfd;
1544 1544                          pa.pa_parsable = flags->parsable;
1545 1545  
1546 1546                          error = pthread_create(&tid, NULL,
1547 1547                              send_progress_thread, &pa);
1548 1548                          if (error != 0) {
1549 1549                                  zfs_close(zhp);
1550 1550                                  return (error);
1551 1551                          }
1552 1552                  }
1553 1553  
1554 1554                  error = lzc_send_resume(zhp->zfs_name, fromname, outfd,
1555 1555                      lzc_flags, resumeobj, resumeoff);
1556 1556  
1557 1557                  if (flags->progress) {
1558 1558                          (void) pthread_cancel(tid);
1559 1559                          (void) pthread_join(tid, NULL);
1560 1560                  }
1561 1561  
1562 1562                  char errbuf[1024];
1563 1563                  (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1564 1564                      "warning: cannot send '%s'"), zhp->zfs_name);
1565 1565  
1566 1566                  zfs_close(zhp);
1567 1567  
1568 1568                  switch (error) {
1569 1569                  case 0:
1570 1570                          return (0);
1571 1571                  case EXDEV:
1572 1572                  case ENOENT:
1573 1573                  case EDQUOT:
1574 1574                  case EFBIG:
1575 1575                  case EIO:
1576 1576                  case ENOLINK:
1577 1577                  case ENOSPC:
1578 1578                  case ENOSTR:
1579 1579                  case ENXIO:
1580 1580                  case EPIPE:
1581 1581                  case ERANGE:
1582 1582                  case EFAULT:
1583 1583                  case EROFS:
1584 1584                          zfs_error_aux(hdl, strerror(errno));
1585 1585                          return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
1586 1586  
1587 1587                  default:
1588 1588                          return (zfs_standard_error(hdl, errno, errbuf));
1589 1589                  }
1590 1590          }
1591 1591  
1592 1592  
1593 1593          zfs_close(zhp);
1594 1594  
1595 1595          return (error);
1596 1596  }
1597 1597  
1598 1598  /*
1599 1599   * Generate a send stream for the dataset identified by the argument zhp.
1600 1600   *
1601 1601   * The content of the send stream is the snapshot identified by
1602 1602   * 'tosnap'.  Incremental streams are requested in two ways:
1603 1603   *     - from the snapshot identified by "fromsnap" (if non-null) or
1604 1604   *     - from the origin of the dataset identified by zhp, which must
1605 1605   *       be a clone.  In this case, "fromsnap" is null and "fromorigin"
1606 1606   *       is TRUE.
1607 1607   *
1608 1608   * The send stream is recursive (i.e. dumps a hierarchy of snapshots) and
1609 1609   * uses a special header (with a hdrtype field of DMU_COMPOUNDSTREAM)
1610 1610   * if "replicate" is set.  If "doall" is set, dump all the intermediate
1611 1611   * snapshots. The DMU_COMPOUNDSTREAM header is used in the "doall"
1612 1612   * case too. If "props" is set, send properties.
1613 1613   */
1614 1614  int
1615 1615  zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
1616 1616      sendflags_t *flags, int outfd, snapfilter_cb_t filter_func,
1617 1617      void *cb_arg, nvlist_t **debugnvp)
1618 1618  {
1619 1619          char errbuf[1024];
1620 1620          send_dump_data_t sdd = { 0 };
1621 1621          int err = 0;
1622 1622          nvlist_t *fss = NULL;
1623 1623          avl_tree_t *fsavl = NULL;
1624 1624          static uint64_t holdseq;
1625 1625          int spa_version;
1626 1626          pthread_t tid = 0;
1627 1627          int pipefd[2];
1628 1628          dedup_arg_t dda = { 0 };
1629 1629          int featureflags = 0;
1630 1630          FILE *fout;
1631 1631  
1632 1632          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1633 1633              "cannot send '%s'"), zhp->zfs_name);
1634 1634  
1635 1635          if (fromsnap && fromsnap[0] == '\0') {
1636 1636                  zfs_error_aux(zhp->zfs_hdl, dgettext(TEXT_DOMAIN,
1637 1637                      "zero-length incremental source"));
1638 1638                  return (zfs_error(zhp->zfs_hdl, EZFS_NOENT, errbuf));
1639 1639          }
1640 1640  
1641 1641          if (zhp->zfs_type == ZFS_TYPE_FILESYSTEM) {
1642 1642                  uint64_t version;
1643 1643                  version = zfs_prop_get_int(zhp, ZFS_PROP_VERSION);
1644 1644                  if (version >= ZPL_VERSION_SA) {
1645 1645                          featureflags |= DMU_BACKUP_FEATURE_SA_SPILL;
1646 1646                  }
1647 1647          }
1648 1648  
1649 1649          if (flags->dedup && !flags->dryrun) {
1650 1650                  featureflags |= (DMU_BACKUP_FEATURE_DEDUP |
1651 1651                      DMU_BACKUP_FEATURE_DEDUPPROPS);
1652 1652                  if (err = pipe(pipefd)) {
1653 1653                          zfs_error_aux(zhp->zfs_hdl, strerror(errno));
1654 1654                          return (zfs_error(zhp->zfs_hdl, EZFS_PIPEFAILED,
1655 1655                              errbuf));
1656 1656                  }
1657 1657                  dda.outputfd = outfd;
1658 1658                  dda.inputfd = pipefd[1];
1659 1659                  dda.dedup_hdl = zhp->zfs_hdl;
1660 1660                  if (err = pthread_create(&tid, NULL, cksummer, &dda)) {
1661 1661                          (void) close(pipefd[0]);
1662 1662                          (void) close(pipefd[1]);
1663 1663                          zfs_error_aux(zhp->zfs_hdl, strerror(errno));
1664 1664                          return (zfs_error(zhp->zfs_hdl,
1665 1665                              EZFS_THREADCREATEFAILED, errbuf));
1666 1666                  }
1667 1667          }
1668 1668  
1669 1669          if (flags->replicate || flags->doall || flags->props) {
1670 1670                  dmu_replay_record_t drr = { 0 };
1671 1671                  char *packbuf = NULL;
1672 1672                  size_t buflen = 0;
1673 1673                  zio_cksum_t zc = { 0 };
1674 1674  
1675 1675                  if (flags->replicate || flags->props) {
1676 1676                          nvlist_t *hdrnv;
1677 1677  
1678 1678                          VERIFY(0 == nvlist_alloc(&hdrnv, NV_UNIQUE_NAME, 0));
1679 1679                          if (fromsnap) {
1680 1680                                  VERIFY(0 == nvlist_add_string(hdrnv,
1681 1681                                      "fromsnap", fromsnap));
1682 1682                          }
1683 1683                          VERIFY(0 == nvlist_add_string(hdrnv, "tosnap", tosnap));
1684 1684                          if (!flags->replicate) {
1685 1685                                  VERIFY(0 == nvlist_add_boolean(hdrnv,
1686 1686                                      "not_recursive"));
1687 1687                          }
1688 1688  
1689 1689                          err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
1690 1690                              fromsnap, tosnap, flags->replicate, &fss, &fsavl);
1691 1691                          if (err)
1692 1692                                  goto err_out;
1693 1693                          VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
1694 1694                          err = nvlist_pack(hdrnv, &packbuf, &buflen,
1695 1695                              NV_ENCODE_XDR, 0);
1696 1696                          if (debugnvp)
1697 1697                                  *debugnvp = hdrnv;
1698 1698                          else
1699 1699                                  nvlist_free(hdrnv);
1700 1700                          if (err)
1701 1701                                  goto stderr_out;
1702 1702                  }
1703 1703  
1704 1704                  if (!flags->dryrun) {
1705 1705                          /* write first begin record */
1706 1706                          drr.drr_type = DRR_BEGIN;
1707 1707                          drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
1708 1708                          DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
1709 1709                              drr_versioninfo, DMU_COMPOUNDSTREAM);
1710 1710                          DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
1711 1711                              drr_versioninfo, featureflags);
1712 1712                          (void) snprintf(drr.drr_u.drr_begin.drr_toname,
1713 1713                              sizeof (drr.drr_u.drr_begin.drr_toname),
1714 1714                              "%s@%s", zhp->zfs_name, tosnap);
1715 1715                          drr.drr_payloadlen = buflen;
1716 1716  
1717 1717                          err = dump_record(&drr, packbuf, buflen, &zc, outfd);
1718 1718                          free(packbuf);
1719 1719                          if (err != 0)
1720 1720                                  goto stderr_out;
1721 1721  
1722 1722                          /* write end record */
1723 1723                          bzero(&drr, sizeof (drr));
1724 1724                          drr.drr_type = DRR_END;
1725 1725                          drr.drr_u.drr_end.drr_checksum = zc;
1726 1726                          err = write(outfd, &drr, sizeof (drr));
1727 1727                          if (err == -1) {
1728 1728                                  err = errno;
1729 1729                                  goto stderr_out;
1730 1730                          }
1731 1731  
1732 1732                          err = 0;
1733 1733                  }
1734 1734          }
1735 1735  
1736 1736          /* dump each stream */
1737 1737          sdd.fromsnap = fromsnap;
1738 1738          sdd.tosnap = tosnap;
1739 1739          if (tid != 0)
1740 1740                  sdd.outfd = pipefd[0];
1741 1741          else
1742 1742                  sdd.outfd = outfd;
1743 1743          sdd.replicate = flags->replicate;
1744 1744          sdd.doall = flags->doall;
1745 1745          sdd.fromorigin = flags->fromorigin;
1746 1746          sdd.fss = fss;
1747 1747          sdd.fsavl = fsavl;
1748 1748          sdd.verbose = flags->verbose;
1749 1749          sdd.parsable = flags->parsable;
1750 1750          sdd.progress = flags->progress;
1751 1751          sdd.dryrun = flags->dryrun;
1752 1752          sdd.large_block = flags->largeblock;
1753 1753          sdd.embed_data = flags->embed_data;
1754 1754          sdd.filter_cb = filter_func;
1755 1755          sdd.filter_cb_arg = cb_arg;
1756 1756          if (debugnvp)
1757 1757                  sdd.debugnv = *debugnvp;
1758 1758          if (sdd.verbose && sdd.dryrun)
1759 1759                  sdd.std_out = B_TRUE;
1760 1760          fout = sdd.std_out ? stdout : stderr;
1761 1761  
1762 1762          /*
1763 1763           * Some flags require that we place user holds on the datasets that are
1764 1764           * being sent so they don't get destroyed during the send. We can skip
1765 1765           * this step if the pool is imported read-only since the datasets cannot
1766 1766           * be destroyed.
1767 1767           */
1768 1768          if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
1769 1769              ZPOOL_PROP_READONLY, NULL) &&
1770 1770              zfs_spa_version(zhp, &spa_version) == 0 &&
1771 1771              spa_version >= SPA_VERSION_USERREFS &&
1772 1772              (flags->doall || flags->replicate)) {
1773 1773                  ++holdseq;
1774 1774                  (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
1775 1775                      ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
1776 1776                  sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
1777 1777                  if (sdd.cleanup_fd < 0) {
1778 1778                          err = errno;
1779 1779                          goto stderr_out;
1780 1780                  }
1781 1781                  sdd.snapholds = fnvlist_alloc();
1782 1782          } else {
1783 1783                  sdd.cleanup_fd = -1;
1784 1784                  sdd.snapholds = NULL;
1785 1785          }
1786 1786          if (flags->verbose || sdd.snapholds != NULL) {
1787 1787                  /*
1788 1788                   * Do a verbose no-op dry run to get all the verbose output
1789 1789                   * or to gather snapshot hold's before generating any data,
1790 1790                   * then do a non-verbose real run to generate the streams.
1791 1791                   */
1792 1792                  sdd.dryrun = B_TRUE;
1793 1793                  err = dump_filesystems(zhp, &sdd);
1794 1794  
1795 1795                  if (err != 0)
1796 1796                          goto stderr_out;
1797 1797  
1798 1798                  if (flags->verbose) {
1799 1799                          if (flags->parsable) {
1800 1800                                  (void) fprintf(fout, "size\t%llu\n",
1801 1801                                      (longlong_t)sdd.size);
1802 1802                          } else {
1803 1803                                  char buf[16];
1804 1804                                  zfs_nicenum(sdd.size, buf, sizeof (buf));
1805 1805                                  (void) fprintf(fout, dgettext(TEXT_DOMAIN,
1806 1806                                      "total estimated size is %s\n"), buf);
1807 1807                          }
1808 1808                  }
1809 1809  
1810 1810                  /* Ensure no snaps found is treated as an error. */
1811 1811                  if (!sdd.seento) {
1812 1812                          err = ENOENT;
1813 1813                          goto err_out;
1814 1814                  }
1815 1815  
1816 1816                  /* Skip the second run if dryrun was requested. */
1817 1817                  if (flags->dryrun)
1818 1818                          goto err_out;
1819 1819  
1820 1820                  if (sdd.snapholds != NULL) {
1821 1821                          err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
1822 1822                          if (err != 0)
1823 1823                                  goto stderr_out;
1824 1824  
1825 1825                          fnvlist_free(sdd.snapholds);
1826 1826                          sdd.snapholds = NULL;
1827 1827                  }
1828 1828  
1829 1829                  sdd.dryrun = B_FALSE;
1830 1830                  sdd.verbose = B_FALSE;
1831 1831          }
1832 1832  
1833 1833          err = dump_filesystems(zhp, &sdd);
1834 1834          fsavl_destroy(fsavl);
1835 1835          nvlist_free(fss);
1836 1836  
1837 1837          /* Ensure no snaps found is treated as an error. */
1838 1838          if (err == 0 && !sdd.seento)
1839 1839                  err = ENOENT;
1840 1840  
1841 1841          if (tid != 0) {
1842 1842                  if (err != 0)
1843 1843                          (void) pthread_cancel(tid);
1844 1844                  (void) close(pipefd[0]);
1845 1845                  (void) pthread_join(tid, NULL);
1846 1846          }
1847 1847  
1848 1848          if (sdd.cleanup_fd != -1) {
1849 1849                  VERIFY(0 == close(sdd.cleanup_fd));
1850 1850                  sdd.cleanup_fd = -1;
1851 1851          }
1852 1852  
1853 1853          if (!flags->dryrun && (flags->replicate || flags->doall ||
1854 1854              flags->props)) {
1855 1855                  /*
1856 1856                   * write final end record.  NB: want to do this even if
1857 1857                   * there was some error, because it might not be totally
1858 1858                   * failed.
1859 1859                   */
1860 1860                  dmu_replay_record_t drr = { 0 };
1861 1861                  drr.drr_type = DRR_END;
1862 1862                  if (write(outfd, &drr, sizeof (drr)) == -1) {
1863 1863                          return (zfs_standard_error(zhp->zfs_hdl,
1864 1864                              errno, errbuf));
1865 1865                  }
1866 1866          }
1867 1867  
1868 1868          return (err || sdd.err);
1869 1869  
1870 1870  stderr_out:
1871 1871          err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
1872 1872  err_out:
1873 1873          fsavl_destroy(fsavl);
1874 1874          nvlist_free(fss);
1875 1875          fnvlist_free(sdd.snapholds);
1876 1876  
1877 1877          if (sdd.cleanup_fd != -1)
1878 1878                  VERIFY(0 == close(sdd.cleanup_fd));
1879 1879          if (tid != 0) {
1880 1880                  (void) pthread_cancel(tid);
1881 1881                  (void) close(pipefd[0]);
1882 1882                  (void) pthread_join(tid, NULL);
1883 1883          }
1884 1884          return (err);
1885 1885  }
1886 1886  
1887 1887  int
1888 1888  zfs_send_one(zfs_handle_t *zhp, const char *from, int fd,
1889 1889      enum lzc_send_flags flags)
1890 1890  {
1891 1891          int err;
1892 1892          libzfs_handle_t *hdl = zhp->zfs_hdl;
1893 1893  
1894 1894          char errbuf[1024];
1895 1895          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
1896 1896              "warning: cannot send '%s'"), zhp->zfs_name);
1897 1897  
1898 1898          err = lzc_send(zhp->zfs_name, from, fd, flags);
1899 1899          if (err != 0) {
1900 1900                  switch (errno) {
1901 1901                  case EXDEV:
1902 1902                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1903 1903                              "not an earlier snapshot from the same fs"));
1904 1904                          return (zfs_error(hdl, EZFS_CROSSTARGET, errbuf));
1905 1905  
1906 1906                  case ENOENT:
1907 1907                  case ESRCH:
1908 1908                          if (lzc_exists(zhp->zfs_name)) {
1909 1909                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1910 1910                                      "incremental source (%s) does not exist"),
1911 1911                                      from);
1912 1912                          }
1913 1913                          return (zfs_error(hdl, EZFS_NOENT, errbuf));
1914 1914  
1915 1915                  case EBUSY:
1916 1916                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1917 1917                              "target is busy; if a filesystem, "
1918 1918                              "it must not be mounted"));
1919 1919                          return (zfs_error(hdl, EZFS_BUSY, errbuf));
1920 1920  
1921 1921                  case EDQUOT:
1922 1922                  case EFBIG:
1923 1923                  case EIO:
1924 1924                  case ENOLINK:
1925 1925                  case ENOSPC:
1926 1926                  case ENOSTR:
1927 1927                  case ENXIO:
1928 1928                  case EPIPE:
1929 1929                  case ERANGE:
1930 1930                  case EFAULT:
1931 1931                  case EROFS:
1932 1932                          zfs_error_aux(hdl, strerror(errno));
1933 1933                          return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
1934 1934  
1935 1935                  default:
1936 1936                          return (zfs_standard_error(hdl, errno, errbuf));
1937 1937                  }
1938 1938          }
1939 1939          return (err != 0);
1940 1940  }
1941 1941  
1942 1942  /*
1943 1943   * Routines specific to "zfs recv"
1944 1944   */
1945 1945  
1946 1946  static int
1947 1947  recv_read(libzfs_handle_t *hdl, int fd, void *buf, int ilen,
1948 1948      boolean_t byteswap, zio_cksum_t *zc)
1949 1949  {
1950 1950          char *cp = buf;
1951 1951          int rv;
1952 1952          int len = ilen;
1953 1953  
1954 1954          assert(ilen <= SPA_MAXBLOCKSIZE);
1955 1955  
1956 1956          do {
1957 1957                  rv = read(fd, cp, len);
1958 1958                  cp += rv;
1959 1959                  len -= rv;
1960 1960          } while (rv > 0);
1961 1961  
1962 1962          if (rv < 0 || len != 0) {
1963 1963                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
1964 1964                      "failed to read from stream"));
1965 1965                  return (zfs_error(hdl, EZFS_BADSTREAM, dgettext(TEXT_DOMAIN,
1966 1966                      "cannot receive")));
1967 1967          }
1968 1968  
1969 1969          if (zc) {
1970 1970                  if (byteswap)
1971 1971                          fletcher_4_incremental_byteswap(buf, ilen, zc);
1972 1972                  else
1973 1973                          fletcher_4_incremental_native(buf, ilen, zc);
1974 1974          }
1975 1975          return (0);
1976 1976  }
1977 1977  
1978 1978  static int
1979 1979  recv_read_nvlist(libzfs_handle_t *hdl, int fd, int len, nvlist_t **nvp,
1980 1980      boolean_t byteswap, zio_cksum_t *zc)
1981 1981  {
1982 1982          char *buf;
1983 1983          int err;
1984 1984  
1985 1985          buf = zfs_alloc(hdl, len);
1986 1986          if (buf == NULL)
1987 1987                  return (ENOMEM);
1988 1988  
1989 1989          err = recv_read(hdl, fd, buf, len, byteswap, zc);
1990 1990          if (err != 0) {
1991 1991                  free(buf);
1992 1992                  return (err);
1993 1993          }
1994 1994  
1995 1995          err = nvlist_unpack(buf, len, nvp, 0);
1996 1996          free(buf);
1997 1997          if (err != 0) {
1998 1998                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
1999 1999                      "stream (malformed nvlist)"));
2000 2000                  return (EINVAL);
2001 2001          }
2002 2002          return (0);
2003 2003  }
2004 2004  
2005 2005  static int
2006 2006  recv_rename(libzfs_handle_t *hdl, const char *name, const char *tryname,
2007 2007      int baselen, char *newname, recvflags_t *flags)
2008 2008  {
2009 2009          static int seq;
2010 2010          zfs_cmd_t zc = { 0 };
2011 2011          int err;
2012 2012          prop_changelist_t *clp;
2013 2013          zfs_handle_t *zhp;
2014 2014  
2015 2015          zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
2016 2016          if (zhp == NULL)
2017 2017                  return (-1);
2018 2018          clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
2019 2019              flags->force ? MS_FORCE : 0);
2020 2020          zfs_close(zhp);
2021 2021          if (clp == NULL)
2022 2022                  return (-1);
2023 2023          err = changelist_prefix(clp);
2024 2024          if (err)
2025 2025                  return (err);
2026 2026  
2027 2027          zc.zc_objset_type = DMU_OST_ZFS;
2028 2028          (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
2029 2029  
2030 2030          if (tryname) {
2031 2031                  (void) strcpy(newname, tryname);
2032 2032  
2033 2033                  (void) strlcpy(zc.zc_value, tryname, sizeof (zc.zc_value));
2034 2034  
2035 2035                  if (flags->verbose) {
2036 2036                          (void) printf("attempting rename %s to %s\n",
2037 2037                              zc.zc_name, zc.zc_value);
2038 2038                  }
2039 2039                  err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
2040 2040                  if (err == 0)
2041 2041                          changelist_rename(clp, name, tryname);
2042 2042          } else {
2043 2043                  err = ENOENT;
2044 2044          }
2045 2045  
2046 2046          if (err != 0 && strncmp(name + baselen, "recv-", 5) != 0) {
2047 2047                  seq++;
2048 2048  
2049 2049                  (void) snprintf(newname, ZFS_MAXNAMELEN, "%.*srecv-%u-%u",
2050 2050                      baselen, name, getpid(), seq);
2051 2051                  (void) strlcpy(zc.zc_value, newname, sizeof (zc.zc_value));
2052 2052  
2053 2053                  if (flags->verbose) {
2054 2054                          (void) printf("failed - trying rename %s to %s\n",
2055 2055                              zc.zc_name, zc.zc_value);
2056 2056                  }
2057 2057                  err = ioctl(hdl->libzfs_fd, ZFS_IOC_RENAME, &zc);
2058 2058                  if (err == 0)
2059 2059                          changelist_rename(clp, name, newname);
2060 2060                  if (err && flags->verbose) {
2061 2061                          (void) printf("failed (%u) - "
2062 2062                              "will try again on next pass\n", errno);
2063 2063                  }
2064 2064                  err = EAGAIN;
2065 2065          } else if (flags->verbose) {
2066 2066                  if (err == 0)
2067 2067                          (void) printf("success\n");
2068 2068                  else
2069 2069                          (void) printf("failed (%u)\n", errno);
2070 2070          }
2071 2071  
2072 2072          (void) changelist_postfix(clp);
2073 2073          changelist_free(clp);
2074 2074  
2075 2075          return (err);
2076 2076  }
2077 2077  
2078 2078  static int
2079 2079  recv_destroy(libzfs_handle_t *hdl, const char *name, int baselen,
2080 2080      char *newname, recvflags_t *flags)
2081 2081  {
2082 2082          zfs_cmd_t zc = { 0 };
2083 2083          int err = 0;
2084 2084          prop_changelist_t *clp;
2085 2085          zfs_handle_t *zhp;
2086 2086          boolean_t defer = B_FALSE;
2087 2087          int spa_version;
2088 2088  
2089 2089          zhp = zfs_open(hdl, name, ZFS_TYPE_DATASET);
2090 2090          if (zhp == NULL)
2091 2091                  return (-1);
2092 2092          clp = changelist_gather(zhp, ZFS_PROP_NAME, 0,
2093 2093              flags->force ? MS_FORCE : 0);
2094 2094          if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT &&
2095 2095              zfs_spa_version(zhp, &spa_version) == 0 &&
2096 2096              spa_version >= SPA_VERSION_USERREFS)
2097 2097                  defer = B_TRUE;
2098 2098          zfs_close(zhp);
2099 2099          if (clp == NULL)
2100 2100                  return (-1);
2101 2101          err = changelist_prefix(clp);
2102 2102          if (err)
2103 2103                  return (err);
2104 2104  
2105 2105          zc.zc_objset_type = DMU_OST_ZFS;
2106 2106          zc.zc_defer_destroy = defer;
2107 2107          (void) strlcpy(zc.zc_name, name, sizeof (zc.zc_name));
2108 2108  
2109 2109          if (flags->verbose)
2110 2110                  (void) printf("attempting destroy %s\n", zc.zc_name);
2111 2111          err = ioctl(hdl->libzfs_fd, ZFS_IOC_DESTROY, &zc);
2112 2112          if (err == 0) {
2113 2113                  if (flags->verbose)
2114 2114                          (void) printf("success\n");
2115 2115                  changelist_remove(clp, zc.zc_name);
2116 2116          }
2117 2117  
2118 2118          (void) changelist_postfix(clp);
2119 2119          changelist_free(clp);
2120 2120  
2121 2121          /*
2122 2122           * Deferred destroy might destroy the snapshot or only mark it to be
2123 2123           * destroyed later, and it returns success in either case.
2124 2124           */
2125 2125          if (err != 0 || (defer && zfs_dataset_exists(hdl, name,
2126 2126              ZFS_TYPE_SNAPSHOT))) {
2127 2127                  err = recv_rename(hdl, name, NULL, baselen, newname, flags);
2128 2128          }
2129 2129  
2130 2130          return (err);
2131 2131  }
2132 2132  
2133 2133  typedef struct guid_to_name_data {
2134 2134          uint64_t guid;
2135 2135          boolean_t bookmark_ok;
2136 2136          char *name;
2137 2137          char *skip;
2138 2138  } guid_to_name_data_t;
2139 2139  
2140 2140  static int
2141 2141  guid_to_name_cb(zfs_handle_t *zhp, void *arg)
2142 2142  {
2143 2143          guid_to_name_data_t *gtnd = arg;
2144 2144          const char *slash;
2145 2145          int err;
2146 2146  
2147 2147          if (gtnd->skip != NULL &&
2148 2148              (slash = strrchr(zhp->zfs_name, '/')) != NULL &&
2149 2149              strcmp(slash + 1, gtnd->skip) == 0) {
2150 2150                  zfs_close(zhp);
2151 2151                  return (0);
2152 2152          }
2153 2153  
2154 2154          if (zfs_prop_get_int(zhp, ZFS_PROP_GUID) == gtnd->guid) {
2155 2155                  (void) strcpy(gtnd->name, zhp->zfs_name);
2156 2156                  zfs_close(zhp);
2157 2157                  return (EEXIST);
2158 2158          }
2159 2159  
2160 2160          err = zfs_iter_children(zhp, guid_to_name_cb, gtnd);
2161 2161          if (err != EEXIST && gtnd->bookmark_ok)
2162 2162                  err = zfs_iter_bookmarks(zhp, guid_to_name_cb, gtnd);
2163 2163          zfs_close(zhp);
2164 2164          return (err);
2165 2165  }
2166 2166  
2167 2167  /*
2168 2168   * Attempt to find the local dataset associated with this guid.  In the case of
2169 2169   * multiple matches, we attempt to find the "best" match by searching
2170 2170   * progressively larger portions of the hierarchy.  This allows one to send a
2171 2171   * tree of datasets individually and guarantee that we will find the source
2172 2172   * guid within that hierarchy, even if there are multiple matches elsewhere.
2173 2173   */
2174 2174  static int
2175 2175  guid_to_name(libzfs_handle_t *hdl, const char *parent, uint64_t guid,
2176 2176      boolean_t bookmark_ok, char *name)
2177 2177  {
2178 2178          char pname[ZFS_MAXNAMELEN];
2179 2179          guid_to_name_data_t gtnd;
2180 2180  
2181 2181          gtnd.guid = guid;
2182 2182          gtnd.bookmark_ok = bookmark_ok;
2183 2183          gtnd.name = name;
2184 2184          gtnd.skip = NULL;
2185 2185  
2186 2186          /*
2187 2187           * Search progressively larger portions of the hierarchy, starting
2188 2188           * with the filesystem specified by 'parent'.  This will
2189 2189           * select the "most local" version of the origin snapshot in the case
2190 2190           * that there are multiple matching snapshots in the system.
2191 2191           */
2192 2192          (void) strlcpy(pname, parent, sizeof (pname));
2193 2193          char *cp = strrchr(pname, '@');
2194 2194          if (cp == NULL)
2195 2195                  cp = strchr(pname, '\0');
2196 2196          for (; cp != NULL; cp = strrchr(pname, '/')) {
2197 2197                  /* Chop off the last component and open the parent */
2198 2198                  *cp = '\0';
2199 2199                  zfs_handle_t *zhp = make_dataset_handle(hdl, pname);
2200 2200  
2201 2201                  if (zhp == NULL)
2202 2202                          continue;
2203 2203                  int err = guid_to_name_cb(zfs_handle_dup(zhp), >nd);
2204 2204                  if (err != EEXIST)
2205 2205                          err = zfs_iter_children(zhp, guid_to_name_cb, >nd);
2206 2206                  if (err != EEXIST && bookmark_ok)
2207 2207                          err = zfs_iter_bookmarks(zhp, guid_to_name_cb, >nd);
2208 2208                  zfs_close(zhp);
2209 2209                  if (err == EEXIST)
2210 2210                          return (0);
2211 2211  
2212 2212                  /*
2213 2213                   * Remember the last portion of the dataset so we skip it next
2214 2214                   * time through (as we've already searched that portion of the
2215 2215                   * hierarchy).
2216 2216                   */
2217 2217                  gtnd.skip = strrchr(pname, '/') + 1;
2218 2218          }
2219 2219  
2220 2220          return (ENOENT);
2221 2221  }
2222 2222  
2223 2223  /*
2224 2224   * Return +1 if guid1 is before guid2, 0 if they are the same, and -1 if
2225 2225   * guid1 is after guid2.
2226 2226   */
2227 2227  static int
2228 2228  created_before(libzfs_handle_t *hdl, avl_tree_t *avl,
2229 2229      uint64_t guid1, uint64_t guid2)
2230 2230  {
2231 2231          nvlist_t *nvfs;
2232 2232          char *fsname, *snapname;
2233 2233          char buf[ZFS_MAXNAMELEN];
2234 2234          int rv;
2235 2235          zfs_handle_t *guid1hdl, *guid2hdl;
2236 2236          uint64_t create1, create2;
2237 2237  
2238 2238          if (guid2 == 0)
2239 2239                  return (0);
2240 2240          if (guid1 == 0)
2241 2241                  return (1);
2242 2242  
2243 2243          nvfs = fsavl_find(avl, guid1, &snapname);
2244 2244          VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
2245 2245          (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
2246 2246          guid1hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
2247 2247          if (guid1hdl == NULL)
2248 2248                  return (-1);
2249 2249  
2250 2250          nvfs = fsavl_find(avl, guid2, &snapname);
2251 2251          VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
2252 2252          (void) snprintf(buf, sizeof (buf), "%s@%s", fsname, snapname);
2253 2253          guid2hdl = zfs_open(hdl, buf, ZFS_TYPE_SNAPSHOT);
2254 2254          if (guid2hdl == NULL) {
2255 2255                  zfs_close(guid1hdl);
2256 2256                  return (-1);
2257 2257          }
2258 2258  
2259 2259          create1 = zfs_prop_get_int(guid1hdl, ZFS_PROP_CREATETXG);
2260 2260          create2 = zfs_prop_get_int(guid2hdl, ZFS_PROP_CREATETXG);
2261 2261  
2262 2262          if (create1 < create2)
2263 2263                  rv = -1;
2264 2264          else if (create1 > create2)
2265 2265                  rv = +1;
2266 2266          else
2267 2267                  rv = 0;
2268 2268  
2269 2269          zfs_close(guid1hdl);
2270 2270          zfs_close(guid2hdl);
2271 2271  
2272 2272          return (rv);
2273 2273  }
2274 2274  
2275 2275  static int
2276 2276  recv_incremental_replication(libzfs_handle_t *hdl, const char *tofs,
2277 2277      recvflags_t *flags, nvlist_t *stream_nv, avl_tree_t *stream_avl,
2278 2278      nvlist_t *renamed)
2279 2279  {
2280 2280          nvlist_t *local_nv;
2281 2281          avl_tree_t *local_avl;
2282 2282          nvpair_t *fselem, *nextfselem;
2283 2283          char *fromsnap;
2284 2284          char newname[ZFS_MAXNAMELEN];
2285 2285          int error;
2286 2286          boolean_t needagain, progress, recursive;
2287 2287          char *s1, *s2;
2288 2288  
2289 2289          VERIFY(0 == nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap));
2290 2290  
2291 2291          recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
2292 2292              ENOENT);
2293 2293  
2294 2294          if (flags->dryrun)
2295 2295                  return (0);
2296 2296  
2297 2297  again:
2298 2298          needagain = progress = B_FALSE;
2299 2299  
2300 2300          if ((error = gather_nvlist(hdl, tofs, fromsnap, NULL,
2301 2301              recursive, &local_nv, &local_avl)) != 0)
2302 2302                  return (error);
2303 2303  
2304 2304          /*
2305 2305           * Process deletes and renames
2306 2306           */
2307 2307          for (fselem = nvlist_next_nvpair(local_nv, NULL);
2308 2308              fselem; fselem = nextfselem) {
2309 2309                  nvlist_t *nvfs, *snaps;
2310 2310                  nvlist_t *stream_nvfs = NULL;
2311 2311                  nvpair_t *snapelem, *nextsnapelem;
2312 2312                  uint64_t fromguid = 0;
2313 2313                  uint64_t originguid = 0;
2314 2314                  uint64_t stream_originguid = 0;
2315 2315                  uint64_t parent_fromsnap_guid, stream_parent_fromsnap_guid;
2316 2316                  char *fsname, *stream_fsname;
2317 2317  
2318 2318                  nextfselem = nvlist_next_nvpair(local_nv, fselem);
2319 2319  
2320 2320                  VERIFY(0 == nvpair_value_nvlist(fselem, &nvfs));
2321 2321                  VERIFY(0 == nvlist_lookup_nvlist(nvfs, "snaps", &snaps));
2322 2322                  VERIFY(0 == nvlist_lookup_string(nvfs, "name", &fsname));
2323 2323                  VERIFY(0 == nvlist_lookup_uint64(nvfs, "parentfromsnap",
2324 2324                      &parent_fromsnap_guid));
2325 2325                  (void) nvlist_lookup_uint64(nvfs, "origin", &originguid);
2326 2326  
2327 2327                  /*
2328 2328                   * First find the stream's fs, so we can check for
2329 2329                   * a different origin (due to "zfs promote")
2330 2330                   */
2331 2331                  for (snapelem = nvlist_next_nvpair(snaps, NULL);
2332 2332                      snapelem; snapelem = nvlist_next_nvpair(snaps, snapelem)) {
2333 2333                          uint64_t thisguid;
2334 2334  
2335 2335                          VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
2336 2336                          stream_nvfs = fsavl_find(stream_avl, thisguid, NULL);
2337 2337  
2338 2338                          if (stream_nvfs != NULL)
2339 2339                                  break;
2340 2340                  }
2341 2341  
2342 2342                  /* check for promote */
2343 2343                  (void) nvlist_lookup_uint64(stream_nvfs, "origin",
2344 2344                      &stream_originguid);
2345 2345                  if (stream_nvfs && originguid != stream_originguid) {
2346 2346                          switch (created_before(hdl, local_avl,
2347 2347                              stream_originguid, originguid)) {
2348 2348                          case 1: {
2349 2349                                  /* promote it! */
2350 2350                                  zfs_cmd_t zc = { 0 };
2351 2351                                  nvlist_t *origin_nvfs;
2352 2352                                  char *origin_fsname;
2353 2353  
2354 2354                                  if (flags->verbose)
2355 2355                                          (void) printf("promoting %s\n", fsname);
2356 2356  
2357 2357                                  origin_nvfs = fsavl_find(local_avl, originguid,
2358 2358                                      NULL);
2359 2359                                  VERIFY(0 == nvlist_lookup_string(origin_nvfs,
2360 2360                                      "name", &origin_fsname));
2361 2361                                  (void) strlcpy(zc.zc_value, origin_fsname,
2362 2362                                      sizeof (zc.zc_value));
2363 2363                                  (void) strlcpy(zc.zc_name, fsname,
2364 2364                                      sizeof (zc.zc_name));
2365 2365                                  error = zfs_ioctl(hdl, ZFS_IOC_PROMOTE, &zc);
2366 2366                                  if (error == 0)
2367 2367                                          progress = B_TRUE;
2368 2368                                  break;
2369 2369                          }
2370 2370                          default:
2371 2371                                  break;
2372 2372                          case -1:
2373 2373                                  fsavl_destroy(local_avl);
2374 2374                                  nvlist_free(local_nv);
2375 2375                                  return (-1);
2376 2376                          }
2377 2377                          /*
2378 2378                           * We had/have the wrong origin, therefore our
2379 2379                           * list of snapshots is wrong.  Need to handle
2380 2380                           * them on the next pass.
2381 2381                           */
2382 2382                          needagain = B_TRUE;
2383 2383                          continue;
2384 2384                  }
2385 2385  
2386 2386                  for (snapelem = nvlist_next_nvpair(snaps, NULL);
2387 2387                      snapelem; snapelem = nextsnapelem) {
2388 2388                          uint64_t thisguid;
2389 2389                          char *stream_snapname;
2390 2390                          nvlist_t *found, *props;
2391 2391  
2392 2392                          nextsnapelem = nvlist_next_nvpair(snaps, snapelem);
2393 2393  
2394 2394                          VERIFY(0 == nvpair_value_uint64(snapelem, &thisguid));
2395 2395                          found = fsavl_find(stream_avl, thisguid,
2396 2396                              &stream_snapname);
2397 2397  
2398 2398                          /* check for delete */
2399 2399                          if (found == NULL) {
2400 2400                                  char name[ZFS_MAXNAMELEN];
2401 2401  
2402 2402                                  if (!flags->force)
2403 2403                                          continue;
2404 2404  
2405 2405                                  (void) snprintf(name, sizeof (name), "%s@%s",
2406 2406                                      fsname, nvpair_name(snapelem));
2407 2407  
2408 2408                                  error = recv_destroy(hdl, name,
2409 2409                                      strlen(fsname)+1, newname, flags);
2410 2410                                  if (error)
2411 2411                                          needagain = B_TRUE;
2412 2412                                  else
2413 2413                                          progress = B_TRUE;
2414 2414                                  continue;
2415 2415                          }
2416 2416  
2417 2417                          stream_nvfs = found;
2418 2418  
2419 2419                          if (0 == nvlist_lookup_nvlist(stream_nvfs, "snapprops",
2420 2420                              &props) && 0 == nvlist_lookup_nvlist(props,
2421 2421                              stream_snapname, &props)) {
2422 2422                                  zfs_cmd_t zc = { 0 };
2423 2423  
2424 2424                                  zc.zc_cookie = B_TRUE; /* received */
2425 2425                                  (void) snprintf(zc.zc_name, sizeof (zc.zc_name),
2426 2426                                      "%s@%s", fsname, nvpair_name(snapelem));
2427 2427                                  if (zcmd_write_src_nvlist(hdl, &zc,
2428 2428                                      props) == 0) {
2429 2429                                          (void) zfs_ioctl(hdl,
2430 2430                                              ZFS_IOC_SET_PROP, &zc);
2431 2431                                          zcmd_free_nvlists(&zc);
2432 2432                                  }
2433 2433                          }
2434 2434  
2435 2435                          /* check for different snapname */
2436 2436                          if (strcmp(nvpair_name(snapelem),
2437 2437                              stream_snapname) != 0) {
2438 2438                                  char name[ZFS_MAXNAMELEN];
2439 2439                                  char tryname[ZFS_MAXNAMELEN];
2440 2440  
2441 2441                                  (void) snprintf(name, sizeof (name), "%s@%s",
2442 2442                                      fsname, nvpair_name(snapelem));
2443 2443                                  (void) snprintf(tryname, sizeof (name), "%s@%s",
2444 2444                                      fsname, stream_snapname);
2445 2445  
2446 2446                                  error = recv_rename(hdl, name, tryname,
2447 2447                                      strlen(fsname)+1, newname, flags);
2448 2448                                  if (error)
2449 2449                                          needagain = B_TRUE;
2450 2450                                  else
2451 2451                                          progress = B_TRUE;
2452 2452                          }
2453 2453  
2454 2454                          if (strcmp(stream_snapname, fromsnap) == 0)
2455 2455                                  fromguid = thisguid;
2456 2456                  }
2457 2457  
2458 2458                  /* check for delete */
2459 2459                  if (stream_nvfs == NULL) {
2460 2460                          if (!flags->force)
2461 2461                                  continue;
2462 2462  
2463 2463                          error = recv_destroy(hdl, fsname, strlen(tofs)+1,
2464 2464                              newname, flags);
2465 2465                          if (error)
2466 2466                                  needagain = B_TRUE;
2467 2467                          else
2468 2468                                  progress = B_TRUE;
2469 2469                          continue;
2470 2470                  }
2471 2471  
2472 2472                  if (fromguid == 0) {
2473 2473                          if (flags->verbose) {
2474 2474                                  (void) printf("local fs %s does not have "
2475 2475                                      "fromsnap (%s in stream); must have "
2476 2476                                      "been deleted locally; ignoring\n",
2477 2477                                      fsname, fromsnap);
2478 2478                          }
2479 2479                          continue;
2480 2480                  }
2481 2481  
2482 2482                  VERIFY(0 == nvlist_lookup_string(stream_nvfs,
2483 2483                      "name", &stream_fsname));
2484 2484                  VERIFY(0 == nvlist_lookup_uint64(stream_nvfs,
2485 2485                      "parentfromsnap", &stream_parent_fromsnap_guid));
2486 2486  
2487 2487                  s1 = strrchr(fsname, '/');
2488 2488                  s2 = strrchr(stream_fsname, '/');
2489 2489  
2490 2490                  /*
2491 2491                   * Check for rename. If the exact receive path is specified, it
2492 2492                   * does not count as a rename, but we still need to check the
2493 2493                   * datasets beneath it.
2494 2494                   */
2495 2495                  if ((stream_parent_fromsnap_guid != 0 &&
2496 2496                      parent_fromsnap_guid != 0 &&
2497 2497                      stream_parent_fromsnap_guid != parent_fromsnap_guid) ||
2498 2498                      ((flags->isprefix || strcmp(tofs, fsname) != 0) &&
2499 2499                      (s1 != NULL) && (s2 != NULL) && strcmp(s1, s2) != 0)) {
2500 2500                          nvlist_t *parent;
2501 2501                          char tryname[ZFS_MAXNAMELEN];
2502 2502  
2503 2503                          parent = fsavl_find(local_avl,
2504 2504                              stream_parent_fromsnap_guid, NULL);
2505 2505                          /*
2506 2506                           * NB: parent might not be found if we used the
2507 2507                           * tosnap for stream_parent_fromsnap_guid,
2508 2508                           * because the parent is a newly-created fs;
2509 2509                           * we'll be able to rename it after we recv the
2510 2510                           * new fs.
2511 2511                           */
2512 2512                          if (parent != NULL) {
2513 2513                                  char *pname;
2514 2514  
2515 2515                                  VERIFY(0 == nvlist_lookup_string(parent, "name",
2516 2516                                      &pname));
2517 2517                                  (void) snprintf(tryname, sizeof (tryname),
2518 2518                                      "%s%s", pname, strrchr(stream_fsname, '/'));
2519 2519                          } else {
2520 2520                                  tryname[0] = '\0';
2521 2521                                  if (flags->verbose) {
2522 2522                                          (void) printf("local fs %s new parent "
2523 2523                                              "not found\n", fsname);
2524 2524                                  }
2525 2525                          }
2526 2526  
2527 2527                          newname[0] = '\0';
2528 2528  
2529 2529                          error = recv_rename(hdl, fsname, tryname,
2530 2530                              strlen(tofs)+1, newname, flags);
2531 2531  
2532 2532                          if (renamed != NULL && newname[0] != '\0') {
2533 2533                                  VERIFY(0 == nvlist_add_boolean(renamed,
2534 2534                                      newname));
2535 2535                          }
2536 2536  
2537 2537                          if (error)
2538 2538                                  needagain = B_TRUE;
2539 2539                          else
2540 2540                                  progress = B_TRUE;
2541 2541                  }
2542 2542          }
2543 2543  
2544 2544          fsavl_destroy(local_avl);
2545 2545          nvlist_free(local_nv);
2546 2546  
2547 2547          if (needagain && progress) {
2548 2548                  /* do another pass to fix up temporary names */
2549 2549                  if (flags->verbose)
2550 2550                          (void) printf("another pass:\n");
2551 2551                  goto again;
2552 2552          }
2553 2553  
2554 2554          return (needagain);
2555 2555  }
2556 2556  
2557 2557  static int
2558 2558  zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
2559 2559      recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
2560 2560      char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
2561 2561  {
2562 2562          nvlist_t *stream_nv = NULL;
2563 2563          avl_tree_t *stream_avl = NULL;
2564 2564          char *fromsnap = NULL;
2565 2565          char *sendsnap = NULL;
2566 2566          char *cp;
2567 2567          char tofs[ZFS_MAXNAMELEN];
2568 2568          char sendfs[ZFS_MAXNAMELEN];
2569 2569          char errbuf[1024];
2570 2570          dmu_replay_record_t drre;
2571 2571          int error;
2572 2572          boolean_t anyerr = B_FALSE;
2573 2573          boolean_t softerr = B_FALSE;
2574 2574          boolean_t recursive;
2575 2575  
2576 2576          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2577 2577              "cannot receive"));
2578 2578  
2579 2579          assert(drr->drr_type == DRR_BEGIN);
2580 2580          assert(drr->drr_u.drr_begin.drr_magic == DMU_BACKUP_MAGIC);
2581 2581          assert(DMU_GET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo) ==
2582 2582              DMU_COMPOUNDSTREAM);
2583 2583  
2584 2584          /*
2585 2585           * Read in the nvlist from the stream.
2586 2586           */
2587 2587          if (drr->drr_payloadlen != 0) {
2588 2588                  error = recv_read_nvlist(hdl, fd, drr->drr_payloadlen,
2589 2589                      &stream_nv, flags->byteswap, zc);
2590 2590                  if (error) {
2591 2591                          error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2592 2592                          goto out;
2593 2593                  }
2594 2594          }
2595 2595  
2596 2596          recursive = (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
2597 2597              ENOENT);
2598 2598  
2599 2599          if (recursive && strchr(destname, '@')) {
2600 2600                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2601 2601                      "cannot specify snapshot name for multi-snapshot stream"));
2602 2602                  error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2603 2603                  goto out;
2604 2604          }
2605 2605  
2606 2606          /*
2607 2607           * Read in the end record and verify checksum.
2608 2608           */
2609 2609          if (0 != (error = recv_read(hdl, fd, &drre, sizeof (drre),
2610 2610              flags->byteswap, NULL)))
2611 2611                  goto out;
2612 2612          if (flags->byteswap) {
2613 2613                  drre.drr_type = BSWAP_32(drre.drr_type);
2614 2614                  drre.drr_u.drr_end.drr_checksum.zc_word[0] =
2615 2615                      BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[0]);
2616 2616                  drre.drr_u.drr_end.drr_checksum.zc_word[1] =
2617 2617                      BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[1]);
2618 2618                  drre.drr_u.drr_end.drr_checksum.zc_word[2] =
2619 2619                      BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[2]);
2620 2620                  drre.drr_u.drr_end.drr_checksum.zc_word[3] =
2621 2621                      BSWAP_64(drre.drr_u.drr_end.drr_checksum.zc_word[3]);
2622 2622          }
2623 2623          if (drre.drr_type != DRR_END) {
2624 2624                  error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2625 2625                  goto out;
2626 2626          }
2627 2627          if (!ZIO_CHECKSUM_EQUAL(drre.drr_u.drr_end.drr_checksum, *zc)) {
2628 2628                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2629 2629                      "incorrect header checksum"));
2630 2630                  error = zfs_error(hdl, EZFS_BADSTREAM, errbuf);
2631 2631                  goto out;
2632 2632          }
2633 2633  
2634 2634          (void) nvlist_lookup_string(stream_nv, "fromsnap", &fromsnap);
2635 2635  
2636 2636          if (drr->drr_payloadlen != 0) {
2637 2637                  nvlist_t *stream_fss;
2638 2638  
2639 2639                  VERIFY(0 == nvlist_lookup_nvlist(stream_nv, "fss",
2640 2640                      &stream_fss));
2641 2641                  if ((stream_avl = fsavl_create(stream_fss)) == NULL) {
2642 2642                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2643 2643                              "couldn't allocate avl tree"));
2644 2644                          error = zfs_error(hdl, EZFS_NOMEM, errbuf);
2645 2645                          goto out;
2646 2646                  }
2647 2647  
2648 2648                  if (fromsnap != NULL) {
2649 2649                          nvlist_t *renamed = NULL;
2650 2650                          nvpair_t *pair = NULL;
2651 2651  
2652 2652                          (void) strlcpy(tofs, destname, ZFS_MAXNAMELEN);
2653 2653                          if (flags->isprefix) {
2654 2654                                  struct drr_begin *drrb = &drr->drr_u.drr_begin;
2655 2655                                  int i;
2656 2656  
2657 2657                                  if (flags->istail) {
2658 2658                                          cp = strrchr(drrb->drr_toname, '/');
2659 2659                                          if (cp == NULL) {
2660 2660                                                  (void) strlcat(tofs, "/",
2661 2661                                                      ZFS_MAXNAMELEN);
2662 2662                                                  i = 0;
2663 2663                                          } else {
2664 2664                                                  i = (cp - drrb->drr_toname);
2665 2665                                          }
2666 2666                                  } else {
2667 2667                                          i = strcspn(drrb->drr_toname, "/@");
2668 2668                                  }
2669 2669                                  /* zfs_receive_one() will create_parents() */
2670 2670                                  (void) strlcat(tofs, &drrb->drr_toname[i],
2671 2671                                      ZFS_MAXNAMELEN);
2672 2672                                  *strchr(tofs, '@') = '\0';
2673 2673                          }
2674 2674  
2675 2675                          if (recursive && !flags->dryrun && !flags->nomount) {
2676 2676                                  VERIFY(0 == nvlist_alloc(&renamed,
2677 2677                                      NV_UNIQUE_NAME, 0));
2678 2678                          }
2679 2679  
2680 2680                          softerr = recv_incremental_replication(hdl, tofs, flags,
2681 2681                              stream_nv, stream_avl, renamed);
2682 2682  
2683 2683                          /* Unmount renamed filesystems before receiving. */
2684 2684                          while ((pair = nvlist_next_nvpair(renamed,
2685 2685                              pair)) != NULL) {
2686 2686                                  zfs_handle_t *zhp;
2687 2687                                  prop_changelist_t *clp = NULL;
2688 2688  
2689 2689                                  zhp = zfs_open(hdl, nvpair_name(pair),
2690 2690                                      ZFS_TYPE_FILESYSTEM);
2691 2691                                  if (zhp != NULL) {
2692 2692                                          clp = changelist_gather(zhp,
2693 2693                                              ZFS_PROP_MOUNTPOINT, 0, 0);
2694 2694                                          zfs_close(zhp);
2695 2695                                          if (clp != NULL) {
2696 2696                                                  softerr |=
2697 2697                                                      changelist_prefix(clp);
2698 2698                                                  changelist_free(clp);
2699 2699                                          }
2700 2700                                  }
2701 2701                          }
2702 2702  
2703 2703                          nvlist_free(renamed);
2704 2704                  }
2705 2705          }
2706 2706  
2707 2707          /*
2708 2708           * Get the fs specified by the first path in the stream (the top level
2709 2709           * specified by 'zfs send') and pass it to each invocation of
2710 2710           * zfs_receive_one().
2711 2711           */
2712 2712          (void) strlcpy(sendfs, drr->drr_u.drr_begin.drr_toname,
2713 2713              ZFS_MAXNAMELEN);
2714 2714          if ((cp = strchr(sendfs, '@')) != NULL) {
2715 2715                  *cp = '\0';
2716 2716                  /*
2717 2717                   * Find the "sendsnap", the final snapshot in a replication
2718 2718                   * stream, so zfs_receive_one() can set filesystem properties
2719 2719                   * ONLY when receiving that final snapshot.
2720 2720                   */
2721 2721                  sendsnap = (cp + 1);
2722 2722          }
2723 2723  
2724 2724          /* Finally, receive each contained stream */
2725 2725          do {
2726 2726                  /*
2727 2727                   * we should figure out if it has a recoverable
2728 2728                   * error, in which case do a recv_skip() and drive on.
2729 2729                   * Note, if we fail due to already having this guid,
2730 2730                   * zfs_receive_one() will take care of it (ie,
2731 2731                   * recv_skip() and return 0).
2732 2732                   */
2733 2733                  error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
2734 2734                      sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
2735 2735                      action_handlep, sendsnap);
2736 2736                  if (error == ENODATA) {
2737 2737                          error = 0;
2738 2738                          break;
2739 2739                  }
2740 2740                  anyerr |= error;
2741 2741          } while (error == 0);
2742 2742  
2743 2743          if (drr->drr_payloadlen != 0 && fromsnap != NULL) {
2744 2744                  /*
2745 2745                   * Now that we have the fs's they sent us, try the
2746 2746                   * renames again.
2747 2747                   */
2748 2748                  softerr = recv_incremental_replication(hdl, tofs, flags,
2749 2749                      stream_nv, stream_avl, NULL);
2750 2750          }
2751 2751  
2752 2752  out:
2753 2753          fsavl_destroy(stream_avl);
2754 2754          if (stream_nv)
2755 2755                  nvlist_free(stream_nv);
2756 2756          if (softerr)
2757 2757                  error = -2;
2758 2758          if (anyerr)
2759 2759                  error = -1;
2760 2760          return (error);
2761 2761  }
2762 2762  
2763 2763  static void
2764 2764  trunc_prop_errs(int truncated)
2765 2765  {
2766 2766          ASSERT(truncated != 0);
2767 2767  
2768 2768          if (truncated == 1)
2769 2769                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2770 2770                      "1 more property could not be set\n"));
2771 2771          else
2772 2772                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
2773 2773                      "%d more properties could not be set\n"), truncated);
2774 2774  }
2775 2775  
2776 2776  static int
2777 2777  recv_skip(libzfs_handle_t *hdl, int fd, boolean_t byteswap)
2778 2778  {
2779 2779          dmu_replay_record_t *drr;
2780 2780          void *buf = zfs_alloc(hdl, SPA_MAXBLOCKSIZE);
2781 2781          char errbuf[1024];
2782 2782  
2783 2783          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2784 2784              "cannot receive:"));
2785 2785  
2786 2786          /* XXX would be great to use lseek if possible... */
2787 2787          drr = buf;
2788 2788  
2789 2789          while (recv_read(hdl, fd, drr, sizeof (dmu_replay_record_t),
2790 2790              byteswap, NULL) == 0) {
2791 2791                  if (byteswap)
2792 2792                          drr->drr_type = BSWAP_32(drr->drr_type);
2793 2793  
2794 2794                  switch (drr->drr_type) {
2795 2795                  case DRR_BEGIN:
2796 2796                          if (drr->drr_payloadlen != 0) {
2797 2797                                  (void) recv_read(hdl, fd, buf,
2798 2798                                      drr->drr_payloadlen, B_FALSE, NULL);
2799 2799                          }
2800 2800                          break;
2801 2801  
2802 2802                  case DRR_END:
2803 2803                          free(buf);
2804 2804                          return (0);
2805 2805  
2806 2806                  case DRR_OBJECT:
2807 2807                          if (byteswap) {
2808 2808                                  drr->drr_u.drr_object.drr_bonuslen =
2809 2809                                      BSWAP_32(drr->drr_u.drr_object.
2810 2810                                      drr_bonuslen);
2811 2811                          }
2812 2812                          (void) recv_read(hdl, fd, buf,
2813 2813                              P2ROUNDUP(drr->drr_u.drr_object.drr_bonuslen, 8),
2814 2814                              B_FALSE, NULL);
2815 2815                          break;
2816 2816  
2817 2817                  case DRR_WRITE:
2818 2818                          if (byteswap) {
2819 2819                                  drr->drr_u.drr_write.drr_length =
2820 2820                                      BSWAP_64(drr->drr_u.drr_write.drr_length);
2821 2821                          }
2822 2822                          (void) recv_read(hdl, fd, buf,
2823 2823                              drr->drr_u.drr_write.drr_length, B_FALSE, NULL);
2824 2824                          break;
2825 2825                  case DRR_SPILL:
2826 2826                          if (byteswap) {
2827 2827                                  drr->drr_u.drr_write.drr_length =
2828 2828                                      BSWAP_64(drr->drr_u.drr_spill.drr_length);
2829 2829                          }
2830 2830                          (void) recv_read(hdl, fd, buf,
2831 2831                              drr->drr_u.drr_spill.drr_length, B_FALSE, NULL);
2832 2832                          break;
2833 2833                  case DRR_WRITE_EMBEDDED:
2834 2834                          if (byteswap) {
2835 2835                                  drr->drr_u.drr_write_embedded.drr_psize =
2836 2836                                      BSWAP_32(drr->drr_u.drr_write_embedded.
2837 2837                                      drr_psize);
2838 2838                          }
2839 2839                          (void) recv_read(hdl, fd, buf,
2840 2840                              P2ROUNDUP(drr->drr_u.drr_write_embedded.drr_psize,
2841 2841                              8), B_FALSE, NULL);
2842 2842                          break;
2843 2843                  case DRR_WRITE_BYREF:
2844 2844                  case DRR_FREEOBJECTS:
2845 2845                  case DRR_FREE:
2846 2846                          break;
2847 2847  
2848 2848                  default:
2849 2849                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2850 2850                              "invalid record type"));
2851 2851                          return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
2852 2852                  }
2853 2853          }
2854 2854  
2855 2855          free(buf);
2856 2856          return (-1);
2857 2857  }
2858 2858  
2859 2859  static void
2860 2860  recv_ecksum_set_aux(libzfs_handle_t *hdl, const char *target_snap,
2861 2861      boolean_t resumable)
2862 2862  {
2863 2863          char target_fs[ZFS_MAXNAMELEN];
2864 2864  
2865 2865          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2866 2866              "checksum mismatch or incomplete stream"));
2867 2867  
2868 2868          if (!resumable)
2869 2869                  return;
2870 2870          (void) strlcpy(target_fs, target_snap, sizeof (target_fs));
2871 2871          *strchr(target_fs, '@') = '\0';
2872 2872          zfs_handle_t *zhp = zfs_open(hdl, target_fs,
2873 2873              ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
2874 2874          if (zhp == NULL)
2875 2875                  return;
2876 2876  
2877 2877          char token_buf[ZFS_MAXPROPLEN];
2878 2878          int error = zfs_prop_get(zhp, ZFS_PROP_RECEIVE_RESUME_TOKEN,
2879 2879              token_buf, sizeof (token_buf),
2880 2880              NULL, NULL, 0, B_TRUE);
2881 2881          if (error == 0) {
2882 2882                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
2883 2883                      "checksum mismatch or incomplete stream.\n"
2884 2884                      "Partially received snapshot is saved.\n"
2885 2885                      "A resuming stream can be generated on the sending "
2886 2886                      "system by running:\n"
2887 2887                      "    zfs send -t %s"),
2888 2888                      token_buf);
2889 2889          }
2890 2890          zfs_close(zhp);
2891 2891  }
2892 2892  
2893 2893  /*
2894 2894   * Restores a backup of tosnap from the file descriptor specified by infd.
2895 2895   */
2896 2896  static int
2897 2897  zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
2898 2898      const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
2899 2899      dmu_replay_record_t *drr_noswap, const char *sendfs,
2900 2900      avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
2901 2901      uint64_t *action_handlep, const char *finalsnap)
2902 2902  {
2903 2903          zfs_cmd_t zc = { 0 };
2904 2904          time_t begin_time;
2905 2905          int ioctl_err, ioctl_errno, err;
2906 2906          char *cp;
  
    | 
      ↓ open down ↓ | 
    2906 lines elided | 
    
      ↑ open up ↑ | 
  
2907 2907          struct drr_begin *drrb = &drr->drr_u.drr_begin;
2908 2908          char errbuf[1024];
2909 2909          char prop_errbuf[1024];
2910 2910          const char *chopprefix;
2911 2911          boolean_t newfs = B_FALSE;
2912 2912          boolean_t stream_wantsnewfs;
2913 2913          uint64_t parent_snapguid = 0;
2914 2914          prop_changelist_t *clp = NULL;
2915 2915          nvlist_t *snapprops_nvlist = NULL;
2916 2916          zprop_errflags_t prop_errflags;
     2917 +        char *snapname = NULL;
2917 2918  
2918 2919          begin_time = time(NULL);
2919 2920  
2920 2921          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
2921 2922              "cannot receive"));
2922 2923  
2923 2924          if (stream_avl != NULL) {
2924      -                char *snapname;
2925 2925                  nvlist_t *fs = fsavl_find(stream_avl, drrb->drr_toguid,
2926 2926                      &snapname);
2927 2927                  nvlist_t *props;
2928 2928                  int ret;
2929      -                boolean_t is_finalsnap;
2930 2929  
2931      -                VERIFY(fs != NULL);
2932 2930                  (void) nvlist_lookup_uint64(fs, "parentfromsnap",
2933 2931                      &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)
     2932 +                err = nvlist_lookup_nvlist(fs, "props", &props);
     2933 +                if (err)
2943 2934                          VERIFY(0 == nvlist_alloc(&props, NV_UNIQUE_NAME, 0));
2944 2935  
2945 2936                  if (flags->canmountoff) {
2946 2937                          VERIFY(0 == nvlist_add_uint64(props,
2947 2938                              zfs_prop_to_name(ZFS_PROP_CANMOUNT), 0));
2948 2939                  }
2949 2940                  ret = zcmd_write_src_nvlist(hdl, &zc, props);
2950      -                if (!is_finalsnap || err)
     2941 +                if (err)
2951 2942                          nvlist_free(props);
2952 2943  
2953 2944                  if (0 == nvlist_lookup_nvlist(fs, "snapprops", &props)) {
2954 2945                          VERIFY(0 == nvlist_lookup_nvlist(props,
2955 2946                              snapname, &snapprops_nvlist));
2956 2947                  }
2957 2948  
2958 2949                  if (ret != 0)
2959 2950                          return (-1);
2960 2951          }
2961 2952  
2962 2953          cp = NULL;
2963 2954  
2964 2955          /*
2965 2956           * Determine how much of the snapshot name stored in the stream
2966 2957           * we are going to tack on to the name they specified on the
2967 2958           * command line, and how much we are going to chop off.
2968 2959           *
2969 2960           * If they specified a snapshot, chop the entire name stored in
2970 2961           * the stream.
2971 2962           */
2972 2963          if (flags->istail) {
2973 2964                  /*
2974 2965                   * A filesystem was specified with -e. We want to tack on only
2975 2966                   * the tail of the sent snapshot path.
2976 2967                   */
2977 2968                  if (strchr(tosnap, '@')) {
2978 2969                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
2979 2970                              "argument - snapshot not allowed with -e"));
2980 2971                          return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
2981 2972                  }
2982 2973  
2983 2974                  chopprefix = strrchr(sendfs, '/');
2984 2975  
2985 2976                  if (chopprefix == NULL) {
2986 2977                          /*
2987 2978                           * The tail is the poolname, so we need to
2988 2979                           * prepend a path separator.
2989 2980                           */
2990 2981                          int len = strlen(drrb->drr_toname);
2991 2982                          cp = malloc(len + 2);
2992 2983                          cp[0] = '/';
2993 2984                          (void) strcpy(&cp[1], drrb->drr_toname);
2994 2985                          chopprefix = cp;
2995 2986                  } else {
2996 2987                          chopprefix = drrb->drr_toname + (chopprefix - sendfs);
2997 2988                  }
2998 2989          } else if (flags->isprefix) {
2999 2990                  /*
3000 2991                   * A filesystem was specified with -d. We want to tack on
3001 2992                   * everything but the first element of the sent snapshot path
3002 2993                   * (all but the pool name).
3003 2994                   */
3004 2995                  if (strchr(tosnap, '@')) {
3005 2996                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
3006 2997                              "argument - snapshot not allowed with -d"));
3007 2998                          return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3008 2999                  }
3009 3000  
3010 3001                  chopprefix = strchr(drrb->drr_toname, '/');
3011 3002                  if (chopprefix == NULL)
3012 3003                          chopprefix = strchr(drrb->drr_toname, '@');
3013 3004          } else if (strchr(tosnap, '@') == NULL) {
3014 3005                  /*
3015 3006                   * If a filesystem was specified without -d or -e, we want to
3016 3007                   * tack on everything after the fs specified by 'zfs send'.
3017 3008                   */
3018 3009                  chopprefix = drrb->drr_toname + strlen(sendfs);
3019 3010          } else {
3020 3011                  /* A snapshot was specified as an exact path (no -d or -e). */
3021 3012                  if (flags->recursive) {
3022 3013                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3023 3014                              "cannot specify snapshot name for multi-snapshot "
3024 3015                              "stream"));
3025 3016                          return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
3026 3017                  }
3027 3018                  chopprefix = drrb->drr_toname + strlen(drrb->drr_toname);
3028 3019          }
3029 3020  
3030 3021          ASSERT(strstr(drrb->drr_toname, sendfs) == drrb->drr_toname);
3031 3022          ASSERT(chopprefix > drrb->drr_toname);
3032 3023          ASSERT(chopprefix <= drrb->drr_toname + strlen(drrb->drr_toname));
3033 3024          ASSERT(chopprefix[0] == '/' || chopprefix[0] == '@' ||
3034 3025              chopprefix[0] == '\0');
3035 3026  
3036 3027          /*
3037 3028           * Determine name of destination snapshot, store in zc_value.
3038 3029           */
3039 3030          (void) strcpy(zc.zc_value, tosnap);
3040 3031          (void) strncat(zc.zc_value, chopprefix, sizeof (zc.zc_value));
3041 3032          free(cp);
3042 3033          if (!zfs_name_valid(zc.zc_value, ZFS_TYPE_SNAPSHOT)) {
3043 3034                  zcmd_free_nvlists(&zc);
3044 3035                  return (zfs_error(hdl, EZFS_INVALIDNAME, errbuf));
3045 3036          }
3046 3037  
3047 3038          /*
3048 3039           * Determine the name of the origin snapshot, store in zc_string.
3049 3040           */
3050 3041          if (drrb->drr_flags & DRR_FLAG_CLONE) {
3051 3042                  if (guid_to_name(hdl, zc.zc_value,
3052 3043                      drrb->drr_fromguid, B_FALSE, zc.zc_string) != 0) {
3053 3044                          zcmd_free_nvlists(&zc);
3054 3045                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3055 3046                              "local origin for clone %s does not exist"),
3056 3047                              zc.zc_value);
3057 3048                          return (zfs_error(hdl, EZFS_NOENT, errbuf));
3058 3049                  }
3059 3050                  if (flags->verbose)
3060 3051                          (void) printf("found clone origin %s\n", zc.zc_string);
3061 3052          } else if (originsnap) {
3062 3053                  (void) strncpy(zc.zc_string, originsnap, ZFS_MAXNAMELEN);
3063 3054                  if (flags->verbose)
3064 3055                          (void) printf("using provided clone origin %s\n",
3065 3056                              zc.zc_string);
3066 3057          }
3067 3058  
3068 3059          boolean_t resuming = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo) &
3069 3060              DMU_BACKUP_FEATURE_RESUMING;
3070 3061          stream_wantsnewfs = (drrb->drr_fromguid == NULL ||
3071 3062              (drrb->drr_flags & DRR_FLAG_CLONE) || originsnap) && !resuming;
3072 3063  
3073 3064          if (stream_wantsnewfs) {
3074 3065                  /*
3075 3066                   * if the parent fs does not exist, look for it based on
3076 3067                   * the parent snap GUID
3077 3068                   */
3078 3069                  (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3079 3070                      "cannot receive new filesystem stream"));
3080 3071  
3081 3072                  (void) strcpy(zc.zc_name, zc.zc_value);
3082 3073                  cp = strrchr(zc.zc_name, '/');
3083 3074                  if (cp)
3084 3075                          *cp = '\0';
3085 3076                  if (cp &&
3086 3077                      !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
3087 3078                          char suffix[ZFS_MAXNAMELEN];
3088 3079                          (void) strcpy(suffix, strrchr(zc.zc_value, '/'));
3089 3080                          if (guid_to_name(hdl, zc.zc_name, parent_snapguid,
3090 3081                              B_FALSE, zc.zc_value) == 0) {
3091 3082                                  *strchr(zc.zc_value, '@') = '\0';
3092 3083                                  (void) strcat(zc.zc_value, suffix);
3093 3084                          }
3094 3085                  }
3095 3086          } else {
3096 3087                  /*
3097 3088                   * if the fs does not exist, look for it based on the
3098 3089                   * fromsnap GUID
3099 3090                   */
3100 3091                  (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3101 3092                      "cannot receive incremental stream"));
3102 3093  
3103 3094                  (void) strcpy(zc.zc_name, zc.zc_value);
3104 3095                  *strchr(zc.zc_name, '@') = '\0';
3105 3096  
3106 3097                  /*
3107 3098                   * If the exact receive path was specified and this is the
3108 3099                   * topmost path in the stream, then if the fs does not exist we
3109 3100                   * should look no further.
3110 3101                   */
3111 3102                  if ((flags->isprefix || (*(chopprefix = drrb->drr_toname +
3112 3103                      strlen(sendfs)) != '\0' && *chopprefix != '@')) &&
3113 3104                      !zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
3114 3105                          char snap[ZFS_MAXNAMELEN];
3115 3106                          (void) strcpy(snap, strchr(zc.zc_value, '@'));
3116 3107                          if (guid_to_name(hdl, zc.zc_name, drrb->drr_fromguid,
3117 3108                              B_FALSE, zc.zc_value) == 0) {
3118 3109                                  *strchr(zc.zc_value, '@') = '\0';
3119 3110                                  (void) strcat(zc.zc_value, snap);
3120 3111                          }
3121 3112                  }
3122 3113          }
3123 3114  
3124 3115          (void) strcpy(zc.zc_name, zc.zc_value);
3125 3116          *strchr(zc.zc_name, '@') = '\0';
3126 3117  
3127 3118          if (zfs_dataset_exists(hdl, zc.zc_name, ZFS_TYPE_DATASET)) {
3128 3119                  zfs_handle_t *zhp;
3129 3120  
3130 3121                  /*
3131 3122                   * Destination fs exists.  It must be one of these cases:
3132 3123                   *  - an incremental send stream
3133 3124                   *  - the stream specifies a new fs (full stream or clone)
3134 3125                   *    and they want us to blow away the existing fs (and
3135 3126                   *    have therefore specified -F and removed any snapshots)
3136 3127                   *  - we are resuming a failed receive.
3137 3128                   */
3138 3129                  if (stream_wantsnewfs) {
3139 3130                          if (!flags->force) {
3140 3131                                  zcmd_free_nvlists(&zc);
3141 3132                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3142 3133                                      "destination '%s' exists\n"
3143 3134                                      "must specify -F to overwrite it"),
3144 3135                                      zc.zc_name);
3145 3136                                  return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3146 3137                          }
3147 3138                          if (ioctl(hdl->libzfs_fd, ZFS_IOC_SNAPSHOT_LIST_NEXT,
3148 3139                              &zc) == 0) {
3149 3140                                  zcmd_free_nvlists(&zc);
3150 3141                                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3151 3142                                      "destination has snapshots (eg. %s)\n"
3152 3143                                      "must destroy them to overwrite it"),
3153 3144                                      zc.zc_name);
3154 3145                                  return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3155 3146                          }
3156 3147                  }
3157 3148  
3158 3149                  if ((zhp = zfs_open(hdl, zc.zc_name,
3159 3150                      ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) {
3160 3151                          zcmd_free_nvlists(&zc);
3161 3152                          return (-1);
3162 3153                  }
3163 3154  
3164 3155                  if (stream_wantsnewfs &&
3165 3156                      zhp->zfs_dmustats.dds_origin[0]) {
3166 3157                          zcmd_free_nvlists(&zc);
3167 3158                          zfs_close(zhp);
3168 3159                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3169 3160                              "destination '%s' is a clone\n"
3170 3161                              "must destroy it to overwrite it"),
3171 3162                              zc.zc_name);
3172 3163                          return (zfs_error(hdl, EZFS_EXISTS, errbuf));
3173 3164                  }
3174 3165  
3175 3166                  if (!flags->dryrun && zhp->zfs_type == ZFS_TYPE_FILESYSTEM &&
3176 3167                      stream_wantsnewfs) {
3177 3168                          /* We can't do online recv in this case */
3178 3169                          clp = changelist_gather(zhp, ZFS_PROP_NAME, 0, 0);
3179 3170                          if (clp == NULL) {
3180 3171                                  zfs_close(zhp);
3181 3172                                  zcmd_free_nvlists(&zc);
3182 3173                                  return (-1);
3183 3174                          }
3184 3175                          if (changelist_prefix(clp) != 0) {
3185 3176                                  changelist_free(clp);
3186 3177                                  zfs_close(zhp);
3187 3178                                  zcmd_free_nvlists(&zc);
3188 3179                                  return (-1);
3189 3180                          }
3190 3181                  }
3191 3182  
3192 3183                  /*
3193 3184                   * If we are resuming a newfs, set newfs here so that we will
3194 3185                   * mount it if the recv succeeds this time.  We can tell
3195 3186                   * that it was a newfs on the first recv because the fs
3196 3187                   * itself will be inconsistent (if the fs existed when we
3197 3188                   * did the first recv, we would have received it into
3198 3189                   * .../%recv).
3199 3190                   */
3200 3191                  if (resuming && zfs_prop_get_int(zhp, ZFS_PROP_INCONSISTENT))
3201 3192                          newfs = B_TRUE;
3202 3193  
3203 3194                  zfs_close(zhp);
3204 3195          } else {
3205 3196                  /*
3206 3197                   * Destination filesystem does not exist.  Therefore we better
3207 3198                   * be creating a new filesystem (either from a full backup, or
3208 3199                   * a clone).  It would therefore be invalid if the user
3209 3200                   * specified only the pool name (i.e. if the destination name
3210 3201                   * contained no slash character).
3211 3202                   */
3212 3203                  if (!stream_wantsnewfs ||
3213 3204                      (cp = strrchr(zc.zc_name, '/')) == NULL) {
3214 3205                          zcmd_free_nvlists(&zc);
3215 3206                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3216 3207                              "destination '%s' does not exist"), zc.zc_name);
3217 3208                          return (zfs_error(hdl, EZFS_NOENT, errbuf));
3218 3209                  }
3219 3210  
3220 3211                  /*
3221 3212                   * Trim off the final dataset component so we perform the
3222 3213                   * recvbackup ioctl to the filesystems's parent.
3223 3214                   */
3224 3215                  *cp = '\0';
3225 3216  
3226 3217                  if (flags->isprefix && !flags->istail && !flags->dryrun &&
3227 3218                      create_parents(hdl, zc.zc_value, strlen(tosnap)) != 0) {
3228 3219                          zcmd_free_nvlists(&zc);
3229 3220                          return (zfs_error(hdl, EZFS_BADRESTORE, errbuf));
3230 3221                  }
3231 3222  
3232 3223                  newfs = B_TRUE;
3233 3224          }
3234 3225  
3235 3226          zc.zc_begin_record = *drr_noswap;
3236 3227          zc.zc_cookie = infd;
3237 3228          zc.zc_guid = flags->force;
3238 3229          zc.zc_resumable = flags->resumable;
3239 3230          if (flags->verbose) {
3240 3231                  (void) printf("%s %s stream of %s into %s\n",
3241 3232                      flags->dryrun ? "would receive" : "receiving",
3242 3233                      drrb->drr_fromguid ? "incremental" : "full",
3243 3234                      drrb->drr_toname, zc.zc_value);
3244 3235                  (void) fflush(stdout);
3245 3236          }
3246 3237  
3247 3238          if (flags->dryrun) {
3248 3239                  zcmd_free_nvlists(&zc);
3249 3240                  return (recv_skip(hdl, infd, flags->byteswap));
3250 3241          }
3251 3242  
3252 3243          zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf;
3253 3244          zc.zc_nvlist_dst_size = sizeof (prop_errbuf);
3254 3245          zc.zc_cleanup_fd = cleanup_fd;
3255 3246          zc.zc_action_handle = *action_handlep;
3256 3247  
3257 3248          err = ioctl_err = zfs_ioctl(hdl, ZFS_IOC_RECV, &zc);
3258 3249          ioctl_errno = errno;
3259 3250          prop_errflags = (zprop_errflags_t)zc.zc_obj;
3260 3251  
3261 3252          if (err == 0) {
3262 3253                  nvlist_t *prop_errors;
3263 3254                  VERIFY(0 == nvlist_unpack((void *)(uintptr_t)zc.zc_nvlist_dst,
3264 3255                      zc.zc_nvlist_dst_size, &prop_errors, 0));
3265 3256  
3266 3257                  nvpair_t *prop_err = NULL;
3267 3258  
3268 3259                  while ((prop_err = nvlist_next_nvpair(prop_errors,
3269 3260                      prop_err)) != NULL) {
  
    | 
      ↓ open down ↓ | 
    309 lines elided | 
    
      ↑ open up ↑ | 
  
3270 3261                          char tbuf[1024];
3271 3262                          zfs_prop_t prop;
3272 3263                          int intval;
3273 3264  
3274 3265                          prop = zfs_name_to_prop(nvpair_name(prop_err));
3275 3266                          (void) nvpair_value_int32(prop_err, &intval);
3276 3267                          if (strcmp(nvpair_name(prop_err),
3277 3268                              ZPROP_N_MORE_ERRORS) == 0) {
3278 3269                                  trunc_prop_errs(intval);
3279 3270                                  break;
3280      -                        } else {
     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 +                                 */
3281 3286                                  (void) snprintf(tbuf, sizeof (tbuf),
3282 3287                                      dgettext(TEXT_DOMAIN,
3283 3288                                      "cannot receive %s property on %s"),
3284 3289                                      nvpair_name(prop_err), zc.zc_name);
3285 3290                                  zfs_setprop_error(hdl, prop, intval, tbuf);
3286 3291                          }
3287 3292                  }
3288 3293                  nvlist_free(prop_errors);
3289 3294          }
3290 3295  
3291 3296          zc.zc_nvlist_dst = 0;
3292 3297          zc.zc_nvlist_dst_size = 0;
3293 3298          zcmd_free_nvlists(&zc);
3294 3299  
3295 3300          if (err == 0 && snapprops_nvlist) {
3296 3301                  zfs_cmd_t zc2 = { 0 };
3297 3302  
3298 3303                  (void) strcpy(zc2.zc_name, zc.zc_value);
3299 3304                  zc2.zc_cookie = B_TRUE; /* received */
3300 3305                  if (zcmd_write_src_nvlist(hdl, &zc2, snapprops_nvlist) == 0) {
3301 3306                          (void) zfs_ioctl(hdl, ZFS_IOC_SET_PROP, &zc2);
3302 3307                          zcmd_free_nvlists(&zc2);
3303 3308                  }
3304 3309          }
3305 3310  
3306 3311          if (err && (ioctl_errno == ENOENT || ioctl_errno == EEXIST)) {
3307 3312                  /*
3308 3313                   * It may be that this snapshot already exists,
3309 3314                   * in which case we want to consume & ignore it
3310 3315                   * rather than failing.
3311 3316                   */
3312 3317                  avl_tree_t *local_avl;
3313 3318                  nvlist_t *local_nv, *fs;
3314 3319                  cp = strchr(zc.zc_value, '@');
3315 3320  
3316 3321                  /*
3317 3322                   * XXX Do this faster by just iterating over snaps in
3318 3323                   * this fs.  Also if zc_value does not exist, we will
3319 3324                   * get a strange "does not exist" error message.
3320 3325                   */
3321 3326                  *cp = '\0';
3322 3327                  if (gather_nvlist(hdl, zc.zc_value, NULL, NULL, B_FALSE,
3323 3328                      &local_nv, &local_avl) == 0) {
3324 3329                          *cp = '@';
3325 3330                          fs = fsavl_find(local_avl, drrb->drr_toguid, NULL);
3326 3331                          fsavl_destroy(local_avl);
3327 3332                          nvlist_free(local_nv);
3328 3333  
3329 3334                          if (fs != NULL) {
3330 3335                                  if (flags->verbose) {
3331 3336                                          (void) printf("snap %s already exists; "
3332 3337                                              "ignoring\n", zc.zc_value);
3333 3338                                  }
3334 3339                                  err = ioctl_err = recv_skip(hdl, infd,
3335 3340                                      flags->byteswap);
3336 3341                          }
3337 3342                  }
3338 3343                  *cp = '@';
3339 3344          }
3340 3345  
3341 3346          if (ioctl_err != 0) {
3342 3347                  switch (ioctl_errno) {
3343 3348                  case ENODEV:
3344 3349                          cp = strchr(zc.zc_value, '@');
3345 3350                          *cp = '\0';
3346 3351                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3347 3352                              "most recent snapshot of %s does not\n"
3348 3353                              "match incremental source"), zc.zc_value);
3349 3354                          (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
3350 3355                          *cp = '@';
3351 3356                          break;
3352 3357                  case ETXTBSY:
3353 3358                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3354 3359                              "destination %s has been modified\n"
3355 3360                              "since most recent snapshot"), zc.zc_name);
3356 3361                          (void) zfs_error(hdl, EZFS_BADRESTORE, errbuf);
3357 3362                          break;
3358 3363                  case EEXIST:
3359 3364                          cp = strchr(zc.zc_value, '@');
3360 3365                          if (newfs) {
3361 3366                                  /* it's the containing fs that exists */
3362 3367                                  *cp = '\0';
3363 3368                          }
3364 3369                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3365 3370                              "destination already exists"));
3366 3371                          (void) zfs_error_fmt(hdl, EZFS_EXISTS,
3367 3372                              dgettext(TEXT_DOMAIN, "cannot restore to %s"),
3368 3373                              zc.zc_value);
3369 3374                          *cp = '@';
3370 3375                          break;
3371 3376                  case EINVAL:
3372 3377                          (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3373 3378                          break;
3374 3379                  case ECKSUM:
3375 3380                          recv_ecksum_set_aux(hdl, zc.zc_value, flags->resumable);
3376 3381                          (void) zfs_error(hdl, EZFS_BADSTREAM, errbuf);
3377 3382                          break;
3378 3383                  case ENOTSUP:
3379 3384                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3380 3385                              "pool must be upgraded to receive this stream."));
3381 3386                          (void) zfs_error(hdl, EZFS_BADVERSION, errbuf);
3382 3387                          break;
3383 3388                  case EDQUOT:
3384 3389                          zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3385 3390                              "destination %s space quota exceeded"), zc.zc_name);
3386 3391                          (void) zfs_error(hdl, EZFS_NOSPC, errbuf);
3387 3392                          break;
3388 3393                  default:
3389 3394                          (void) zfs_standard_error(hdl, ioctl_errno, errbuf);
3390 3395                  }
3391 3396          }
3392 3397  
3393 3398          /*
3394 3399           * Mount the target filesystem (if created).  Also mount any
3395 3400           * children of the target filesystem if we did a replication
3396 3401           * receive (indicated by stream_avl being non-NULL).
3397 3402           */
3398 3403          cp = strchr(zc.zc_value, '@');
3399 3404          if (cp && (ioctl_err == 0 || !newfs)) {
3400 3405                  zfs_handle_t *h;
3401 3406  
3402 3407                  *cp = '\0';
3403 3408                  h = zfs_open(hdl, zc.zc_value,
3404 3409                      ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
3405 3410                  if (h != NULL) {
3406 3411                          if (h->zfs_type == ZFS_TYPE_VOLUME) {
3407 3412                                  *cp = '@';
3408 3413                          } else if (newfs || stream_avl) {
3409 3414                                  /*
3410 3415                                   * Track the first/top of hierarchy fs,
3411 3416                                   * for mounting and sharing later.
3412 3417                                   */
3413 3418                                  if (top_zfs && *top_zfs == NULL)
3414 3419                                          *top_zfs = zfs_strdup(hdl, zc.zc_value);
3415 3420                          }
3416 3421                          zfs_close(h);
3417 3422                  }
3418 3423                  *cp = '@';
3419 3424          }
3420 3425  
3421 3426          if (clp) {
3422 3427                  err |= changelist_postfix(clp);
3423 3428                  changelist_free(clp);
3424 3429          }
3425 3430  
3426 3431          if (prop_errflags & ZPROP_ERR_NOCLEAR) {
3427 3432                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
3428 3433                      "failed to clear unreceived properties on %s"),
3429 3434                      zc.zc_name);
3430 3435                  (void) fprintf(stderr, "\n");
3431 3436          }
3432 3437          if (prop_errflags & ZPROP_ERR_NORESTORE) {
3433 3438                  (void) fprintf(stderr, dgettext(TEXT_DOMAIN, "Warning: "
3434 3439                      "failed to restore original properties on %s"),
3435 3440                      zc.zc_name);
3436 3441                  (void) fprintf(stderr, "\n");
3437 3442          }
3438 3443  
3439 3444          if (err || ioctl_err)
3440 3445                  return (-1);
3441 3446  
3442 3447          *action_handlep = zc.zc_action_handle;
3443 3448  
3444 3449          if (flags->verbose) {
3445 3450                  char buf1[64];
3446 3451                  char buf2[64];
3447 3452                  uint64_t bytes = zc.zc_cookie;
3448 3453                  time_t delta = time(NULL) - begin_time;
3449 3454                  if (delta == 0)
3450 3455                          delta = 1;
3451 3456                  zfs_nicenum(bytes, buf1, sizeof (buf1));
3452 3457                  zfs_nicenum(bytes/delta, buf2, sizeof (buf1));
3453 3458  
3454 3459                  (void) printf("received %sB stream in %lu seconds (%sB/sec)\n",
3455 3460                      buf1, delta, buf2);
3456 3461          }
3457 3462  
3458 3463          return (0);
3459 3464  }
3460 3465  
3461 3466  static int
3462 3467  zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
3463 3468      const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
3464 3469      nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
3465 3470      uint64_t *action_handlep, const char *finalsnap)
3466 3471  {
3467 3472          int err;
3468 3473          dmu_replay_record_t drr, drr_noswap;
3469 3474          struct drr_begin *drrb = &drr.drr_u.drr_begin;
3470 3475          char errbuf[1024];
3471 3476          zio_cksum_t zcksum = { 0 };
3472 3477          uint64_t featureflags;
3473 3478          int hdrtype;
3474 3479  
3475 3480          (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
3476 3481              "cannot receive"));
3477 3482  
3478 3483          if (flags->isprefix &&
3479 3484              !zfs_dataset_exists(hdl, tosnap, ZFS_TYPE_DATASET)) {
3480 3485                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified fs "
3481 3486                      "(%s) does not exist"), tosnap);
3482 3487                  return (zfs_error(hdl, EZFS_NOENT, errbuf));
3483 3488          }
3484 3489          if (originsnap &&
3485 3490              !zfs_dataset_exists(hdl, originsnap, ZFS_TYPE_DATASET)) {
3486 3491                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "specified origin fs "
3487 3492                      "(%s) does not exist"), originsnap);
3488 3493                  return (zfs_error(hdl, EZFS_NOENT, errbuf));
3489 3494          }
3490 3495  
3491 3496          /* read in the BEGIN record */
3492 3497          if (0 != (err = recv_read(hdl, infd, &drr, sizeof (drr), B_FALSE,
3493 3498              &zcksum)))
3494 3499                  return (err);
3495 3500  
3496 3501          if (drr.drr_type == DRR_END || drr.drr_type == BSWAP_32(DRR_END)) {
3497 3502                  /* It's the double end record at the end of a package */
3498 3503                  return (ENODATA);
3499 3504          }
3500 3505  
3501 3506          /* the kernel needs the non-byteswapped begin record */
3502 3507          drr_noswap = drr;
3503 3508  
3504 3509          flags->byteswap = B_FALSE;
3505 3510          if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC)) {
3506 3511                  /*
3507 3512                   * We computed the checksum in the wrong byteorder in
3508 3513                   * recv_read() above; do it again correctly.
3509 3514                   */
3510 3515                  bzero(&zcksum, sizeof (zio_cksum_t));
3511 3516                  fletcher_4_incremental_byteswap(&drr, sizeof (drr), &zcksum);
3512 3517                  flags->byteswap = B_TRUE;
3513 3518  
3514 3519                  drr.drr_type = BSWAP_32(drr.drr_type);
3515 3520                  drr.drr_payloadlen = BSWAP_32(drr.drr_payloadlen);
3516 3521                  drrb->drr_magic = BSWAP_64(drrb->drr_magic);
3517 3522                  drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
3518 3523                  drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
3519 3524                  drrb->drr_type = BSWAP_32(drrb->drr_type);
3520 3525                  drrb->drr_flags = BSWAP_32(drrb->drr_flags);
3521 3526                  drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
3522 3527                  drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
3523 3528          }
3524 3529  
3525 3530          if (drrb->drr_magic != DMU_BACKUP_MAGIC || drr.drr_type != DRR_BEGIN) {
3526 3531                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
3527 3532                      "stream (bad magic number)"));
3528 3533                  return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
3529 3534          }
3530 3535  
3531 3536          featureflags = DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo);
3532 3537          hdrtype = DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo);
3533 3538  
3534 3539          if (!DMU_STREAM_SUPPORTED(featureflags) ||
3535 3540              (hdrtype != DMU_SUBSTREAM && hdrtype != DMU_COMPOUNDSTREAM)) {
3536 3541                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
3537 3542                      "stream has unsupported feature, feature flags = %lx"),
3538 3543                      featureflags);
3539 3544                  return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
3540 3545          }
3541 3546  
3542 3547          if (strchr(drrb->drr_toname, '@') == NULL) {
3543 3548                  zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "invalid "
3544 3549                      "stream (bad snapshot name)"));
3545 3550                  return (zfs_error(hdl, EZFS_BADSTREAM, errbuf));
3546 3551          }
3547 3552  
3548 3553          if (DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) == DMU_SUBSTREAM) {
3549 3554                  char nonpackage_sendfs[ZFS_MAXNAMELEN];
3550 3555                  if (sendfs == NULL) {
3551 3556                          /*
3552 3557                           * We were not called from zfs_receive_package(). Get
3553 3558                           * the fs specified by 'zfs send'.
3554 3559                           */
3555 3560                          char *cp;
3556 3561                          (void) strlcpy(nonpackage_sendfs,
3557 3562                              drr.drr_u.drr_begin.drr_toname, ZFS_MAXNAMELEN);
3558 3563                          if ((cp = strchr(nonpackage_sendfs, '@')) != NULL)
3559 3564                                  *cp = '\0';
3560 3565                          sendfs = nonpackage_sendfs;
3561 3566                          VERIFY(finalsnap == NULL);
3562 3567                  }
3563 3568                  flags->recursive =
3564 3569                      (nvlist_lookup_boolean(stream_nv, "not_recursive") ==
3565 3570                      ENOENT);
3566 3571                  err = zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
3567 3572                      &drr, &drr_noswap, sendfs, stream_avl, top_zfs,
3568 3573                      cleanup_fd, action_handlep, finalsnap);
3569 3574                  /* Clear out internal-only flags. */
3570 3575                  flags->recursive = B_FALSE;
3571 3576                  return (err);
3572 3577          } else {
3573 3578                  assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
3574 3579                      DMU_COMPOUNDSTREAM);
3575 3580                  return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
3576 3581                      &zcksum, top_zfs, cleanup_fd, action_handlep));
3577 3582          }
3578 3583  }
3579 3584  
3580 3585  /*
3581 3586   * Restores a backup of tosnap from the file descriptor specified by infd.
3582 3587   * Return 0 on total success, -2 if some things couldn't be
3583 3588   * destroyed/renamed/promoted, -1 if some things couldn't be received.
3584 3589   * (-1 will override -2, if -1 and the resumable flag was specified the
3585 3590   * transfer can be resumed if the sending side supports it).
3586 3591   */
3587 3592  int
3588 3593  zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
3589 3594      recvflags_t *flags, int infd, avl_tree_t *stream_avl)
3590 3595  {
3591 3596          char *top_zfs = NULL;
3592 3597          int err;
3593 3598          int cleanup_fd;
3594 3599          uint64_t action_handle = 0;
3595 3600          char *originsnap = NULL;
3596 3601          if (props) {
3597 3602                  err = nvlist_lookup_string(props, "origin", &originsnap);
3598 3603                  if (err && err != ENOENT)
3599 3604                          return (err);
3600 3605          }
3601 3606  
3602 3607          cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
3603 3608          VERIFY(cleanup_fd >= 0);
3604 3609  
3605 3610          err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
3606 3611              stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL);
3607 3612  
3608 3613          VERIFY(0 == close(cleanup_fd));
3609 3614  
3610 3615          if (err == 0 && !flags->nomount && top_zfs) {
3611 3616                  zfs_handle_t *zhp;
3612 3617                  prop_changelist_t *clp;
3613 3618  
3614 3619                  zhp = zfs_open(hdl, top_zfs, ZFS_TYPE_FILESYSTEM);
3615 3620                  if (zhp != NULL) {
3616 3621                          clp = changelist_gather(zhp, ZFS_PROP_MOUNTPOINT,
3617 3622                              CL_GATHER_MOUNT_ALWAYS, 0);
3618 3623                          zfs_close(zhp);
3619 3624                          if (clp != NULL) {
3620 3625                                  /* mount and share received datasets */
3621 3626                                  err = changelist_postfix(clp);
3622 3627                                  changelist_free(clp);
3623 3628                          }
3624 3629                  }
3625 3630                  if (zhp == NULL || clp == NULL || err)
3626 3631                          err = -1;
3627 3632          }
3628 3633          if (top_zfs)
3629 3634                  free(top_zfs);
3630 3635  
3631 3636          return (err);
3632 3637  }
  
    | 
      ↓ open down ↓ | 
    342 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX