Skip to content

Commit 16daae3

Browse files
committed
Added error for writing to /dev/ on Linux
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. Signed-off-by: Rich Ercolani <[email protected]>
1 parent 08cd071 commit 16daae3

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

cmd/zfs/zfs_main.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -728,6 +728,32 @@ finish_progress(char *done)
728728
pt_header = NULL;
729729
}
730730

731+
/* This function checks if the passed fd refers to /dev/null or /dev/zero */
732+
#ifdef __linux__
733+
static boolean_t
734+
is_dev_nullzero(int fd)
735+
{
736+
struct stat st;
737+
fstat(fd, &st);
738+
return (major(st.st_rdev) == 1 && (minor(st.st_rdev) == 3 /* null */ ||
739+
minor(st.st_rdev) == 5 /* zero */));
740+
}
741+
#endif
742+
743+
static void
744+
note_dev_error(int err, int fd)
745+
{
746+
#ifdef __linux__
747+
if (err == EINVAL && is_dev_nullzero(fd)) {
748+
(void) fprintf(stderr,
749+
gettext("Error: Writing directly to /dev/{null,zero} files"
750+
" on certain kernels is not currently implemented.\n"
751+
"(As a workaround, "
752+
"try \"zfs send [...] | cat > /dev/null\")\n"));
753+
}
754+
#endif
755+
}
756+
731757
static int
732758
zfs_mount_and_share(libzfs_handle_t *hdl, const char *dataset, zfs_type_t type)
733759
{
@@ -4572,11 +4598,16 @@ zfs_do_send(int argc, char **argv)
45724598

45734599
err = zfs_send_saved(zhp, &flags, STDOUT_FILENO,
45744600
resume_token);
4601+
if (err != 0)
4602+
note_dev_error(errno, STDOUT_FILENO);
45754603
zfs_close(zhp);
45764604
return (err != 0);
45774605
} else if (resume_token != NULL) {
4578-
return (zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
4579-
resume_token));
4606+
err = zfs_send_resume(g_zfs, &flags, STDOUT_FILENO,
4607+
resume_token);
4608+
if (err != 0)
4609+
note_dev_error(errno, STDOUT_FILENO);
4610+
return (err);
45804611
}
45814612

45824613
if (flags.skipmissing && !flags.replicate) {
@@ -4627,6 +4658,8 @@ zfs_do_send(int argc, char **argv)
46274658
err = zfs_send_one(zhp, fromname, STDOUT_FILENO, &flags,
46284659
redactbook);
46294660
zfs_close(zhp);
4661+
if (err != 0)
4662+
note_dev_error(errno, STDOUT_FILENO);
46304663
return (err != 0);
46314664
}
46324665

@@ -4703,6 +4736,7 @@ zfs_do_send(int argc, char **argv)
47034736
nvlist_free(dbgnv);
47044737
}
47054738
zfs_close(zhp);
4739+
note_dev_error(errno, STDOUT_FILENO);
47064740

47074741
return (err != 0);
47084742
}

lib/libzfs/libzfs_sendrecv.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,7 @@ dump_ioctl(zfs_handle_t *zhp, const char *fromsnap, uint64_t fromsnap_obj,
849849
case ERANGE:
850850
case EFAULT:
851851
case EROFS:
852+
case EINVAL:
852853
zfs_error_aux(hdl, "%s", strerror(errno));
853854
return (zfs_error(hdl, EZFS_BADBACKUP, errbuf));
854855

0 commit comments

Comments
 (0)