Deleted Added
full compact
27a28
> * Copyright (c) 2013 Steven Hartland. All rights reserved.
804a806
> nvlist_t *snapholds;
955,956c957,958
< static int
< hold_for_send(zfs_handle_t *zhp, send_dump_data_t *sdd)
---
> static void
> gather_holds(zfs_handle_t *zhp, send_dump_data_t *sdd)
958,961d959
< zfs_handle_t *pzhp;
< int error = 0;
< char *thissnap;
<
964,966d961
< if (sdd->dryrun)
< return (0);
<
968c963
< * zfs_send() only opens a cleanup_fd for sends that need it,
---
> * zfs_send() only sets snapholds for sends that need them,
971,972c966,967
< if (sdd->cleanup_fd == -1)
< return (0);
---
> if (sdd->snapholds == NULL)
> return;
974,989c969
< thissnap = strchr(zhp->zfs_name, '@') + 1;
< *(thissnap - 1) = '\0';
< pzhp = zfs_open(zhp->zfs_hdl, zhp->zfs_name, ZFS_TYPE_DATASET);
< *(thissnap - 1) = '@';
<
< /*
< * It's OK if the parent no longer exists. The send code will
< * handle that error.
< */
< if (pzhp) {
< error = zfs_hold(pzhp, thissnap, sdd->holdtag,
< B_FALSE, B_TRUE, sdd->cleanup_fd);
< zfs_close(pzhp);
< }
<
< return (error);
---
> fnvlist_add_string(sdd->snapholds, zhp->zfs_name, sdd->holdtag);
1045d1024
<
1050a1030
> err = 0;
1056,1064c1036,1039
< err = hold_for_send(zhp, sdd);
< if (err == 0) {
< sdd->seenfrom = B_TRUE;
< (void) strcpy(sdd->prevsnap, thissnap);
< sdd->prevsnap_obj = zfs_prop_get_int(zhp,
< ZFS_PROP_OBJSETID);
< } else if (err == ENOENT) {
< err = 0;
< }
---
> gather_holds(zhp, sdd);
> sdd->seenfrom = B_TRUE;
> (void) strcpy(sdd->prevsnap, thissnap);
> sdd->prevsnap_obj = zfs_prop_get_int(zhp, ZFS_PROP_OBJSETID);
1066c1041
< return (err);
---
> return (0);
1117,1124c1092
< err = hold_for_send(zhp, sdd);
< if (err) {
< if (err == ENOENT)
< err = 0;
< zfs_close(zhp);
< return (err);
< }
<
---
> gather_holds(zhp, sdd);
1392c1360
< pthread_t tid;
---
> pthread_t tid = 0;
1465,1467c1433
< if (err) {
< fsavl_destroy(fsavl);
< nvlist_free(fss);
---
> if (err)
1469d1434
< }
1493,1494d1457
< fsavl_destroy(fsavl);
< nvlist_free(fss);
1505,1506d1467
< fsavl_destroy(fsavl);
< nvlist_free(fss);
1518c1479
< if (flags->dedup)
---
> if (tid != 0)
1554a1516
> sdd.snapholds = fnvlist_alloc();
1556a1519
> sdd.snapholds = NULL;
1558c1521
< if (flags->verbose) {
---
> if (flags->verbose || sdd.snapholds != NULL) {
1561,1562c1524,1525
< * before generating any data. Then do a non-verbose real
< * run to generate the streams.
---
> * or to gather snapshot hold's before generating any data,
> * then do a non-verbose real run to generate the streams.
1566,1575c1529,1542
< sdd.dryrun = flags->dryrun;
< sdd.verbose = B_FALSE;
< if (flags->parsable) {
< (void) fprintf(stderr, "size\t%llu\n",
< (longlong_t)sdd.size);
< } else {
< char buf[16];
< zfs_nicenum(sdd.size, buf, sizeof (buf));
< (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
< "total estimated size is %s\n"), buf);
---
>
> if (err != 0)
> goto stderr_out;
>
> if (flags->verbose) {
> if (flags->parsable) {
> (void) fprintf(stderr, "size\t%llu\n",
> (longlong_t)sdd.size);
> } else {
> char buf[16];
> zfs_nicenum(sdd.size, buf, sizeof (buf));
> (void) fprintf(stderr, dgettext(TEXT_DOMAIN,
> "total estimated size is %s\n"), buf);
> }
1576a1544,1565
>
> /* Ensure no snaps found is treated as an error. */
> if (!sdd.seento) {
> err = ENOENT;
> goto err_out;
> }
>
> /* Skip the second run if dryrun was requested. */
> if (flags->dryrun)
> goto err_out;
>
> if (sdd.snapholds != NULL) {
> err = zfs_hold_nvl(zhp, sdd.cleanup_fd, sdd.snapholds);
> if (err != 0)
> goto stderr_out;
>
> fnvlist_free(sdd.snapholds);
> sdd.snapholds = NULL;
> }
>
> sdd.dryrun = B_FALSE;
> sdd.verbose = B_FALSE;
1577a1567
>
1582,1583c1572,1578
< if (flags->dedup) {
< (void) close(pipefd[0]);
---
> /* Ensure no snaps found is treated as an error. */
> if (err == 0 && !sdd.seento)
> err = ENOENT;
>
> if (tid != 0) {
> if (err != 0)
> (void) pthread_cancel(tid);
1584a1580
> (void) close(pipefd[0]);
1611a1608,1611
> fsavl_destroy(fsavl);
> nvlist_free(fss);
> fnvlist_free(sdd.snapholds);
>
1614c1614
< if (flags->dedup) {
---
> if (tid != 0) {