diff options
author | Rich Ercolani <214141+rincebrain@users.noreply.github.com> | 2021-06-09 20:57:57 -0400 |
---|---|---|
committer | Tony Hutter <hutter2@llnl.gov> | 2021-11-01 16:31:45 -0700 |
commit | 1b9f133028ba7a55ed247ea387d53a7fbde1b639 (patch) | |
tree | d46991448f0f7f4e4b53f1345d8028582435f0d0 | |
parent | 5e6435e2f7625f6e512233dd1d38099f1e698459 (diff) |
Added error for writing to /dev/ on Linuxzfs-2.0.7-staging
Starting in Linux 5.10, trying to write to /dev/{null,zero} errors out.
Prefer to inform people when this happens rather than hoping they guess
what's wrong.
Reviewed-by: Antonio Russo <aerusso@aerusso.net>
Reviewed-by: Ahelenia ZiemiaĆska <nabijaczleweli@nabijaczleweli.xyz>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: John Kennedy <john.kennedy@delphix.com>
Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
Closes: #11991
-rw-r--r-- | cmd/zfs/zfs_main.c | 38 | ||||
-rw-r--r-- | lib/libzfs/libzfs_sendrecv.c | 3 |
2 files changed, 38 insertions, 3 deletions
diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 92aafb091..52fd829e9 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -730,6 +730,32 @@ finish_progress(char *done) pt_header = NULL; } +/* This function checks if the passed fd refers to /dev/null or /dev/zero */ +#ifdef __linux__ +static boolean_t +is_dev_nullzero(int fd) +{ + struct stat st; + fstat(fd, &st); + return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ || + minor(st.st_rdev) == 5 /* zero */)); +} +#endif + +static void +note_dev_error(int err, int fd) +{ +#ifdef __linux__ + if (err == EINVAL && is_dev_nullzero(fd)) { + (void) fprintf(stderr, + gettext("Error: Writing directly to /dev/{null,zero} files" + " on certain kernels is not currently implemented.\n" + "(As a workaround, " + "try \"zfs send [...] | cat > /dev/null\")\n")); + } +#endif +} + static int zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type) { @@ -4448,11 +4474,16 @@ zfs_do_send(int argc, char **argv) err = zfs_send_saved(zhp, &flags, STDOUT_FILENO, resume_token); + if (err != 0) + note_dev_error(errno, STDOUT_FILENO); zfs_close(zhp); return (err != 0); } else if (resume_token != NULL) { - return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO, - resume_token)); + err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO, + resume_token); + if (err != 0) + note_dev_error(errno, STDOUT_FILENO); + return (err); } /* @@ -4496,6 +4527,8 @@ zfs_do_send(int argc, char **argv) err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags, redactbook); zfs_close(zhp); + if (err != 0) + note_dev_error(errno, STDOUT_FILENO); return (err != 0); } @@ -4572,6 +4605,7 @@ zfs_do_send(int argc, char **argv) nvlist_free(dbgnv); } zfs_close(zhp); + note_dev_error(errno, STDOUT_FILENO); return (err != 0); } diff --git a/lib/libzfs/libzfs_sendrecv.c b/lib/libzfs/libzfs_sendrecv.c index 5410b8fae..3ea2d22bd 100644 --- a/lib/libzfs/libzfs_sendrecv.c +++ b/lib/libzfs/libzfs_sendrecv.c @@ -847,7 +847,8 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj, case ERANGE: case EFAULT: case EROFS: - zfs_error_aux(hdl, strerror(errno)); + case EINVAL: + zfs_error_aux(hdl, "%s", strerror(errno)); return (zfs_error(hdl, EZFS_BADBACKUP, errbuf)); default: |