kernel+libc+apps: Add mount and umount syscalls, libc wrappers, and utilities
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-05-17 20:30:15 +02:00
parent 29174ca228
commit 1f4c4928cc
Signed by: apio
GPG Key ID: B8A7D06E42258954
14 changed files with 145 additions and 23 deletions

View File

@ -24,3 +24,5 @@ luna_app(uname.cpp uname)
luna_app(base64.cpp base64)
luna_app(login.cpp login)
luna_app(ipc-test.cpp ipc-test)
luna_app(mount.cpp mount)
luna_app(umount.cpp umount)

24
apps/mount.cpp Normal file
View File

@ -0,0 +1,24 @@
#include <os/ArgumentParser.h>
#include <stdio.h>
#include <sys/mount.h>
Result<int> luna_main(int argc, char** argv)
{
StringView target;
StringView fstype;
os::ArgumentParser parser;
parser.add_description("Mount a file system.");
parser.add_system_program_info("mount"_sv);
parser.add_positional_argument(target, "mountpoint"_sv, true);
parser.add_value_argument(fstype, 't', "type"_sv, "auto"_sv, "the file system type to use");
parser.parse(argc, argv);
if (mount(target.chars(), fstype.chars()) < 0)
{
perror("mount");
return 1;
}
return 0;
}

22
apps/umount.cpp Normal file
View File

@ -0,0 +1,22 @@
#include <os/ArgumentParser.h>
#include <stdio.h>
#include <sys/mount.h>
Result<int> luna_main(int argc, char** argv)
{
StringView target;
os::ArgumentParser parser;
parser.add_description("Unmount a file system.");
parser.add_system_program_info("umount"_sv);
parser.add_positional_argument(target, "mountpoint"_sv, true);
parser.parse(argc, argv);
if (umount(target.chars()) < 0)
{
perror("umount");
return 1;
}
return 0;
}

View File

