@@ -1,5 +1,7 @@
init
cpio_list
initrd
+testdir/
empty
+rdonly
@@ -1,10 +1,10 @@
# SPDX-License-Identifier: GPL-2.0
CFLAGS := -static -I../../../../usr/include
-TEST_PROGS := run_empty.sh
-TEST_GEN_FILES := init empty
+TEST_PROGS := run_empty.sh run_rdonly.sh
+TEST_GEN_FILES := init empty rdonly
TEST_FILES := lib.sh
include ../lib.mk
-EXTRA_CLEAN := initrd cpio_list
+EXTRA_CLEAN := initrd cpio_list testdir
@@ -55,3 +55,9 @@ run_qemu_empty() {
detect_debug "$1"
$run -drive index=0,if=floppy
}
+
+run_qemu_rdonly_fat() {
+ detect_debug "$2"
+ $run -drive file=fat:floppy:"$1",index=0,if=floppy,readonly
+}
+
new file mode 100644
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include <sys/ioctl.h>
+#include <linux/fd.h>
+#include "../kselftest_harness.h"
+
+FIXTURE(floppy) {
+ const char *dev;
+};
+
+FIXTURE_SETUP(floppy)
+{
+ int fd;
+ struct floppy_drive_params params;
+
+ self->dev = "/dev/fd0";
+ if (access(self->dev, F_OK))
+ ksft_exit_skip("No floppy device found\n");
+ if (access(self->dev, R_OK))
+ ksft_exit_skip("Floppy is not read accessible\n");
+
+ fd = open(self->dev, O_ACCMODE|O_NDELAY);
+ EXPECT_EQ(0, ioctl(fd, FDGETDRVPRM, ¶ms));
+ params.flags |= FTD_MSG|FD_DEBUG;
+ EXPECT_EQ(0, ioctl(fd, FDSETDRVPRM, ¶ms));
+ close(fd);
+}
+
+FIXTURE_TEARDOWN(floppy)
+{
+}
+
+TEST_F(floppy, read)
+{
+ int fd, test;
+
+ fd = open(self->dev, O_RDONLY);
+ ASSERT_GT(fd, 0);
+ ASSERT_EQ(read(fd, &test, sizeof(test)), sizeof(test));
+ ASSERT_EQ(close(fd), 0);
+}
+
+TEST_F(floppy, open_write_fail)
+{
+ ASSERT_LT(open(self->dev, O_WRONLY), 0);
+}
+
+TEST_F(floppy, open_rdwr_fail)
+{
+ ASSERT_LT(open(self->dev, O_RDWR), 0);
+}
+
+TEST_F(floppy, ioctl_disk_writable)
+{
+ int fd;
+ struct floppy_drive_struct drive;
+
+ fd = open(self->dev, O_RDONLY|O_NDELAY);
+ ASSERT_GT(fd, 0);
+ ASSERT_EQ(0, ioctl(fd, FDGETDRVSTAT, &drive));
+ ASSERT_FALSE(drive.flags & FD_DISK_WRITABLE);
+ ASSERT_EQ(close(fd), 0);
+}
+
+TEST_F(floppy, mount)
+{
+ int fd;
+ char test[5] = {};
+
+ mount(self->dev, "/mnt", "vfat", MS_RDONLY, NULL);
+ ASSERT_EQ(0, errno);
+
+ fd = open("/mnt/test", O_RDONLY);
+ read(fd, &test, sizeof(test));
+ ASSERT_EQ(0, strncmp(test, "TEST", 4));
+}
+
+TEST_F(floppy, open_ndelay_write_fail)
+{
+#define TEST_DATA "TEST_FAIL_WRITE"
+ int fd;
+ char test[] = TEST_DATA;
+
+ fd = open(self->dev, O_RDWR|O_NDELAY);
+ ASSERT_GT(fd, 0);
+
+ write(fd, test, sizeof(test));
+ read(fd, test, sizeof(test));
+ ASSERT_NE(0, strncmp(TEST_DATA, test, sizeof(TEST_DATA)));
+
+ ASSERT_EQ(close(fd), 0);
+#undef TEST_DATA
+}
+
+TEST_HARNESS_MAIN
new file mode 100755
@@ -0,0 +1,22 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+set -e
+
+source "$(dirname $0)"/lib.sh
+
+while getopts d flag; do
+ case "${flag}" in
+ d) debug=1;;
+ esac
+done
+
+if [ -z $debug ]; then
+ trap "rm -rf testdir" EXIT
+fi
+mkdir -p testdir
+echo -n TEST > testdir/test
+
+gen_cpio_list rdonly
+gen_initrd rdonly
+run_qemu_rdonly_fat testdir $debug
Add basic tests for a floppy with a readonly disk. "rdonly" test works under following assumptions: - there is a readonly disk in "/dev/fd0" - the disk is VFAT formatted - there is "test" file with "TEST" in it on the disk "run_rdonly.sh" script simulates the conditions and automates the testing process. The tests cover the regression: - commit f2791e7eadf4 ("Revert "floppy: refactor open() flags handling"") Signed-off-by: Denis Efremov <efremov@linux.com> --- tools/testing/selftests/floppy/.gitignore | 2 + tools/testing/selftests/floppy/Makefile | 6 +- tools/testing/selftests/floppy/lib.sh | 6 ++ tools/testing/selftests/floppy/rdonly.c | 99 ++++++++++++++++++++ tools/testing/selftests/floppy/run_rdonly.sh | 22 +++++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 tools/testing/selftests/floppy/rdonly.c create mode 100755 tools/testing/selftests/floppy/run_rdonly.sh