diff --git a/Meta/build-root-filesystem.sh b/Meta/build-root-filesystem.sh index 3f9aa2cf076f3e..2c824f6d252959 100755 --- a/Meta/build-root-filesystem.sh +++ b/Meta/build-root-filesystem.sh @@ -110,6 +110,10 @@ if [ -f mnt/usr/Tests/Kernel/TestProcFSWrite ]; then chown 0:0 mnt/usr/Tests/Kernel/TestProcFSWrite chmod 4755 mnt/usr/Tests/Kernel/TestProcFSWrite fi +if [ -f mnt/usr/Tests/Kernel/TestLoopDevice ]; then + chown 0:0 mnt/usr/Tests/Kernel/TestLoopDevice + chmod 4755 mnt/usr/Tests/Kernel/TestLoopDevice +fi if [ -f mnt/res/kernel.map ]; then chmod 0400 mnt/res/kernel.map diff --git a/Tests/Kernel/CMakeLists.txt b/Tests/Kernel/CMakeLists.txt index 9e49b0487c83fa..e5c08dcbc6c092 100644 --- a/Tests/Kernel/CMakeLists.txt +++ b/Tests/Kernel/CMakeLists.txt @@ -50,6 +50,7 @@ set(LIBTEST_BASED_SOURCES TestKernelFilePermissions.cpp TestKernelPledge.cpp TestKernelUnveil.cpp + TestLoopDevice.cpp TestMemoryDeviceMmap.cpp TestMunMap.cpp TestProcFS.cpp diff --git a/Tests/Kernel/TestLoopDevice.cpp b/Tests/Kernel/TestLoopDevice.cpp new file mode 100644 index 00000000000000..2935e8a493118e --- /dev/null +++ b/Tests/Kernel/TestLoopDevice.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, Liav A. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include + +static int open_loop_device(int loop_device_index) +{ + auto loop_device_path = ByteString::formatted("/dev/loop/{}", loop_device_index); + return open(loop_device_path.view().characters_without_null_termination(), O_RDONLY); +} + +TEST_CASE(create_attach_and_destory_loop_device) +{ + constexpr char const* test_path = "/tmp/create_attach_and_destory_loop_device_test"; + + int devctl_fd = open("/dev/devctl", O_RDONLY); + VERIFY(devctl_fd >= 0); + auto cleanup_devctl_fd_guard = ScopeGuard([&] { + close(devctl_fd); + }); + + u8 buf[0x1000]; + memset(buf, 0, sizeof(buf)); + int fd = open(test_path, O_RDWR | O_CREAT, 0644); + VERIFY(fd >= 0); + auto cleanup_fd_guard = ScopeGuard([&] { + close(fd); + unlink(test_path); + }); + auto rc = write(fd, buf, sizeof(buf)); + VERIFY(rc == sizeof(buf)); + + int value = fd; + auto create_result = ioctl(devctl_fd, DEVCTL_CREATE_LOOP_DEVICE, &value); + EXPECT_EQ(create_result, 0); + + auto loop_device_index = value; + auto loop_device_fd_or_error = open_loop_device(loop_device_index); + EXPECT(loop_device_fd_or_error >= 0); + auto cleanup_loop_device_fd_guard = ScopeGuard([&] { + close(loop_device_fd_or_error); + }); + + auto destroy_result = ioctl(devctl_fd, DEVCTL_DESTROY_LOOP_DEVICE, &loop_device_index); + EXPECT_EQ(destroy_result, 0); +}