Print this page
6536 zfs send: want a way to disable sending of free records
Reviewed by: Alexander Stetsenko <astetsenko@racktopsystems.com>
Reviewed by: Kim Shrier <kshrier@racktopsystems.com>


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 Steven Hartland. All rights reserved.

  25  */
  26 
  27 /*
  28  * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
  29  * It has the following characteristics:
  30  *
  31  *  - Thread Safe.  libzfs_core is accessible concurrently from multiple
  32  *  threads.  This is accomplished primarily by avoiding global data
  33  *  (e.g. caching).  Since it's thread-safe, there is no reason for a
  34  *  process to have multiple libzfs "instances".  Therefore, we store
  35  *  our few pieces of data (e.g. the file descriptor) in global
  36  *  variables.  The fd is reference-counted so that the libzfs_core
  37  *  library can be "initialized" multiple times (e.g. by different
  38  *  consumers within the same process).
  39  *
  40  *  - Committed Interface.  The libzfs_core interface will be committed,
  41  *  therefore consumers can compile against it and be confident that
  42  *  their code will continue to work on future releases of this code.
  43  *  Currently, the interface is Evolving (not Committed), but we intend
  44  *  to commit to it once it is more complete and we determine that it


 469     enum lzc_send_flags flags)
 470 {
 471         return (lzc_send_resume(snapname, from, fd, flags, 0, 0));
 472 }
 473 
 474 int
 475 lzc_send_resume(const char *snapname, const char *from, int fd,
 476     enum lzc_send_flags flags, uint64_t resumeobj, uint64_t resumeoff)
 477 {
 478         nvlist_t *args;
 479         int err;
 480 
 481         args = fnvlist_alloc();
 482         fnvlist_add_int32(args, "fd", fd);
 483         if (from != NULL)
 484                 fnvlist_add_string(args, "fromsnap", from);
 485         if (flags & LZC_SEND_FLAG_LARGE_BLOCK)
 486                 fnvlist_add_boolean(args, "largeblockok");
 487         if (flags & LZC_SEND_FLAG_EMBED_DATA)
 488                 fnvlist_add_boolean(args, "embedok");


 489         if (resumeobj != 0 || resumeoff != 0) {
 490                 fnvlist_add_uint64(args, "resume_object", resumeobj);
 491                 fnvlist_add_uint64(args, "resume_offset", resumeoff);
 492         }
 493         err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
 494         nvlist_free(args);
 495         return (err);
 496 }
 497 
 498 /*
 499  * "from" can be NULL, a snapshot, or a bookmark.
 500  *
 501  * If from is NULL, a full (non-incremental) stream will be estimated.  This
 502  * is calculated very efficiently.
 503  *
 504  * If from is a snapshot, lzc_send_space uses the deadlists attached to
 505  * each snapshot to efficiently estimate the stream size.
 506  *
 507  * If from is a bookmark, the indirect blocks in the destination snapshot
 508  * are traversed, looking for blocks with a birth time since the creation TXG of




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  25  * Copyright 2015 RackTop Systems.
  26  */
  27 
  28 /*
  29  * LibZFS_Core (lzc) is intended to replace most functionality in libzfs.
  30  * It has the following characteristics:
  31  *
  32  *  - Thread Safe.  libzfs_core is accessible concurrently from multiple
  33  *  threads.  This is accomplished primarily by avoiding global data
  34  *  (e.g. caching).  Since it's thread-safe, there is no reason for a
  35  *  process to have multiple libzfs "instances".  Therefore, we store
  36  *  our few pieces of data (e.g. the file descriptor) in global
  37  *  variables.  The fd is reference-counted so that the libzfs_core
  38  *  library can be "initialized" multiple times (e.g. by different
  39  *  consumers within the same process).
  40  *
  41  *  - Committed Interface.  The libzfs_core interface will be committed,
  42  *  therefore consumers can compile against it and be confident that
  43  *  their code will continue to work on future releases of this code.
  44  *  Currently, the interface is Evolving (not Committed), but we intend
  45  *  to commit to it once it is more complete and we determine that it


 470     enum lzc_send_flags flags)
 471 {
 472         return (lzc_send_resume(snapname, from, fd, flags, 0, 0));
 473 }
 474 
 475 int
 476 lzc_send_resume(const char *snapname, const char *from, int fd,
 477     enum lzc_send_flags flags, uint64_t resumeobj, uint64_t resumeoff)
 478 {
 479         nvlist_t *args;
 480         int err;
 481 
 482         args = fnvlist_alloc();
 483         fnvlist_add_int32(args, "fd", fd);
 484         if (from != NULL)
 485                 fnvlist_add_string(args, "fromsnap", from);
 486         if (flags & LZC_SEND_FLAG_LARGE_BLOCK)
 487                 fnvlist_add_boolean(args, "largeblockok");
 488         if (flags & LZC_SEND_FLAG_EMBED_DATA)
 489                 fnvlist_add_boolean(args, "embedok");
 490         if (flags & LZC_SEND_FLAG_SKIP_FREE)
 491                 fnvlist_add_boolean(args, "skipfree");
 492         if (resumeobj != 0 || resumeoff != 0) {
 493                 fnvlist_add_uint64(args, "resume_object", resumeobj);
 494                 fnvlist_add_uint64(args, "resume_offset", resumeoff);
 495         }
 496         err = lzc_ioctl(ZFS_IOC_SEND_NEW, snapname, args, NULL);
 497         nvlist_free(args);
 498         return (err);
 499 }
 500 
 501 /*
 502  * "from" can be NULL, a snapshot, or a bookmark.
 503  *
 504  * If from is NULL, a full (non-incremental) stream will be estimated.  This
 505  * is calculated very efficiently.
 506  *
 507  * If from is a snapshot, lzc_send_space uses the deadlists attached to
 508  * each snapshot to efficiently estimate the stream size.
 509  *
 510  * If from is a bookmark, the indirect blocks in the destination snapshot
 511  * are traversed, looking for blocks with a birth time since the creation TXG of