1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-14 05:24:58 +00:00

Utilities/mount: Automatically mount regular files with loop devices

Check if the source fd is not a block device file using the fstat
syscall and if that's the case, try to mount the file using a temporary
loop device.
This commit is contained in:
Liav A 2024-02-09 17:17:14 +02:00 committed by Andrew Kaster
parent e14c571916
commit 0739b5df11
2 changed files with 24 additions and 1 deletions

View file

@ -44,6 +44,9 @@ Additionally, the name `defaults` is accepted and ignored.
```sh ```sh
# mount devpts /dev/pts -t devpts -o noexec,nosuid # mount devpts /dev/pts -t devpts -o noexec,nosuid
# mount /home/anon/myfile.txt /tmp/foo -o bind # mount /home/anon/myfile.txt /tmp/foo -o bind
# mount a regular file using a temporary loop device
$ mount /home/anon/myfilesystem.bin /mnt
``` ```
## See also ## See also

View file

@ -7,6 +7,7 @@
#include <AK/JsonArray.h> #include <AK/JsonArray.h>
#include <AK/JsonObject.h> #include <AK/JsonObject.h>
#include <AK/JsonValue.h> #include <AK/JsonValue.h>
#include <AK/String.h>
#include <LibCore/ArgsParser.h> #include <LibCore/ArgsParser.h>
#include <LibCore/DirIterator.h> #include <LibCore/DirIterator.h>
#include <LibCore/File.h> #include <LibCore/File.h>
@ -197,6 +198,21 @@ static ErrorOr<void> print_mounts()
return {}; return {};
} }
static ErrorOr<void> mount_using_loop_device(int inode_fd, StringView mountpoint, StringView fs_type, int flags)
{
int devctl_fd = TRY(Core::System::open("/dev/devctl"sv, O_RDONLY));
int value = inode_fd;
TRY(Core::System::ioctl(devctl_fd, DEVCTL_CREATE_LOOP_DEVICE, &value));
int loop_device_index = value;
auto loop_device_path = TRY(String::formatted("/dev/loop/{}", loop_device_index));
int loop_device_fd = TRY(Core::System::open(loop_device_path.bytes_as_string_view(), O_RDONLY));
auto result = Core::System::mount(loop_device_fd, mountpoint, fs_type, flags);
TRY(Core::System::ioctl(devctl_fd, DEVCTL_DESTROY_LOOP_DEVICE, &loop_device_index));
return result;
}
ErrorOr<int> serenity_main(Main::Arguments arguments) ErrorOr<int> serenity_main(Main::Arguments arguments)
{ {
StringView source; StringView source;
@ -242,7 +258,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
} else { } else {
if (fs_type.is_empty()) if (fs_type.is_empty())
fs_type = "ext2"sv; fs_type = "ext2"sv;
TRY(Core::System::mount(fd, mountpoint, fs_type, flags)); auto stat = TRY(Core::System::fstat(fd));
if (!S_ISBLK(stat.st_mode))
TRY(mount_using_loop_device(fd, mountpoint, fs_type, flags));
else
TRY(Core::System::mount(fd, mountpoint, fs_type, flags));
} }
return 0; return 0;
} }