openzfs / zfs

OpenZFS on Linux and FreeBSD
https://openzfs.github.io/openzfs-docs
Other
10.55k stars 1.74k forks source link

zfs binary does not ignore SIGPIPE #12716

Open MEschenbacher opened 2 years ago

MEschenbacher commented 2 years ago

System information

Type Version/Name
Distribution Name FreeBSD
Distribution Version 13.0-RELEASE-p3
Kernel Version see above
Architecture amd64
OpenZFS Version zfs-2.0.0-FreeBSD_gf11b09dec zfs-kmod-2.0.0-FreeBSD_gf11b09dec

Describe the problem you're observing

The zfs binary does not ignore signal SIGPIPE except for zfs diff. This is normally not a problem when being used interactively in a shell or used in shell scripts where specific options are not set.

When using the zfs binary within bash scripts and options set -o pipefail -o errexit in a pipe chain where one of the consuming processes does not read all of zfs's output, zfs does not ignore signal SIGPIPE, resulting in erroneous termination of the bash script.

Arguably, it would not be wise to ignore SIGPIPE when the output is required to be consumed in total (e.g. for when using zfs send). Incidentally, SIGPIPE is already ignored for zfs diff.

I propose to ignore SIGPIPE for all commands except zfs ...:

Describe how to reproduce the problem

Use any zfs command (except zfs diff) to output a large amount of lines, pipe it into a command which exits before zfs has written all its output to stdout e.g. head -n 1 or grep -q.

Example:

set -o pipefail -o errexit

snapshot_name=$(zfs list -H -t snapshot -o name -S creation | head -n 1)

echo "$snapshot_name"

```bash
$ bash pipefail.sh; echo $?
141

Notice the snapshot name is not output but the script is exiting with exit code 141 (141-128=13 i.e. killed by SIGPIPE).

szubersk commented 2 years ago

Works perfectly fine on Debian.

System

szubersk@laptop /tmp % uname -a
Linux laptop.local 5.14.0-2-amd64 #1 SMP Debian 5.14.9-2 (2021-10-03) x86_64 GNU/Linux
szubersk@laptop /tmp % zfs --version
zfs-2.0.6-1
zfs-kmod-2.1.1-1

Result

szubersk@laptop /tmp % cat > test.sh
#!/usr/bin/env bash

set -o pipefail -o errexit

snapshot_name=$(zfs list -H -t snapshot -o name -S creation | head -n 1)

echo "$snapshot_name"
echo EXIT OK
szubersk@laptop /tmp % bash test.sh
zpool/ROOT/default@autosnap_2021-11-10_20:00:11_hourly
EXIT OK

Do you have a proof that the signals are misinterpreted on FreeBSD?

MEschenbacher commented 2 years ago

Are there many snapshots present to come to a situation in which input/output buffering of these shell pipes takes place? I believe this should happen around a tens or hundrets snapshots.

stale[bot] commented 1 year ago

This issue has been automatically marked as "stale" because it has not had any activity for a while. It will be closed in 90 days if no further activity occurs. Thank you for your contributions.

FloGatt commented 1 year ago

Is there any update on this?