We have occasional crashes in the rsend tests. Debugging revealed
that this is because the send_worker thread is getting EINTR from
splice(). This happens when a non-fatal signal is received during
the syscall. We should retry the syscall, rather than exiting failure.
Tweak the loop to only break if the splice is finished or we receive
a non-EINTR error.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Ahelenia ZiemiaĆska <nabijaczleweli@nabijaczleweli.xyz>
Signed-off-by: Paul Dagnelie <pcd@delphix.com>
Closes #15273
unsigned int bufsiz = max_pipe_buffer(ctx->from);
ssize_t rd;
- while ((rd = splice(ctx->from, NULL, ctx->to, NULL, bufsiz,
- SPLICE_F_MOVE | SPLICE_F_MORE)) > 0)
- ;
-
+ for (;;) {
+ rd = splice(ctx->from, NULL, ctx->to, NULL, bufsiz,
+ SPLICE_F_MOVE | SPLICE_F_MORE);
+ if ((rd == -1 && errno != EINTR) || rd == 0)
+ break;
+ }
int err = (rd == -1) ? errno : 0;
close(ctx->from);
return ((void *)(uintptr_t)err);