Skip to content

Commit 96813ab

Browse files
libzfs: sendrecv: always start the progress thread, but not the timer
Current semantics are preserved, /except/ no-flag "zfs send" can now receive SIGUSR1/SIGINFO will write the progress. Closes: https://101010.pl/@[email protected]/110731819189629373 Signed-off-by: Ahelenia Ziemiańska <[email protected]>
1 parent 2924c78 commit 96813ab

File tree

2 files changed

+46
-23
lines changed

2 files changed

+46
-23
lines changed

lib/libzfs/libzfs_sendrecv.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -928,16 +928,24 @@ zfs_send_progress(zfs_handle_t *zhp, int fd, uint64_t *bytes_written,
928928
return (0);
929929
}
930930

931+
static volatile boolean_t send_progress_thread_signal_duetotimer;
931932
static void
932-
signal_nop(int sig)
933+
send_progress_thread_act(int sig, siginfo_t *info, void *ucontext)
933934
{
934-
(void) sig;
935+
(void) sig, (void) ucontext;
936+
send_progress_thread_signal_duetotimer = info->si_code == SI_TIMER;
935937
}
936938

939+
struct timer_desirability {
940+
timer_t timer;
941+
boolean_t desired;
942+
};
937943
static void
938944
timer_delete_cleanup(void *timer)
939945
{
940-
timer_delete(timer);
946+
struct timer_desirability *td = timer;
947+
if (td->desired)
948+
timer_delete(td->timer);
941949
}
942950

943951
#ifdef SIGINFO
@@ -967,22 +975,24 @@ send_progress_thread(void *arg)
967975
int err;
968976

969977
const struct sigaction signal_action =
970-
{.sa_handler = signal_nop};
978+
{.sa_sigaction = send_progress_thread_act, .sa_flags = SA_SIGINFO};
971979
struct sigevent timer_cfg =
972980
{.sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGUSR1};
973981
const struct itimerspec timer_time =
974982
{.it_value = {.tv_sec = 1}, .it_interval = {.tv_sec = 1}};
975-
timer_t timer;
983+
struct timer_desirability timer = {};
976984

977985
sigaction(SIGUSR1, &signal_action, NULL);
978986
#ifdef SIGINFO
979987
sigaction(SIGINFO, &signal_action, NULL);
980988
#endif
981989

982-
if (timer_create(CLOCK_MONOTONIC, &timer_cfg, &timer))
983-
return ((void *)(uintptr_t)errno);
984-
pthread_cleanup_push(timer_delete_cleanup, timer);
985-
(void) timer_settime(timer, 0, &timer_time, NULL);
990+
if ((timer.desired = pa->pa_progress || pa->pa_astitle)) {
991+
if (timer_create(CLOCK_MONOTONIC, &timer_cfg, &timer.timer))
992+
return ((void *)(uintptr_t)errno);
993+
(void) timer_settime(timer.timer, 0, &timer_time, NULL);
994+
}
995+
pthread_cleanup_push(timer_delete_cleanup, &timer);
986996

