Print this page
Placeholder


   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  25  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  27  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.

  28  */
  29 
  30 #include <assert.h>
  31 #include <ctype.h>
  32 #include <errno.h>
  33 #include <libintl.h>
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <unistd.h>
  38 #include <stddef.h>
  39 #include <fcntl.h>
  40 #include <sys/mount.h>
  41 #include <pthread.h>
  42 #include <umem.h>
  43 #include <time.h>
  44 
  45 #include <libzfs.h>
  46 #include <libzfs_core.h>
  47 


 797                 *nvlp = NULL;
 798                 return (EZFS_NOMEM);
 799         }
 800 
 801         *nvlp = sd.fss;
 802         return (0);
 803 }
 804 
 805 /*
 806  * Routines specific to "zfs send"
 807  */
 808 typedef struct send_dump_data {
 809         /* these are all just the short snapname (the part after the @) */
 810         const char *fromsnap;
 811         const char *tosnap;
 812         char prevsnap[ZFS_MAXNAMELEN];
 813         uint64_t prevsnap_obj;
 814         boolean_t seenfrom, seento, replicate, doall, fromorigin;
 815         boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
 816         boolean_t large_block;

 817         int outfd;
 818         boolean_t err;
 819         nvlist_t *fss;
 820         nvlist_t *snapholds;
 821         avl_tree_t *fsavl;
 822         snapfilter_cb_t *filter_cb;
 823         void *filter_cb_arg;
 824         nvlist_t *debugnv;
 825         char holdtag[ZFS_MAXNAMELEN];
 826         int cleanup_fd;
 827         uint64_t size;
 828 } send_dump_data_t;
 829 
 830 static int
 831 estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
 832     boolean_t fromorigin, uint64_t *sizep)
 833 {
 834         zfs_cmd_t zc = { 0 };
 835         libzfs_handle_t *hdl = zhp->zfs_hdl;
 836 


1167                  * If progress reporting is requested, spawn a new thread to
1168                  * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1169                  */
1170                 if (sdd->progress) {
1171                         pa.pa_zhp = zhp;
1172                         pa.pa_fd = sdd->outfd;
1173                         pa.pa_parsable = sdd->parsable;
1174 
1175                         if (err = pthread_create(&tid, NULL,
1176                             send_progress_thread, &pa)) {
1177                                 zfs_close(zhp);
1178                                 return (err);
1179                         }
1180                 }
1181 
1182                 enum lzc_send_flags flags = 0;
1183                 if (sdd->large_block)
1184                         flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1185                 if (sdd->embed_data)
1186                         flags |= LZC_SEND_FLAG_EMBED_DATA;


1187 
1188                 err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
1189                     fromorigin, sdd->outfd, flags, sdd->debugnv);
1190 
1191                 if (sdd->progress) {
1192                         (void) pthread_cancel(tid);
1193                         (void) pthread_join(tid, NULL);
1194                 }
1195         }
1196 
1197         (void) strcpy(sdd->prevsnap, thissnap);
1198         sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1199         zfs_close(zhp);
1200         return (err);
1201 }
1202 
1203 static int
1204 dump_filesystem(zfs_handle_t *zhp, void *arg)
1205 {
1206         int rv = 0;


1733                 }
1734         }
1735 
1736         /* dump each stream */
1737         sdd.fromsnap = fromsnap;
1738         sdd.tosnap = tosnap;
1739         if (tid != 0)
1740                 sdd.outfd = pipefd[0];
1741         else
1742                 sdd.outfd = outfd;
1743         sdd.replicate = flags->replicate;
1744         sdd.doall = flags->doall;
1745         sdd.fromorigin = flags->fromorigin;
1746         sdd.fss = fss;
1747         sdd.fsavl = fsavl;
1748         sdd.verbose = flags->verbose;
1749         sdd.parsable = flags->parsable;
1750         sdd.progress = flags->progress;
1751         sdd.dryrun = flags->dryrun;
1752         sdd.large_block = flags->largeblock;

