@@ -83,6 +83,8 @@ typedef struct progress_arg {
83
83
boolean_t pa_parsable ;
84
84
boolean_t pa_estimate ;
85
85
int pa_verbosity ;
86
+ boolean_t pa_astitle ;
87
+ uint64_t pa_size ;
86
88
} progress_arg_t ;
87
89
88
90
static int
@@ -733,6 +735,7 @@ typedef struct send_dump_data {
733
735
boolean_t seenfrom , seento , replicate , doall , fromorigin ;
734
736
boolean_t dryrun , parsable , progress , embed_data , std_out ;
735
737
boolean_t large_block , compress , raw , holds ;
738
+ boolean_t progressastitle ;
736
739
int outfd ;
737
740
boolean_t err ;
738
741
nvlist_t * fss ;
@@ -931,12 +934,13 @@ send_progress_thread(void *arg)
931
934
zfs_handle_t * zhp = pa -> pa_zhp ;
932
935
uint64_t bytes ;
933
936
uint64_t blocks ;
937
+ uint64_t total = pa -> pa_size / 100 ;
934
938
char buf [16 ];
935
939
time_t t ;
936
940
struct tm tm ;
937
941
int err ;
938
942
939
- if (!pa -> pa_parsable ) {
943
+ if (!pa -> pa_parsable && pa -> pa_verbosity != 0 ) {
940
944
(void ) fprintf (stderr ,
941
945
"TIME %s %sSNAPSHOT %s\n" ,
942
946
pa -> pa_estimate ? "BYTES" : " SENT" ,
@@ -959,6 +963,17 @@ send_progress_thread(void *arg)
959
963
(void ) time (& t );
960
964
localtime_r (& t , & tm );
961
965
966
+ if (pa -> pa_astitle ) {
967
+ char buf_bytes [16 ];
968
+ char buf_size [16 ];
969
+ int pct ;
970
+ zfs_nicenum (bytes , buf_bytes , sizeof (buf_bytes ));
971
+ zfs_nicenum (pa -> pa_size , buf_size , sizeof (buf_size ));
972
+ pct = (total > 0 ) ? bytes / total : 100 ;
973
+ zfs_setproctitle ("sending %s (%d%%: %s/%s)" ,
974
+ zhp -> zfs_name , MIN (pct , 100 ), buf_bytes , buf_size );
975
+ }
976
+
962
977
if (pa -> pa_verbosity >= 2 && pa -> pa_parsable ) {
963
978
(void ) fprintf (stderr ,
964
979
"%02d:%02d:%02d\t%llu\t%llu\t%s\n" ,
@@ -975,7 +990,7 @@ send_progress_thread(void *arg)
975
990
(void ) fprintf (stderr , "%02d:%02d:%02d\t%llu\t%s\n" ,
976
991
tm .tm_hour , tm .tm_min , tm .tm_sec ,
977
992
(u_longlong_t )bytes , zhp -> zfs_name );
978
- } else {
993
+ } else if ( pa -> pa_verbosity != 0 ) {
979
994
zfs_nicebytes (bytes , buf , sizeof (buf ));
980
995
(void ) fprintf (stderr , "%02d:%02d:%02d %5s %s\n" ,
981
996
tm .tm_hour , tm .tm_min , tm .tm_sec ,
@@ -1183,12 +1198,14 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
1183
1198
* If progress reporting is requested, spawn a new thread to
1184
1199
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1185
1200
*/
1186
- if (sdd -> progress ) {
1201
+ if (sdd -> progress || sdd -> progressastitle ) {
1187
1202
pa .pa_zhp = zhp ;
1188
1203
pa .pa_fd = sdd -> outfd ;
1189
1204
pa .pa_parsable = sdd -> parsable ;
1190
1205
pa .pa_estimate = B_FALSE ;
1191
1206
pa .pa_verbosity = sdd -> verbosity ;
1207
+ pa .pa_size = sdd -> size ;
1208
+ pa .pa_astitle = sdd -> progressastitle ;
1192
1209
1193
1210
if ((err = pthread_create (& tid , NULL ,
1194
1211
send_progress_thread , & pa )) != 0 ) {
@@ -1200,7 +1217,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
1200
1217
err = dump_ioctl (zhp , sdd -> prevsnap , sdd -> prevsnap_obj ,
1201
1218
fromorigin , sdd -> outfd , flags , sdd -> debugnv );
1202
1219
1203
- if (sdd -> progress &&
1220
+ if (( sdd -> progress || sdd -> progressastitle ) &&
1204
1221
send_progress_thread_exit (zhp -> zfs_hdl , tid ))
1205
1222
return (-1 );
1206
1223
}
@@ -1536,15 +1553,15 @@ lzc_flags_from_sendflags(const sendflags_t *flags)
1536
1553
static int
1537
1554
estimate_size (zfs_handle_t * zhp , const char * from , int fd , sendflags_t * flags ,
1538
1555
uint64_t resumeobj , uint64_t resumeoff , uint64_t bytes ,
1539
- const char * redactbook , char * errbuf )
1556
+ const char * redactbook , char * errbuf , uint64_t * sizep )
1540
1557
{
1541
1558
uint64_t size ;
1542
1559
FILE * fout = flags -> dryrun ? stdout : stderr ;
1543
1560
progress_arg_t pa = { 0 };
1544
1561
int err = 0 ;
1545
1562
pthread_t ptid ;
1546
1563
1547
- if (flags -> progress ) {
1564
+ if (flags -> progress || flags -> progressastitle ) {
1548
1565
pa .pa_zhp = zhp ;
1549
1566
pa .pa_fd = fd ;
1550
1567
pa .pa_parsable = flags -> parsable ;
@@ -1563,10 +1580,15 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
1563
1580
err = lzc_send_space_resume_redacted (zhp -> zfs_name , from ,
1564
1581
lzc_flags_from_sendflags (flags ), resumeobj , resumeoff , bytes ,
1565
1582
redactbook , fd , & size );
1583
+ * sizep = size ;
1566
1584
1567
- if (flags -> progress && send_progress_thread_exit (zhp -> zfs_hdl , ptid ))
1585
+ if ((flags -> progress || flags -> progressastitle ) &&
1586
+ send_progress_thread_exit (zhp -> zfs_hdl , ptid ))
1568
1587
return (-1 );
1569
1588
1589
+ if (!flags -> progress && !flags -> parsable )
1590
+ return (err );
1591
+
1570
1592
if (err != 0 ) {
1571
1593
zfs_error_aux (zhp -> zfs_hdl , "%s" , strerror (err ));
1572
1594
return (zfs_error (zhp -> zfs_hdl , EZFS_BADBACKUP ,
@@ -1743,6 +1765,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1743
1765
uint64_t * redact_snap_guids = NULL ;
1744
1766
int num_redact_snaps = 0 ;
1745
1767
char * redact_book = NULL ;
1768
+ uint64_t size = 0 ;
1746
1769
1747
1770
(void ) snprintf (errbuf , sizeof (errbuf ), dgettext (TEXT_DOMAIN ,
1748
1771
"cannot resume send" ));
@@ -1828,7 +1851,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1828
1851
enum lzc_send_flags lzc_flags = lzc_flags_from_sendflags (flags ) |
1829
1852
lzc_flags_from_resume_nvl (resume_nvl );
1830
1853
1831
- if (flags -> verbosity != 0 ) {
1854
+ if (flags -> verbosity != 0 || flags -> progressastitle ) {
1832
1855
/*
1833
1856
* Some of these may have come from the resume token, set them
1834
1857
* here for size estimate purposes.
@@ -1845,7 +1868,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1845
1868
if (lzc_flags & LZC_SEND_FLAG_SAVED )
1846
1869
tmpflags .saved = B_TRUE ;
1847
1870
error = estimate_size (zhp , fromname , outfd , & tmpflags ,
1848
- resumeobj , resumeoff , bytes , redact_book , errbuf );
1871
+ resumeobj , resumeoff , bytes , redact_book , errbuf , & size );
1849
1872
}
1850
1873
1851
1874
if (!flags -> dryrun ) {
@@ -1855,12 +1878,14 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1855
1878
* If progress reporting is requested, spawn a new thread to
1856
1879
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
1857
1880
*/
1858
- if (flags -> progress ) {
1881
+ if (flags -> progress || flags -> progressastitle ) {
1859
1882
pa .pa_zhp = zhp ;
1860
1883
pa .pa_fd = outfd ;
1861
1884
pa .pa_parsable = flags -> parsable ;
1862
1885
pa .pa_estimate = B_FALSE ;
1863
1886
pa .pa_verbosity = flags -> verbosity ;
1887
+ pa .pa_size = size ;
1888
+ pa .pa_astitle = flags -> progressastitle ;
1864
1889
1865
1890
error = pthread_create (& tid , NULL ,
1866
1891
send_progress_thread , & pa );
@@ -1877,8 +1902,11 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
1877
1902
if (redact_book != NULL )
1878
1903
free (redact_book );
1879
1904
1880
- if (flags -> progress && send_progress_thread_exit (hdl , tid ))
1905
+ if ((flags -> progressastitle || flags -> progress ) &&
1906
+ send_progress_thread_exit (hdl , tid )) {
1907
+ zfs_close (zhp );
1881
1908
return (-1 );
1909
+ }
1882
1910
1883
1911
char errbuf [ERRBUFLEN ];
1884
1912
(void ) snprintf (errbuf , sizeof (errbuf ), dgettext (TEXT_DOMAIN ,
@@ -2313,6 +2341,7 @@ zfs_send_cb_impl(zfs_handle_t *zhp, const char *fromsnap, const char *tosnap,
2313
2341
sdd .verbosity = flags -> verbosity ;
2314
2342
sdd .parsable = flags -> parsable ;
2315
2343
sdd .progress = flags -> progress ;
2344
+ sdd .progressastitle = flags -> progressastitle ;
2316
2345
sdd .dryrun = flags -> dryrun ;
2317
2346
sdd .large_block = flags -> largeblock ;
2318
2347
sdd .embed_data = flags -> embed_data ;
@@ -2562,6 +2591,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
2562
2591
char * name = zhp -> zfs_name ;
2563
2592
pthread_t ptid ;
2564
2593
progress_arg_t pa = { 0 };
2594
+ uint64_t size = 0 ;
2565
2595
2566
2596
char errbuf [ERRBUFLEN ];
2567
2597
(void ) snprintf (errbuf , sizeof (errbuf ), dgettext (TEXT_DOMAIN ,
@@ -2644,9 +2674,9 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
2644
2674
/*
2645
2675
* Perform size estimate if verbose was specified.
2646
2676
*/
2647
- if (flags -> verbosity != 0 ) {
2677
+ if (flags -> verbosity != 0 || flags -> progressastitle ) {
2648
2678
err = estimate_size (zhp , from , fd , flags , 0 , 0 , 0 , redactbook ,
2649
- errbuf );
2679
+ errbuf , & size );
2650
2680
if (err != 0 )
2651
2681
return (err );
2652
2682
}
@@ -2658,12 +2688,14 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
2658
2688
* If progress reporting is requested, spawn a new thread to poll
2659
2689
* ZFS_IOC_SEND_PROGRESS at a regular interval.
2660
2690
*/
2661
- if (flags -> progress ) {
2691
+ if (flags -> progress || flags -> progressastitle ) {
2662
2692
pa .pa_zhp = zhp ;
2663
2693
pa .pa_fd = fd ;
2664
2694
pa .pa_parsable = flags -> parsable ;
2665
2695
pa .pa_estimate = B_FALSE ;
2666
2696
pa .pa_verbosity = flags -> verbosity ;
2697
+ pa .pa_size = size ;
2698
+ pa .pa_astitle = flags -> progressastitle ;
2667
2699
2668
2700
err = pthread_create (& ptid , NULL ,
2669
2701
send_progress_thread , & pa );
@@ -2677,7 +2709,8 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
2677
2709
err = lzc_send_redacted (name , from , fd ,
2678
2710
lzc_flags_from_sendflags (flags ), redactbook );
2679
2711
2680
- if (flags -> progress && send_progress_thread_exit (hdl , ptid ))
2712
+ if ((flags -> progress || flags -> progressastitle ) &&
2713
+ send_progress_thread_exit (hdl , ptid ))
2681
2714
return (-1 );
2682
2715
2683
2716
if (err == 0 && (flags -> props || flags -> holds || flags -> backup )) {
0 commit comments