From a30927f763834d3b16b4945ff8d5638ede69d545 Mon Sep 17 00:00:00 2001 From: Rich Ercolani <214141+rincebrain@users.noreply.github.com> Date: Mon, 9 May 2022 19:33:55 -0400 Subject: [PATCH] Add workaround for broken Linux pipes Linux has an unresolved hang if you resize a pipe with bytes in it. Since there's no obvious way to detect this happening, added a workaround to disable resizing the pipe buffer if you set an environment variable. Reviewed-by: Brian Behlendorf Signed-off-by: Rich Ercolani Closes #13309 --- lib/libzfs_core/libzfs_core.c | 13 +++++++++++++ man/man8/zfs.8 | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index 0d74aa213..681fd8c7b 100644 --- a/lib/libzfs_core/libzfs_core.c +++ b/lib/libzfs_core/libzfs_core.c @@ -607,6 +607,19 @@ max_pipe_buffer(int infd) } unsigned int cur = fcntl(infd, F_GETPIPE_SZ); + /* + * Sadly, Linux has an unfixed deadlock if you do SETPIPE_SZ on a pipe + * with data in it. + * cf. #13232, https://bugzilla.kernel.org/show_bug.cgi?id=212295 + * + * And since the problem is in waking up the writer, there's nothing + * we can do about it from here. + * + * So if people want to, they can set this, but they + * may regret it... + */ + if (getenv("ZFS_SET_PIPE_MAX") == NULL) + return (cur); if (cur < max && fcntl(infd, F_SETPIPE_SZ, max) != -1) cur = max; return (cur); diff --git a/man/man8/zfs.8 b/man/man8/zfs.8 index 08996861a..bf8e86a5b 100644 --- a/man/man8/zfs.8 +++ b/man/man8/zfs.8 @@ -745,6 +745,14 @@ to use to mount ZFS datasets. This option is provided for backwards compatibility with older ZFS versions. .El +.Bl -tag -width "ZFS_SET_PIPE_MAX" +.It Sy ZFS_SET_PIPE_MAX +Tells +.Nm zfs +to set the maximum pipe size for sends/recieves. +Disabled by default on Linux +due to an unfixed deadlock in Linux's pipe size handling code. +.El . .Sh INTERFACE STABILITY .Sy Committed .