1753         sdd.embed_data = flags->embed_data;
1754         sdd.filter_cb = filter_func;
1755         sdd.filter_cb_arg = cb_arg;
1756         if (debugnvp)
1757                 sdd.debugnv = *debugnvp;
1758         if (sdd.verbose && sdd.dryrun)
1759                 sdd.std_out = B_TRUE;
1760         fout = sdd.std_out ? stdout : stderr;
1761 
1762         /*
1763          * Some flags require that we place user holds on the datasets that are
1764          * being sent so they don't get destroyed during the send. We can skip
1765          * this step if the pool is imported read-only since the datasets cannot
1766          * be destroyed.
1767          */
1768         if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
1769             ZPOOL_PROP_READONLY, NULL) &&
1770             zfs_spa_version(zhp, &spa_version) == 0 &&
1771             spa_version >= SPA_VERSION_USERREFS &&
1772             (flags->doall || flags->replicate)) {




   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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
  25  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  26  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  27  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
  28  * Copyright 2015 RackTop Systems.
  29  */
  30 
  31 #include <assert.h>
  32 #include <ctype.h>
  33 #include <errno.h>
  34 #include <libintl.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <strings.h>
  38 #include <unistd.h>
  39 #include <stddef.h>
  40 #include <fcntl.h>
  41 #include <sys/mount.h>
  42 #include <pthread.h>
  43 #include <umem.h>
  44 #include <time.h>
  45 
  46 #include <libzfs.h>
  47 #include <libzfs_core.h>
  48 


 798                 *nvlp = NULL;
 799                 return (EZFS_NOMEM);
 800         }
 801 
 802         *nvlp = sd.fss;
 803         return (0);
 804 }
 805 
 806 /*
 807  * Routines specific to "zfs send"
 808  */
 809 typedef struct send_dump_data {
 810         /* these are all just the short snapname (the part after the @) */
 811         const char *fromsnap;
 812         const char *tosnap;
 813         char prevsnap[ZFS_MAXNAMELEN];
 814         uint64_t prevsnap_obj;
 815         boolean_t seenfrom, seento, replicate, doall, fromorigin;
 816         boolean_t verbose, dryrun, parsable, progress, embed_data, std_out;
 817         boolean_t large_block;
 818         boolean_t skip_free;
 819         int outfd;
 820         boolean_t err;
 821         nvlist_t *fss;
 822         nvlist_t *snapholds;
 823         avl_tree_t *fsavl;
 824         snapfilter_cb_t *filter_cb;
 825         void *filter_cb_arg;
 826         nvlist_t *debugnv;
 827         char holdtag[ZFS_MAXNAMELEN];
 828         int cleanup_fd;
 829         uint64_t size;
 830 } send_dump_data_t;
 831 
 832 static int
 833 estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
 834     boolean_t fromorigin, uint64_t *sizep)
 835 {
 836         zfs_cmd_t zc = { 0 };
 837         libzfs_handle_t *hdl = zhp->zfs_hdl;
 838 


1169                  * If progress reporting is requested, spawn a new thread to
1170                  * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1171                  */
1172                 if (sdd->progress) {
1173                         pa.pa_zhp = zhp;
1174                         pa.pa_fd = sdd->outfd;
1175                         pa.pa_parsable = sdd->parsable;
1176 
1177                         if (err = pthread_create(&tid, NULL,
1178                             send_progress_thread, &pa)) {
1179                                 zfs_close(zhp);
1180                                 return (err);
1181                         }
1182                 }
1183 
1184                 enum lzc_send_flags flags = 0;
1185                 if (sdd->large_block)
1186                         flags |= LZC_SEND_FLAG_LARGE_BLOCK;
1187                 if (sdd->embed_data)
1188                         flags |= LZC_SEND_FLAG_EMBED_DATA;
1189                 if (sdd->skip_free)
1190                         flags |= LZC_SEND_FLAG_SKIP_FREE;
1191 
1192                 err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
1193                     fromorigin, sdd->outfd, flags, sdd->debugnv);
1194 
1195                 if (sdd->progress) {
1196                         (void) pthread_cancel(tid);
1197                         (void) pthread_join(tid, NULL);
1198                 }
1199         }
1200 
1201         (void) strcpy(sdd->prevsnap, thissnap);
1202         sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1203         zfs_close(zhp);
1204         return (err);
1205 }
1206 
1207 static int
1208 dump_filesystem(zfs_handle_t *zhp, void *arg)
1209 {
1210         int rv = 0;


1737                 }
1738         }
1739 
1740         /* dump each stream */
1741         sdd.fromsnap = fromsnap;
1742         sdd.tosnap = tosnap;
1743         if (tid != 0)
1744                 sdd.outfd = pipefd[0];
1745         else
1746                 sdd.outfd = outfd;
1747         sdd.replicate = flags->replicate;
1748         sdd.doall = flags->doall;
1749         sdd.fromorigin = flags->fromorigin;
1750         sdd.fss = fss;
1751         sdd.fsavl = fsavl;
1752         sdd.verbose = flags->verbose;
1753         sdd.parsable = flags->parsable;
1754         sdd.progress = flags->progress;
1755         sdd.dryrun = flags->dryrun;
1756         sdd.large_block = flags->largeblock;
1757         sdd.skip_free = flags->skip_free;
1758         sdd.embed_data = flags->embed_data;
1759         sdd.filter_cb = filter_func;
1760         sdd.filter_cb_arg = cb_arg;
1761         if (debugnvp)
1762                 sdd.debugnv = *debugnvp;
1763         if (sdd.verbose && sdd.dryrun)
1764                 sdd.std_out = B_TRUE;
1765         fout = sdd.std_out ? stdout : stderr;
1766 
1767         /*
1768          * Some flags require that we place user holds on the datasets that are
1769          * being sent so they don't get destroyed during the send. We can skip
1770          * this step if the pool is imported read-only since the datasets cannot
1771          * be destroyed.
1772          */
1773         if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
1774             ZPOOL_PROP_READONLY, NULL) &&
1775             zfs_spa_version(zhp, &spa_version) == 0 &&
1776             spa_version >= SPA_VERSION_USERREFS &&
1777             (flags->doall || flags->replicate)) {