kernel+libc+apps: Add mount and umount syscalls, libc wrappers, and utilities
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
29174ca228
commit
1f4c4928cc
@ -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
24
apps/mount.cpp
Normal 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
22
apps/umount.cpp
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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
34
kernel/src/sys/mount.cpp
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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
21
libc/include/sys/mount.h
Normal 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
19
libc/src/sys/mount.cpp
Normal 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);
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user