Skip to content

Commit

Permalink
Illumos #2703: add mechanism to report ZFS send progress
Browse files Browse the repository at this point in the history
Reviewed by: Matt Ahrens <matt@delphix.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Eric Schrock <Eric.Schrock@delphix.com>

References:
  https://www.illumos.org/issues/2703

Ported by: Martin Matuska <martin@matuska.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
  • Loading branch information
Bill Pijewski authored and behlendorf committed Sep 19, 2012
1 parent 1bd201e commit 37abac6
Show file tree
Hide file tree
Showing 12 changed files with 312 additions and 127 deletions.
2 changes: 2 additions & 0 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

#include <assert.h>
Expand Down Expand Up @@ -3551,6 +3552,7 @@ zfs_do_send(int argc, char **argv)
if (flags.verbose)
extraverbose = B_TRUE;
flags.verbose = B_TRUE;
flags.progress = B_TRUE;
break;
case 'D':
flags.dedup = B_TRUE;
Expand Down
4 changes: 4 additions & 0 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

#ifndef _LIBZFS_H
Expand Down Expand Up @@ -580,6 +581,9 @@ typedef struct sendflags {

/* parsable verbose output (ie. -P) */
boolean_t parsable;

/* show progress (ie. -v) */
boolean_t progress;
} sendflags_t;

typedef boolean_t (snapfilter_cb_t)(zfs_handle_t *, void *);
Expand Down
5 changes: 3 additions & 2 deletions include/sys/dmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -705,8 +706,8 @@ typedef void (*dmu_traverse_cb_t)(objset_t *os, void *arg, struct blkptr *bp,
void dmu_traverse_objset(objset_t *os, uint64_t txg_start,
dmu_traverse_cb_t cb, void *arg);

int dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
struct vnode *vp, offset_t *off);
int dmu_send(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
int outfd, struct vnode *vp, offset_t *off);
int dmu_send_estimate(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorign,
uint64_t *sizep);

Expand Down
28 changes: 28 additions & 0 deletions include/sys/dmu_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

#ifndef _SYS_DMU_IMPL_H
Expand All @@ -30,6 +31,7 @@
#include <sys/zio.h>
#include <sys/dnode.h>
#include <sys/zfs_context.h>
#include <sys/zfs_ioctl.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -239,6 +241,32 @@ typedef struct dmu_xuio {
iovec_t *iovp;
} dmu_xuio_t;

/*
* The list of data whose inclusion in a send stream can be pending from
* one call to backup_cb to another. Multiple calls to dump_free() and
* dump_freeobjects() can be aggregated into a single DRR_FREE or
* DRR_FREEOBJECTS replay record.
*/
typedef enum {
PENDING_NONE,
PENDING_FREE,
PENDING_FREEOBJECTS
} dmu_pendop_t;

typedef struct dmu_sendarg {
list_node_t dsa_link;
dmu_replay_record_t *dsa_drr;
vnode_t *dsa_vp;
int dsa_outfd;
proc_t *dsa_proc;
offset_t *dsa_off;
objset_t *dsa_os;
zio_cksum_t dsa_zc;
uint64_t dsa_toguid;
int dsa_err;
dmu_pendop_t dsa_pending_op;
} dmu_sendarg_t;

#ifdef __cplusplus
}
#endif
Expand Down
4 changes: 4 additions & 0 deletions include/sys/dsl_dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

#ifndef _SYS_DSL_DATASET_H
Expand Down Expand Up @@ -150,6 +151,9 @@ typedef struct dsl_dataset {
uint64_t ds_reserved; /* cached refreservation */
uint64_t ds_quota; /* cached refquota */

kmutex_t ds_sendstream_lock;
list_t ds_sendstreams;

/* Protected by ds_lock; keep at end of struct for better locality */
char ds_snapname[MAXNAMELEN];
} dsl_dataset_t;
Expand Down
2 changes: 2 additions & 0 deletions include/sys/fs/zfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

/* Portions Copyright 2010 Robert Milkowski */
Expand Down Expand Up @@ -803,6 +804,7 @@ typedef enum zfs_ioc {
ZFS_IOC_SPACE_WRITTEN,
ZFS_IOC_SPACE_SNAPS,
ZFS_IOC_POOL_REOPEN,
ZFS_IOC_SEND_PROGRESS,
} zfs_ioc_t;

/*
Expand Down
2 changes: 2 additions & 0 deletions include/sys/zfs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/
/*
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/

#ifndef _SYS_ZFS_CONTEXT_H
Expand Down Expand Up @@ -201,6 +202,7 @@ typedef struct proc {
} proc_t;

extern struct proc p0;
#define curproc (&p0)

typedef void (*thread_func_t)(void *);
typedef void (*thread_func_arg_t)(void *);
Expand Down
82 changes: 81 additions & 1 deletion lib/libzfs/libzfs_sendrecv.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* All rights reserved
*/