987997
if (!pa->pa_parsable && pa->pa_progress) {
988998
(void) fprintf(stderr,
@@ -1033,7 +1043,8 @@ send_progress_thread(void *arg)
10331043
(void) fprintf(stderr, "%02d:%02d:%02d\t%llu\t%s\n",
10341044
tm.tm_hour, tm.tm_min, tm.tm_sec,
10351045
(u_longlong_t)bytes, zhp->zfs_name);
1036-
} else if (pa->pa_progress) {
1046+
} else if (pa->pa_progress ||
1047+
!send_progress_thread_signal_duetotimer) {
10371048
zfs_nicebytes(bytes, buf, sizeof (buf));
10381049
(void) fprintf(stderr, "%02d:%02d:%02d %5s %s\n",
10391050
tm.tm_hour, tm.tm_min, tm.tm_sec,
@@ -1246,7 +1257,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
12461257
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
12471258
*/
12481259
sigset_t oldmask;
1249-
if (sdd->progress || sdd->progressastitle) {
1260+
{
12501261
pa.pa_zhp = zhp;
12511262
pa.pa_fd = sdd->outfd;
12521263
pa.pa_parsable = sdd->parsable;
@@ -1267,8 +1278,7 @@ dump_snapshot(zfs_handle_t *zhp, void *arg)
12671278
err = dump_ioctl(zhp, sdd->prevsnap, sdd->prevsnap_obj,
12681279
fromorigin, sdd->outfd, flags, sdd->debugnv);
12691280

1270-
if ((sdd->progress || sdd->progressastitle) &&
1271-
send_progress_thread_exit(zhp->zfs_hdl, tid, &oldmask))
1281+
if (send_progress_thread_exit(zhp->zfs_hdl, tid, &oldmask))
12721282
return (-1);
12731283
}
12741284

@@ -1612,7 +1622,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
16121622
pthread_t ptid;
16131623
sigset_t oldmask;
16141624

1615-
if (flags->progress || flags->progressastitle) {
1625+
{
16161626
pa.pa_zhp = zhp;
16171627
pa.pa_fd = fd;
16181628
pa.pa_parsable = flags->parsable;
@@ -1634,8 +1644,7 @@ estimate_size(zfs_handle_t *zhp, const char *from, int fd, sendflags_t *flags,
16341644
redactbook, fd, &size);
16351645
*sizep = size;
16361646

1637-
if ((flags->progress || flags->progressastitle) &&
1638-
send_progress_thread_exit(zhp->zfs_hdl, ptid, &oldmask))
1647+
if (send_progress_thread_exit(zhp->zfs_hdl, ptid, &oldmask))
16391648
return (-1);
16401649

16411650
if (!flags->progress && !flags->parsable)
@@ -1931,7 +1940,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
19311940
* If progress reporting is requested, spawn a new thread to
19321941
* poll ZFS_IOC_SEND_PROGRESS at a regular interval.
19331942
*/
1934-
if (flags->progress || flags->progressastitle) {
1943+
{
19351944
pa.pa_zhp = zhp;
19361945
pa.pa_fd = outfd;
19371946
pa.pa_parsable = flags->parsable;
@@ -1957,8 +1966,7 @@ zfs_send_resume_impl_cb_impl(libzfs_handle_t *hdl, sendflags_t *flags,
19571966
if (redact_book != NULL)
19581967
free(redact_book);
19591968

1960-
if ((flags->progressastitle || flags->progress) &&
1961-
send_progress_thread_exit(hdl, tid, &oldmask)) {
1969+
if (send_progress_thread_exit(hdl, tid, &oldmask)) {
19621970
zfs_close(zhp);
19631971
return (-1);
19641972
}
@@ -2744,7 +2752,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
27442752
* ZFS_IOC_SEND_PROGRESS at a regular interval.
27452753
*/
27462754
sigset_t oldmask;
2747-
if (flags->progress || flags->progressastitle) {
2755+
{
27482756
pa.pa_zhp = zhp;
27492757
pa.pa_fd = fd;
27502758
pa.pa_parsable = flags->parsable;
@@ -2767,8 +2775,7 @@ zfs_send_one_cb_impl(zfs_handle_t *zhp, const char *from, int fd,
27672775
err = lzc_send_redacted(name, from, fd,
27682776
lzc_flags_from_sendflags(flags), redactbook);
27692777

2770-
if ((flags->progress || flags->progressastitle) &&
2771-
send_progress_thread_exit(hdl, ptid, &oldmask))
2778+
if (send_progress_thread_exit(hdl, ptid, &oldmask))
27722779
return (-1);
27732780

27742781
if (err == 0 && (flags->props || flags->holds || flags->backup)) {

man/man8/zfs-send.8

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
.\" Copyright 2018 Nexenta Systems, Inc.
3030
.\" Copyright 2019 Joyent, Inc.
3131
.\"
32-
.Dd January 12, 2023
32+
.Dd July 27, 2023
3333
.Dt ZFS-SEND 8
3434
.Os
3535
.
@@ -297,6 +297,12 @@ This flag can only be used in conjunction with
297297
.It Fl v , -verbose
298298
Print verbose information about the stream package generated.
299299
This information includes a per-second report of how much data has been sent.
300+
The same report can be requested by sending
301+
.Dv SIGINFO
302+
or
303+
.Dv SIGUSR1 ,
304+
regardless of
305+
.Fl v .
300306
.Pp
301307
The format of the stream is committed.
302308
You will be able to receive your streams on future versions of ZFS.
@@ -433,6 +439,12 @@ and the verbose output goes to standard error
433439
.It Fl v , -verbose
434440
Print verbose information about the stream package generated.
435441
This information includes a per-second report of how much data has been sent.
442+
The same report can be requested by sending
443+
.Dv SIGINFO
444+
or
445+
.Dv SIGUSR1 ,
446+
regardless of
447+
.Fl v .
436448
.El
437449
.It Xo
438450
.Nm zfs
@@ -669,6 +681,10 @@ ones on the source, and are ready to be used, while the parent snapshot on the
669681
target contains none of the username and password data present on the source,
670682
because it was removed by the redacted send operation.
671683
.
684+
.Sh SIGNALS
685+
See
686+
.Fl v .
687+
.
672688
.Sh EXAMPLES
673689
.\" These are, respectively, examples 12, 13 from zfs.8
674690
.\" Make sure to update them bidirectionally

0 commit comments

Comments
 (0)