@ -38,6 +38,7 @@ set(SOURCES
src/sys/chdir.cpp
src/sys/link.cpp
src/sys/uname.cpp
src/sys/mount.cpp
src/fs/VFS.cpp
src/fs/Pipe.cpp
src/fs/Mount.cpp

View File

@ -88,7 +88,11 @@ Result<u64> sys_execve(Registers* regs, SyscallArgs args)
{
auto& descriptor = current->fd_table[i];
if (!descriptor.has_value()) continue;
if (descriptor->flags & O_CLOEXEC) descriptor = {};
if (descriptor->flags & O_CLOEXEC)
{
descriptor->inode->fs()->remove_handle();
descriptor = {};
}
}
MMU::delete_userspace_page_directory(current->directory);
@ -132,7 +136,11 @@ Result<u64> sys_fork(Registers* regs, SyscallArgs)
thread->current_directory_path = move(current_directory_path);
thread->parent = current;
for (int i = 0; i < FD_MAX; i++) { thread->fd_table[i] = current->fd_table[i]; }
for (int i = 0; i < FD_MAX; i++)
{
thread->fd_table[i] = current->fd_table[i];
if (current->fd_table[i].has_value()) current->fd_table[i]->inode->fs()->add_handle();
}
image->apply(thread);

34
kernel/src/sys/mount.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "fs/VFS.h"
#include "fs/tmpfs/FileSystem.h"
#include "memory/MemoryManager.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
Result<u64> sys_mount(Registers*, SyscallArgs args)
{
auto target = TRY(MemoryManager::strdup_from_user(args[0]));
auto fstype = TRY(MemoryManager::strdup_from_user(args[1]));
auto* current = Scheduler::current();
if (current->auth.euid != 0) return err(EPERM);
// Right now we only support one file system.
if (fstype.view() != "tmpfs") return err(ENODEV);
auto fs = TRY(TmpFS::FileSystem::create());
TRY(VFS::mount(target.chars(), fs, current->auth, current->current_directory));
return 0;
}
Result<u64> sys_umount(Registers*, SyscallArgs args)
{
auto target = TRY(MemoryManager::strdup_from_user(args[0]));
auto* current = Scheduler::current();
if (current->auth.euid != 0) return err(EPERM);
TRY(VFS::umount(target.chars(), current->auth, current->current_directory));
return 0;
}

View File

@ -72,6 +72,8 @@ Result<u64> sys_openat(Registers*, SyscallArgs args)
kinfoln("openat: opening file %s from dirfd %d, flags %d, mode %#o = fd %d", path.chars(), dirfd, flags, mode, fd);
inode->fs()->add_handle();
current->fd_table[fd] = FileDescriptor { inode, 0, flags & FLAGS_TO_KEEP };
return (u64)fd;
@ -88,6 +90,8 @@ Result<u64> sys_close(Registers*, SyscallArgs args)
if (!descriptor.has_value()) return err(EBADF);
descriptor->inode->fs()->remove_handle();
descriptor = {};
return 0;

View File

@ -182,6 +182,11 @@ namespace Scheduler
{
auto stack = thread->kernel_stack;
MemoryManager::unmap_owned_and_free_vm(stack.bottom(), stack.bytes() / ARCH_PAGE_SIZE).release_value();
for (int i = 0; i < FD_MAX; i++)
{
if (thread->fd_table[i].has_value()) thread->fd_table[i]->inode->fs()->remove_handle();
}
}
if (!thread->is_kernel) MMU::delete_userspace_page_directory(thread->directory);

View File

@ -66,22 +66,6 @@ Result<SharedPtr<VFS::Inode>> Thread::resolve_atfile(int dirfd, const String& pa
return VFS::resolve_path(path.chars(), this->auth, descriptor->inode);
}
FileDescriptor::FileDescriptor(SharedPtr<VFS::Inode> _inode, usize _offset, int _flags)
: inode(_inode), offset(_offset), flags(_flags)
{
inode->fs()->add_handle();
}
FileDescriptor::FileDescriptor(const FileDescriptor& f) : inode(f.inode), offset(f.offset), flags(f.flags)
{
inode->fs()->add_handle();
}
FileDescriptor::~FileDescriptor()
{
inode->fs()->remove_handle();
}
bool FileDescriptor::should_append()
{
return flags & O_APPEND;

View File

@ -33,10 +33,6 @@ struct FileDescriptor
usize offset { 0 };
int flags { 0 };
FileDescriptor(SharedPtr<VFS::Inode> inode, usize offset, int flags);
FileDescriptor(const FileDescriptor& f);
~FileDescriptor();
bool should_append();
bool should_block();
bool is_writable();

View File

@ -24,6 +24,7 @@ set(SOURCES
src/sys/wait.cpp
src/sys/ioctl.cpp
src/sys/utsname.cpp
src/sys/mount.cpp
)
if(${LUNA_ARCH} STREQUAL "x86_64")

21
libc/include/sys/mount.h Normal file
View File

@ -0,0 +1,21 @@
/* sys/mount.h: Virtual file system mounting operations. */
#ifndef _SYS_MOUNT_H
#define _SYS_MOUNT_H
#ifdef __cplusplus
extern "C"
{
#endif
/* Mount a file system on target. */
int mount(const char* target, const char* fstype);
/* Unmount the file system mounted on target. */
int umount(const char* target);
#ifdef __cplusplus
}
#endif
#endif

19
libc/src/sys/mount.cpp Normal file
View File

@ -0,0 +1,19 @@
#include <bits/errno-return.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <unistd.h>
extern "C"
{
int mount(const char* target, const char* fstype)
{
long rc = syscall(SYS_mount, target, fstype);
__errno_return(rc, int);
}
int umount(const char* target)
{
long rc = syscall(SYS_umount, target);
__errno_return(rc, int);
}
}

View File

@ -4,7 +4,8 @@
_e(exit) _e(clock_gettime) _e(mmap) _e(munmap) _e(usleep) _e(openat) _e(close) _e(read) _e(getpid) _e(write) \
_e(lseek) _e(mkdir) _e(execve) _e(mknod) _e(fork) _e(waitpid) _e(getppid) _e(fcntl) _e(getdents) _e(getuid) \
_e(geteuid) _e(getgid) _e(getegid) _e(setuid) _e(setgid) _e(seteuid) _e(setegid) _e(fchmodat) _e(fchownat) \
_e(ioctl) _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe)
_e(ioctl) _e(fstatat) _e(chdir) _e(getcwd) _e(unlinkat) _e(uname) _e(sethostname) _e(dup2) _e(pipe) \
_e(mount) _e(umount)
enum Syscalls
{