Expand All @@ -44,6 +45,7 @@
#include <stddef.h>
#include <pthread.h>
#include <umem.h>
#include <time.h>

#include <libzfs.h>

Expand All @@ -69,6 +71,12 @@ typedef struct dedup_arg {
libzfs_handle_t *dedup_hdl;
} dedup_arg_t;

typedef struct progress_arg {
zfs_handle_t *pa_zhp;
int pa_fd;
boolean_t pa_parsable;
} progress_arg_t;

typedef struct dataref {
uint64_t ref_guid;
uint64_t ref_object;
Expand Down Expand Up @@ -787,7 +795,7 @@ typedef struct send_dump_data {
char prevsnap[ZFS_MAXNAMELEN];
uint64_t prevsnap_obj;
boolean_t seenfrom, seento, replicate, doall, fromorigin;
boolean_t verbose, dryrun, parsable;
boolean_t verbose, dryrun, parsable, progress;
int outfd;
boolean_t err;
nvlist_t *fss;
Expand Down Expand Up @@ -979,10 +987,60 @@ hold_for_send(zfs_handle_t *zhp, send_dump_data_t *sdd)
return (error);
}

static void *
send_progress_thread(void *arg)
{
progress_arg_t *pa = arg;

zfs_cmd_t zc = { "\0", "\0", "\0", "\0", 0 };
zfs_handle_t *zhp = pa->pa_zhp;
libzfs_handle_t *hdl = zhp->zfs_hdl;
unsigned long long bytes;
char buf[16];

time_t t;
struct tm *tm;

assert(zhp->zfs_type == ZFS_TYPE_SNAPSHOT);
(void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name));

if (!pa->pa_parsable)
(void) fprintf(stderr, "TIME SENT SNAPSHOT\n");

/*
* Print the progress from ZFS_IOC_SEND_PROGRESS every second.
*/
for (;;) {
(void) sleep(1);

zc.zc_cookie = pa->pa_fd;
if (zfs_ioctl(hdl, ZFS_IOC_SEND_PROGRESS, &zc) != 0)
return ((void *)-1);

(void) time(&t);
tm = localtime(&t);
bytes = zc.zc_cookie;

if (pa->pa_parsable) {
(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
tm->tm_hour, tm->tm_min, tm->tm_sec,
bytes, zhp->zfs_name);
} else {
zfs_nicenum(bytes, buf, sizeof (buf));
(void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
tm->tm_hour, tm->tm_min, tm->tm_sec,
buf, zhp->zfs_name);
}
}
}

static int
dump_snapshot(zfs_handle_t *zhp, void *arg)
{
send_dump_data_t *sdd = arg;
progress_arg_t pa = { 0 };
pthread_t tid;

char *thissnap;
int err;
boolean_t isfromsnap, istosnap, fromorigin;
Expand Down Expand Up @@ -1100,8 +1158,29 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
}

if (!sdd->dryrun) {
/*
* If progress reporting is requested, spawn a new thread to
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
*/
if (sdd->progress) {
pa.pa_zhp = zhp;
pa.pa_fd = sdd->outfd;
pa.pa_parsable = sdd->parsable;

if ((err = pthread_create(&tid, NULL,
send_progress_thread, &pa))) {
zfs_close(zhp);
return (err);
}
}

err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
fromorigin, sdd->outfd, sdd->debugnv);

if (sdd->progress) {
(void) pthread_cancel(tid);
(void) pthread_join(tid, NULL);
}
}

(void) strcpy(sdd->prevsnap, thissnap);
Expand Down Expand Up @@ -1445,6 +1524,7 @@ zfs_send(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
sdd.fsavl = fsavl;
sdd.verbose = flags->verbose;
sdd.parsable = flags->parsable;
sdd.progress = flags->progress;
sdd.dryrun = flags->dryrun;
sdd.filter_cb = filter_func;
sdd.filter_cb_arg = cb_arg;
Expand Down
4 changes: 3 additions & 1 deletion man/man8/zfs.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.\" Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
.\" Copyright (c) 2012 by Delphix. All rights reserved.
.\" Copyright (c) 2012 Nexenta Systems, Inc. All Rights Reserved.
.\" Copyright (c) 2012, Joyent, Inc. All rights reserved.
.\" Copyright 2011 Joshua M. Clulow <josh@sysmgr.org>
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.
.\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with
Expand Down Expand Up @@ -2306,7 +2307,8 @@ Generate a stream package that sends all intermediary snapshots from the first s
.ad
.sp .6
.RS 4n
Print verbose information about the stream package generated.
Print verbose information about the stream package generated. This information
includes a per-second report of how much data has been sent.
.RE

.sp
Expand Down
Loading

0 comments on commit 37abac6

Please sign in to comment.