772 if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
773 nvlist_free(sd.fss);
774 *nvlp = NULL;
775 return (EZFS_NOMEM);
776 }
777
778 *nvlp = sd.fss;
779 return (0);
780 }
781
782 /*
783 * Routines specific to "zfs send"
784 */
785 typedef struct send_dump_data {
786 /* these are all just the short snapname (the part after the @) */
787 const char *fromsnap;
788 const char *tosnap;
789 char prevsnap[ZFS_MAXNAMELEN];
790 uint64_t prevsnap_obj;
791 boolean_t seenfrom, seento, replicate, doall, fromorigin;
792 boolean_t verbose, dryrun, parsable, progress;
793 int outfd;
794 boolean_t err;
795 nvlist_t *fss;
796 avl_tree_t *fsavl;
797 snapfilter_cb_t *filter_cb;
798 void *filter_cb_arg;
799 nvlist_t *debugnv;
800 char holdtag[ZFS_MAXNAMELEN];
801 int cleanup_fd;
802 uint64_t size;
803 } send_dump_data_t;
804
805 static int
806 estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
807 boolean_t fromorigin, uint64_t *sizep)
808 {
809 zfs_cmd_t zc = { 0 };
810 libzfs_handle_t *hdl = zhp->zfs_hdl;
811
812 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
851 case EROFS:
852 zfs_error_aux(hdl, strerror(errno));
853 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
854
855 default:
856 return (zfs_standard_error(hdl, errno, errbuf));
857 }
858 }
859
860 *sizep = zc.zc_objset_type;
861
862 return (0);
863 }
864
865 /*
866 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
867 * NULL) to the file descriptor specified by outfd.
868 */
869 static int
870 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
871 boolean_t fromorigin, int outfd, nvlist_t *debugnv)
872 {
873 zfs_cmd_t zc = { 0 };
874 libzfs_handle_t *hdl = zhp->zfs_hdl;
875 nvlist_t *thisdbg;
876
877 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
878 assert(fromsnap_obj == 0 || !fromorigin);
879
880 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
881 zc.zc_cookie = outfd;
882 zc.zc_obj = fromorigin;
883 zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
884 zc.zc_fromobj = fromsnap_obj;
885
886 VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
887 if (fromsnap && fromsnap[0] != '\0') {
888 VERIFY(0 == nvlist_add_string(thisdbg,
889 "fromsnap", fromsnap));
890 }
891
892 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
893 char errbuf[1024];
894 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
895 "warning: cannot send '%s'"), zhp->zfs_name);
896
897 VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
898 if (debugnv) {
899 VERIFY(0 == nvlist_add_nvlist(debugnv,
900 zhp->zfs_name, thisdbg));
901 }
902 nvlist_free(thisdbg);
903
904 switch (errno) {
1152 }
1153
1154 if (!sdd->dryrun) {
1155 /*
1156 * If progress reporting is requested, spawn a new thread to
1157 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1158 */
1159 if (sdd->progress) {
1160 pa.pa_zhp = zhp;
1161 pa.pa_fd = sdd->outfd;
1162 pa.pa_parsable = sdd->parsable;
1163
1164 if (err = pthread_create(&tid, NULL,
1165 send_progress_thread, &pa)) {
1166 zfs_close(zhp);
1167 return (err);
1168 }
1169 }
1170
1171 err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
1172 fromorigin, sdd->outfd, sdd->debugnv);
1173
1174 if (sdd->progress) {
1175 (void) pthread_cancel(tid);
1176 (void) pthread_join(tid, NULL);
1177 }
1178 }
1179
1180 (void) strcpy(sdd->prevsnap, thissnap);
1181 sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1182 zfs_close(zhp);
1183 return (err);
1184 }
1185
1186 static int
1187 dump_filesystem(zfs_handle_t *zhp, void *arg)
1188 {
1189 int rv = 0;
1190 send_dump_data_t *sdd = arg;
1191 boolean_t missingfrom = B_FALSE;
1192 zfs_cmd_t zc = { 0 };
1444 }
1445
1446 err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
1447 fromsnap, tosnap, flags->replicate, &fss, &fsavl);
1448 if (err)
1449 goto err_out;
1450 VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
1451 err = nvlist_pack(hdrnv, &packbuf, &buflen,
1452 NV_ENCODE_XDR, 0);
1453 if (debugnvp)
1454 *debugnvp = hdrnv;
1455 else
1456 nvlist_free(hdrnv);
1457 if (err) {
1458 fsavl_destroy(fsavl);
1459 nvlist_free(fss);
1460 goto stderr_out;
1461 }
1462 }
1463
1464 if (!flags->dryrun) {
1465 /* write first begin record */
1466 drr.drr_type = DRR_BEGIN;
1467 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
1468 DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
1469 drr_versioninfo, DMU_COMPOUNDSTREAM);
1470 DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
1471 drr_versioninfo, featureflags);
1472 (void) snprintf(drr.drr_u.drr_begin.drr_toname,
1473 sizeof (drr.drr_u.drr_begin.drr_toname),
1474 "%s@%s", zhp->zfs_name, tosnap);
1475 drr.drr_payloadlen = buflen;
1476 err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
1477
1478 /* write header nvlist */
1479 if (err != -1 && packbuf != NULL) {
1480 err = cksum_and_write(packbuf, buflen, &zc,
1481 outfd);
1482 }
1483 free(packbuf);
1484 if (err == -1) {
1503 err = 0;
1504 }
1505 }
1506
1507 /* dump each stream */
1508 sdd.fromsnap = fromsnap;
1509 sdd.tosnap = tosnap;
1510 if (flags->dedup)
1511 sdd.outfd = pipefd[0];
1512 else
1513 sdd.outfd = outfd;
1514 sdd.replicate = flags->replicate;
1515 sdd.doall = flags->doall;
1516 sdd.fromorigin = flags->fromorigin;
1517 sdd.fss = fss;
1518 sdd.fsavl = fsavl;
1519 sdd.verbose = flags->verbose;
1520 sdd.parsable = flags->parsable;
1521 sdd.progress = flags->progress;
1522 sdd.dryrun = flags->dryrun;
1523 sdd.filter_cb = filter_func;
1524 sdd.filter_cb_arg = cb_arg;
1525 if (debugnvp)
1526 sdd.debugnv = *debugnvp;
1527
1528 /*
1529 * Some flags require that we place user holds on the datasets that are
1530 * being sent so they don't get destroyed during the send. We can skip
1531 * this step if the pool is imported read-only since the datasets cannot
1532 * be destroyed.
1533 */
1534 if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
1535 ZPOOL_PROP_READONLY, NULL) &&
1536 zfs_spa_version(zhp, &spa_version) == 0 &&
1537 spa_version >= SPA_VERSION_USERREFS &&
1538 (flags->doall || flags->replicate)) {
1539 ++holdseq;
1540 (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
1541 ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
1542 sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
1564 char buf[16];
1565 zfs_nicenum(sdd.size, buf, sizeof (buf));
1566 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1567 "total estimated size is %s\n"), buf);
1568 }
1569 }
1570 err = dump_filesystems(zhp, &sdd);
1571 fsavl_destroy(fsavl);
1572 nvlist_free(fss);
1573
1574 if (flags->dedup) {
1575 (void) close(pipefd[0]);
1576 (void) pthread_join(tid, NULL);
1577 }
1578
1579 if (sdd.cleanup_fd != -1) {
1580 VERIFY(0 == close(sdd.cleanup_fd));
1581 sdd.cleanup_fd = -1;
1582 }
1583
1584 if (!flags->dryrun && (flags->replicate || flags->doall ||
1585 flags->props)) {
1586 /*
1587 * write final end record. NB: want to do this even if
1588 * there was some error, because it might not be totally
1589 * failed.
1590 */
1591 dmu_replay_record_t drr = { 0 };
1592 drr.drr_type = DRR_END;
1593 if (write(outfd, &drr, sizeof (drr)) == -1) {
1594 return (zfs_standard_error(zhp->zfs_hdl,
1595 errno, errbuf));
1596 }
1597 }
1598
1599 return (err || sdd.err);
1600
1601 stderr_out:
1602 err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
1603 err_out:
1604 if (sdd.cleanup_fd != -1)
1605 VERIFY(0 == close(sdd.cleanup_fd));
|
772 if (avlp != NULL && (*avlp = fsavl_create(sd.fss)) == NULL) {
773 nvlist_free(sd.fss);
774 *nvlp = NULL;
775 return (EZFS_NOMEM);
776 }
777
778 *nvlp = sd.fss;
779 return (0);
780 }
781
782 /*
783 * Routines specific to "zfs send"
784 */
785 typedef struct send_dump_data {
786 /* these are all just the short snapname (the part after the @) */
787 const char *fromsnap;
788 const char *tosnap;
789 char prevsnap[ZFS_MAXNAMELEN];
790 uint64_t prevsnap_obj;
791 boolean_t seenfrom, seento, replicate, doall, fromorigin;
792 boolean_t verbose, dryrun, parsable, progress, far;
793 int outfd;
794 boolean_t err;
795 nvlist_t *fss;
796 avl_tree_t *fsavl;
797 snapfilter_cb_t *filter_cb;
798 void *filter_cb_arg;
799 nvlist_t *debugnv;
800 char holdtag[ZFS_MAXNAMELEN];
801 int cleanup_fd;
802 uint64_t size;
803 } send_dump_data_t;
804
805 static int
806 estimate_ioctl(zfs_handle_t *zhp, uint64_t fromsnap_obj,
807 boolean_t fromorigin, uint64_t *sizep)
808 {
809 zfs_cmd_t zc = { 0 };
810 libzfs_handle_t *hdl = zhp->zfs_hdl;
811
812 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
851 case EROFS:
852 zfs_error_aux(hdl, strerror(errno));
853 return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
854
855 default:
856 return (zfs_standard_error(hdl, errno, errbuf));
857 }
858 }
859
860 *sizep = zc.zc_objset_type;
861
862 return (0);
863 }
864
865 /*
866 * Dumps a backup of the given snapshot (incremental from fromsnap if it's not
867 * NULL) to the file descriptor specified by outfd.
868 */
869 static int
870 dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
871 boolean_t fromorigin, int outfd, int far, nvlist_t *debugnv)
872 {
873 zfs_cmd_t zc = { 0 };
874 libzfs_handle_t *hdl = zhp->zfs_hdl;
875 nvlist_t *thisdbg;
876
877 assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
878 assert(fromsnap_obj == 0 || !fromorigin);
879
880 (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));
881 zc.zc_cookie = outfd;
882 zc.zc_obj = fromorigin;
883 zc.zc_sendobj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
884 zc.zc_fromobj = fromsnap_obj;
885 zc.zc_guid = far ? 2 : 0;
886
887 VERIFY(0 == nvlist_alloc(&thisdbg, NV_UNIQUE_NAME, 0));
888 if (fromsnap && fromsnap[0] != '\0') {
889 VERIFY(0 == nvlist_add_string(thisdbg,
890 "fromsnap", fromsnap));
891 }
892
893 if (zfs_ioctl(zhp->zfs_hdl, ZFS_IOC_SEND, &zc) != 0) {
894 char errbuf[1024];
895 (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN,
896 "warning: cannot send '%s'"), zhp->zfs_name);
897
898 VERIFY(0 == nvlist_add_uint64(thisdbg, "error", errno));
899 if (debugnv) {
900 VERIFY(0 == nvlist_add_nvlist(debugnv,
901 zhp->zfs_name, thisdbg));
902 }
903 nvlist_free(thisdbg);
904
905 switch (errno) {
1153 }
1154
1155 if (!sdd->dryrun) {
1156 /*
1157 * If progress reporting is requested, spawn a new thread to
1158 * poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1159 */
1160 if (sdd->progress) {
1161 pa.pa_zhp = zhp;
1162 pa.pa_fd = sdd->outfd;
1163 pa.pa_parsable = sdd->parsable;
1164
1165 if (err = pthread_create(&tid, NULL,
1166 send_progress_thread, &pa)) {
1167 zfs_close(zhp);
1168 return (err);
1169 }
1170 }
1171
1172 err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
1173 fromorigin, sdd->outfd, sdd->far, sdd->debugnv);
1174
1175 if (sdd->progress) {
1176 (void) pthread_cancel(tid);
1177 (void) pthread_join(tid, NULL);
1178 }
1179 }
1180
1181 (void) strcpy(sdd->prevsnap, thissnap);
1182 sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1183 zfs_close(zhp);
1184 return (err);
1185 }
1186
1187 static int
1188 dump_filesystem(zfs_handle_t *zhp, void *arg)
1189 {
1190 int rv = 0;
1191 send_dump_data_t *sdd = arg;
1192 boolean_t missingfrom = B_FALSE;
1193 zfs_cmd_t zc = { 0 };
1445 }
1446
1447 err = gather_nvlist(zhp->zfs_hdl, zhp->zfs_name,
1448 fromsnap, tosnap, flags->replicate, &fss, &fsavl);
1449 if (err)
1450 goto err_out;
1451 VERIFY(0 == nvlist_add_nvlist(hdrnv, "fss", fss));
1452 err = nvlist_pack(hdrnv, &packbuf, &buflen,
1453 NV_ENCODE_XDR, 0);
1454 if (debugnvp)
1455 *debugnvp = hdrnv;
1456 else
1457 nvlist_free(hdrnv);
1458 if (err) {
1459 fsavl_destroy(fsavl);
1460 nvlist_free(fss);
1461 goto stderr_out;
1462 }
1463 }
1464
1465 if (!flags->dryrun && !flags->far) {
1466 /* write first begin record */
1467 drr.drr_type = DRR_BEGIN;
1468 drr.drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
1469 DMU_SET_STREAM_HDRTYPE(drr.drr_u.drr_begin.
1470 drr_versioninfo, DMU_COMPOUNDSTREAM);
1471 DMU_SET_FEATUREFLAGS(drr.drr_u.drr_begin.
1472 drr_versioninfo, featureflags);
1473 (void) snprintf(drr.drr_u.drr_begin.drr_toname,
1474 sizeof (drr.drr_u.drr_begin.drr_toname),
1475 "%s@%s", zhp->zfs_name, tosnap);
1476 drr.drr_payloadlen = buflen;
1477 err = cksum_and_write(&drr, sizeof (drr), &zc, outfd);
1478
1479 /* write header nvlist */
1480 if (err != -1 && packbuf != NULL) {
1481 err = cksum_and_write(packbuf, buflen, &zc,
1482 outfd);
1483 }
1484 free(packbuf);
1485 if (err == -1) {
1504 err = 0;
1505 }
1506 }
1507
1508 /* dump each stream */
1509 sdd.fromsnap = fromsnap;
1510 sdd.tosnap = tosnap;
1511 if (flags->dedup)
1512 sdd.outfd = pipefd[0];
1513 else
1514 sdd.outfd = outfd;
1515 sdd.replicate = flags->replicate;
1516 sdd.doall = flags->doall;
1517 sdd.fromorigin = flags->fromorigin;
1518 sdd.fss = fss;
1519 sdd.fsavl = fsavl;
1520 sdd.verbose = flags->verbose;
1521 sdd.parsable = flags->parsable;
1522 sdd.progress = flags->progress;
1523 sdd.dryrun = flags->dryrun;
1524 sdd.far = flags->far;
1525 sdd.filter_cb = filter_func;
1526 sdd.filter_cb_arg = cb_arg;
1527 if (debugnvp)
1528 sdd.debugnv = *debugnvp;
1529
1530 /*
1531 * Some flags require that we place user holds on the datasets that are
1532 * being sent so they don't get destroyed during the send. We can skip
1533 * this step if the pool is imported read-only since the datasets cannot
1534 * be destroyed.
1535 */
1536 if (!flags->dryrun && !zpool_get_prop_int(zfs_get_pool_handle(zhp),
1537 ZPOOL_PROP_READONLY, NULL) &&
1538 zfs_spa_version(zhp, &spa_version) == 0 &&
1539 spa_version >= SPA_VERSION_USERREFS &&
1540 (flags->doall || flags->replicate)) {
1541 ++holdseq;
1542 (void) snprintf(sdd.holdtag, sizeof (sdd.holdtag),
1543 ".send-%d-%llu", getpid(), (u_longlong_t)holdseq);
1544 sdd.cleanup_fd = open(ZFS_DEV, O_RDWR|O_EXCL);
1566 char buf[16];
1567 zfs_nicenum(sdd.size, buf, sizeof (buf));
1568 (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
1569 "total estimated size is %s\n"), buf);
1570 }
1571 }
1572 err = dump_filesystems(zhp, &sdd);
1573 fsavl_destroy(fsavl);
1574 nvlist_free(fss);
1575
1576 if (flags->dedup) {
1577 (void) close(pipefd[0]);
1578 (void) pthread_join(tid, NULL);
1579 }
1580
1581 if (sdd.cleanup_fd != -1) {
1582 VERIFY(0 == close(sdd.cleanup_fd));
1583 sdd.cleanup_fd = -1;
1584 }
1585
1586 if (!flags->dryrun && !flags->far &&
1587 (flags->replicate || flags->doall || flags->props)) {
1588 /*
1589 * write final end record. NB: want to do this even if
1590 * there was some error, because it might not be totally
1591 * failed.
1592 */
1593 dmu_replay_record_t drr = { 0 };
1594 drr.drr_type = DRR_END;
1595 if (write(outfd, &drr, sizeof (drr)) == -1) {
1596 return (zfs_standard_error(zhp->zfs_hdl,
1597 errno, errbuf));
1598 }
1599 }
1600
1601 return (err || sdd.err);
1602
1603 stderr_out:
1604 err = zfs_standard_error(zhp->zfs_hdl, err, errbuf);
1605 err_out:
1606 if (sdd.cleanup_fd != -1)
1607 VERIFY(0 == close(sdd.cleanup_fd));
|