summaryrefslogtreecommitdiff
path: root/usr/src/cmd
diff options
context:
space:
mode:
authorLori Alt <Lori.Alt@Sun.COM>2009-11-09 11:04:55 -0700
committerLori Alt <Lori.Alt@Sun.COM>2009-11-09 11:04:55 -0700
commit9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22 (patch)
treecbdb5ce75ee3c1332210914bbbd7c59a2ac3d4ba /usr/src/cmd
parentbb9b6b3f59b8820022416cea99b49c50fef6e391 (diff)
downloadillumos-joyent-9e69d7d0feb2a0394435ca1d9746c4c3d7bf9b22.tar.gz
PSARC/2009/557 ZFS send dedup
6812638 zfs send intra-stream dedup 6887817 want snapshot filtering for zfs send 6812603 zfs send can aggregate free records
Diffstat (limited to 'usr/src/cmd')
-rw-r--r--usr/src/cmd/zfs/zfs_main.c31
-rw-r--r--usr/src/cmd/zstreamdump/zstreamdump.c49
2 files changed, 59 insertions, 21 deletions
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c
index d9fec6aafe..3d037ee469 100644
--- a/usr/src/cmd/zfs/zfs_main.c
+++ b/usr/src/cmd/zfs/zfs_main.c
@@ -232,7 +232,7 @@ get_usage(zfs_help_t idx)
case HELP_ROLLBACK:
return (gettext("\trollback [-rRf] <snapshot>\n"));
case HELP_SEND:
- return (gettext("\tsend [-R] [-[iI] snapshot] <snapshot>\n"));
+ return (gettext("\tsend [-RD] [-[iI] snapshot] <snapshot>\n"));
case HELP_SET:
return (gettext("\tset <property=value> "
"<filesystem|volume|snapshot> ...\n"));
@@ -2488,8 +2488,8 @@ usage:
}
/*
- * zfs send [-v] -R [-i|-I <@snap>] <fs@snap>
- * zfs send [-v] [-i|-I <@snap>] <fs@snap>
+ * zfs send [-vD] -R [-i|-I <@snap>] <fs@snap>
+ * zfs send [-vD] [-i|-I <@snap>] <fs@snap>
*
* Send a backup stream to stdout.
*/
@@ -2500,14 +2500,11 @@ zfs_do_send(int argc, char **argv)
char *toname = NULL;
char *cp;
zfs_handle_t *zhp;
- boolean_t doall = B_FALSE;
- boolean_t replicate = B_FALSE;
- boolean_t fromorigin = B_FALSE;
- boolean_t verbose = B_FALSE;
+ sendflags_t flags = { 0 };
int c, err;
/* check options */
- while ((c = getopt(argc, argv, ":i:I:Rv")) != -1) {
+ while ((c = getopt(argc, argv, ":i:I:RDv")) != -1) {
switch (c) {
case 'i':
if (fromname)
@@ -2518,13 +2515,16 @@ zfs_do_send(int argc, char **argv)
if (fromname)
usage(B_FALSE);
fromname = optarg;
- doall = B_TRUE;
+ flags.doall = B_TRUE;
break;
case 'R':
- replicate = B_TRUE;
+ flags.replicate = B_TRUE;
break;
case 'v':
- verbose = B_TRUE;
+ flags.verbose = B_TRUE;
+ break;
+ case 'D':
+ flags.dedup = B_TRUE;
break;
case ':':
(void) fprintf(stderr, gettext("missing argument for "
@@ -2584,7 +2584,7 @@ zfs_do_send(int argc, char **argv)
if (strcmp(origin, fromname) == 0) {
fromname = NULL;
- fromorigin = B_TRUE;
+ flags.fromorigin = B_TRUE;
} else {
*cp = '\0';
if (cp != fromname && strcmp(argv[0], fromname)) {
@@ -2602,11 +2602,10 @@ zfs_do_send(int argc, char **argv)
}
}
- if (replicate && fromname == NULL)
- doall = B_TRUE;
+ if (flags.replicate && fromname == NULL)
+ flags.doall = B_TRUE;
- err = zfs_send(zhp, fromname, toname, replicate, doall, fromorigin,
- verbose, STDOUT_FILENO);
+ err = zfs_send(zhp, fromname, toname, flags, STDOUT_FILENO, NULL, 0);
zfs_close(zhp);
return (err != 0);
diff --git a/usr/src/cmd/zstreamdump/zstreamdump.c b/usr/src/cmd/zstreamdump/zstreamdump.c
index c862ac66a1..649d3e68bc 100644
--- a/usr/src/cmd/zstreamdump/zstreamdump.c
+++ b/usr/src/cmd/zstreamdump/zstreamdump.c
@@ -86,6 +86,7 @@ main(int argc, char *argv[])
struct drr_object *drro = &thedrr.drr_u.drr_object;
struct drr_freeobjects *drrfo = &thedrr.drr_u.drr_freeobjects;
struct drr_write *drrw = &thedrr.drr_u.drr_write;
+ struct drr_write_byref *drrwbr = &thedrr.drr_u.drr_write_byref;
struct drr_free *drrf = &thedrr.drr_u.drr_free;
char c;
boolean_t verbose = B_FALSE;
@@ -172,7 +173,8 @@ main(int argc, char *argv[])
case DRR_BEGIN:
if (do_byteswap) {
drrb->drr_magic = BSWAP_64(drrb->drr_magic);
- drrb->drr_version = BSWAP_64(drrb->drr_version);
+ drrb->drr_versioninfo =
+ BSWAP_64(drrb->drr_versioninfo);
drrb->drr_creation_time =
BSWAP_64(drrb->drr_creation_time);
drrb->drr_type = BSWAP_32(drrb->drr_type);
@@ -183,8 +185,10 @@ main(int argc, char *argv[])
}
(void) printf("BEGIN record\n");
- (void) printf("\tversion = %llx\n",
- (u_longlong_t)drrb->drr_version);
+ (void) printf("\thdrtype = %lld\n",
+ DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo));
+ (void) printf("\tfeatures = %llx\n",
+ DMU_GET_FEATUREFLAGS(drrb->drr_versioninfo));
(void) printf("\tmagic = %llx\n",
(u_longlong_t)drrb->drr_magic);
(void) printf("\tcreation_time = %llx\n",
@@ -199,8 +203,8 @@ main(int argc, char *argv[])
if (verbose)
(void) printf("\n");
- if (drrb->drr_version == 2 &&
- drr->drr_payloadlen != 0) {
+ if ((DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
+ DMU_COMPOUNDSTREAM) && drr->drr_payloadlen != 0) {
nvlist_t *nv;
int sz = drr->drr_payloadlen;
@@ -264,6 +268,7 @@ main(int argc, char *argv[])
drro->drr_blksz = BSWAP_32(drro->drr_blksz);
drro->drr_bonuslen =
BSWAP_32(drro->drr_bonuslen);
+ drro->drr_toguid = BSWAP_64(drro->drr_toguid);
}
if (verbose) {
(void) printf("OBJECT object = %llu type = %u "
@@ -286,6 +291,7 @@ main(int argc, char *argv[])
BSWAP_64(drrfo->drr_firstobj);
drrfo->drr_numobjs =
BSWAP_64(drrfo->drr_numobjs);
+ drrfo->drr_toguid = BSWAP_64(drrfo->drr_toguid);
}
if (verbose) {
(void) printf("FREEOBJECTS firstobj = %llu "
@@ -301,6 +307,7 @@ main(int argc, char *argv[])
drrw->drr_type = BSWAP_32(drrw->drr_type);
drrw->drr_offset = BSWAP_64(drrw->drr_offset);
drrw->drr_length = BSWAP_64(drrw->drr_length);
+ drrw->drr_toguid = BSWAP_64(drrw->drr_toguid);
}
if (verbose) {
(void) printf("WRITE object = %llu type = %u "
@@ -314,6 +321,38 @@ main(int argc, char *argv[])
total_write_size += drrw->drr_length;
break;
+ case DRR_WRITE_BYREF:
+ if (do_byteswap) {
+ drrwbr->drr_object =
+ BSWAP_64(drrwbr->drr_object);
+ drrwbr->drr_offset =
+ BSWAP_64(drrwbr->drr_offset);
+ drrwbr->drr_length =
+ BSWAP_64(drrwbr->drr_length);
+ drrwbr->drr_toguid =
+ BSWAP_64(drrwbr->drr_toguid);
+ drrwbr->drr_refguid =
+ BSWAP_64(drrwbr->drr_refguid);
+ drrwbr->drr_refobject =
+ BSWAP_64(drrwbr->drr_refobject);
+ drrwbr->drr_refoffset =
+ BSWAP_64(drrwbr->drr_refoffset);
+ }
+ if (verbose) {
+ (void) printf("WRITE_BYREF object = %llu "
+ "offset = %llu length = %llu\n"
+ "toguid = %llx refguid = %llx\n"
+ "refobject = %llu refoffset = %llu\n",
+ (u_longlong_t)drrwbr->drr_object,
+ (u_longlong_t)drrwbr->drr_offset,
+ (u_longlong_t)drrwbr->drr_length,
+ (u_longlong_t)drrwbr->drr_toguid,
+ (u_longlong_t)drrwbr->drr_refguid,
+ (u_longlong_t)drrwbr->drr_refobject,
+ (u_longlong_t)drrwbr->drr_refoffset);
+ }
+ break;
+
case DRR_FREE:
if (do_byteswap) {
drrf->drr_object = BSWAP_64(drrf->drr_object);