expose mounting to userspace
This commit is contained in:
parent
b59871ca67
commit
17e332b5e7
@ -71,7 +71,6 @@ static void output_process(pty_t * pty, uint8_t c) {
|
||||
|
||||
static void input_process(pty_t * pty, uint8_t c) {
|
||||
if (pty->tios.c_lflag & ICANON) {
|
||||
debug_print(INFO, "Processing for character %d in canon mode", c);
|
||||
if (c == pty->tios.c_cc[VKILL]) {
|
||||
while (pty->canon_buflen > 0) {
|
||||
pty->canon_buflen--;
|
||||
@ -151,7 +150,6 @@ static void input_process(pty_t * pty, uint8_t c) {
|
||||
}
|
||||
|
||||
int pty_ioctl(pty_t * pty, int request, void * argp) {
|
||||
debug_print(INFO, "Incoming IOCTL request %d", request);
|
||||
switch (request) {
|
||||
case IOCTLDTYPE:
|
||||
/*
|
||||
@ -200,9 +198,8 @@ int pty_ioctl(pty_t * pty, int request, void * argp) {
|
||||
memcpy(&pty->tios, argp, sizeof(struct termios));
|
||||
return 0;
|
||||
default:
|
||||
return -1; /* TODO EINV... something or other */
|
||||
return -EINVAL;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
|
@ -14,14 +14,19 @@
|
||||
#include <list.h>
|
||||
#include <process.h>
|
||||
#include <logging.h>
|
||||
#include <hashmap.h>
|
||||
|
||||
tree_t * fs_tree = NULL; /* File system mountpoint tree */
|
||||
fs_node_t * fs_root = NULL; /* Pointer to the root mount fs_node (must be some form of filesystem, even ramdisk) */
|
||||
|
||||
hashmap_t * fs_types = NULL;
|
||||
|
||||
|
||||
static struct dirent * readdir_mapper(fs_node_t *node, uint32_t index) {
|
||||
tree_node_t * d = (tree_node_t *)node->device;
|
||||
|
||||
if (!d) return NULL;
|
||||
|
||||
if (index == 0) {
|
||||
struct dirent * dir = malloc(sizeof(struct dirent));
|
||||
strcpy(dir->name, ".");
|
||||
@ -477,6 +482,31 @@ void vfs_install(void) {
|
||||
root->file = NULL; /* Nothing mounted as root */
|
||||
|
||||
tree_set_root(fs_tree, root);
|
||||
|
||||
fs_types = hashmap_create(5);
|
||||
}
|
||||
|
||||
int vfs_register(char * name, vfs_mount_callback callback) {
|
||||
if (hashmap_get(fs_types, name)) return 1;
|
||||
hashmap_set(fs_types, name, (void *)(uintptr_t)callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vfs_mount_type(char * type, char * arg, char * mountpoint) {
|
||||
|
||||
vfs_mount_callback t = (vfs_mount_callback)(uintptr_t)hashmap_get(fs_types, type);
|
||||
if (!t) {
|
||||
debug_print(WARNING, "Unknown filesystem type: %s", type);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
fs_node_t * n = t(arg, mountpoint);
|
||||
|
||||
if (!n) return -EINVAL;
|
||||
|
||||
vfs_mount(mountpoint, n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -577,8 +607,11 @@ _vfs_cleanup:
|
||||
void map_vfs_directory(char * c) {
|
||||
fs_node_t * f = vfs_mapper();
|
||||
struct vfs_entry * e = vfs_mount(c, f);
|
||||
strcpy(f->name, e->name);
|
||||
f->device = e;
|
||||
if (!strcmp(c, "/")) {
|
||||
f->device = fs_tree->root;
|
||||
} else {
|
||||
f->device = e;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -686,7 +719,7 @@ fs_node_t *get_mount_point(char * path, unsigned int path_depth, char **outpath,
|
||||
*/
|
||||
fs_node_t *kopen(char *filename, uint32_t flags) {
|
||||
/* Simple sanity checks that we actually have a file system */
|
||||
if (!fs_root || !filename) {
|
||||
if (!filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -742,6 +775,8 @@ fs_node_t *kopen(char *filename, uint32_t flags) {
|
||||
/* Find the mountpoint for this file */
|
||||
fs_node_t *node_ptr = get_mount_point(path, path_depth, &path_offset, &depth);
|
||||
|
||||
if (!node_ptr) return NULL;
|
||||
|
||||
if (path_offset >= path+path_len) {
|
||||
free(path);
|
||||
open_fs(node_ptr, flags);
|
||||
|
@ -132,6 +132,9 @@ int unlink_fs(char * name);
|
||||
|
||||
void vfs_install(void);
|
||||
void * vfs_mount(char * path, fs_node_t * local_root);
|
||||
typedef fs_node_t * (*vfs_mount_callback)(char * arg, char * mount_point);
|
||||
int vfs_register(char * name, vfs_mount_callback callback);
|
||||
int vfs_mount_type(char * type, char * arg, char * mountpoint);
|
||||
|
||||
/* Debug purposes only, please */
|
||||
void debug_print_vfs_tree(void);
|
||||
|
@ -1,43 +0,0 @@
|
||||
#define SYS_EXT 0
|
||||
#define SYS_OPEN 2
|
||||
#define SYS_READ 3
|
||||
#define SYS_WRITE 4
|
||||
#define SYS_CLOSE 5
|
||||
#define SYS_GETTIMEOFDAY 6
|
||||
#define SYS_EXECVE 7
|
||||
#define SYS_FORK 8
|
||||
#define SYS_GETPID 9
|
||||
#define SYS_SBRK 10
|
||||
#define SYS_UNAME 12
|
||||
#define SYS_OPENPTY 13
|
||||
#define SYS_SEEK 14
|
||||
#define SYS_STAT 15
|
||||
#define SYS_MKPIPE 21
|
||||
#define SYS_DUP2 22
|
||||
#define SYS_GETUID 23
|
||||
#define SYS_SETUID 24
|
||||
#define SYS_REBOOT 26
|
||||
#define SYS_READDIR 27
|
||||
#define SYS_CHDIR 28
|
||||
#define SYS_GETCWD 29
|
||||
#define SYS_CLONE 30
|
||||
#define SYS_SETHOSTNAME 31
|
||||
#define SYS_GETHOSTNAME 32
|
||||
#define SYS_MKDIR 34
|
||||
#define SYS_SHM_OBTAIN 35
|
||||
#define SYS_SHM_RELEASE 36
|
||||
#define SYS_KILL 37
|
||||
#define SYS_SIGNAL 38
|
||||
#define SYS_GETTID 41
|
||||
#define SYS_YIELD 42
|
||||
#define SYS_SYSFUNC 43
|
||||
#define SYS_SLEEPABS 45
|
||||
#define SYS_SLEEP 46
|
||||
#define SYS_IOCTL 47
|
||||
#define SYS_ACCESS 48
|
||||
#define SYS_STATF 49
|
||||
#define SYS_CHMOD 50
|
||||
#define SYS_UMASK 51
|
||||
#define SYS_UNLINK 52
|
||||
#define SYS_WAITPID 53
|
||||
#define SYS_PIPE 54
|
1
kernel/include/syscall_nums.h
Symbolic link
1
kernel/include/syscall_nums.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../toolchain/patches/newlib/include/syscall_nums.h
|
@ -183,10 +183,13 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Map /dev to a device mapper */
|
||||
map_vfs_directory("/dev");
|
||||
|
||||
if (args_present("root")) {
|
||||
vfs_mount_type("ext2", "/dev/hda", "/");
|
||||
}
|
||||
|
||||
if (args_present("start")) {
|
||||
char * c = args_value("start");
|
||||
if (!c) {
|
||||
@ -197,6 +200,12 @@ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs_root) {
|
||||
debug_print(CRITICAL, "No root filesystem is mounted. Skipping init.");
|
||||
map_vfs_directory("/");
|
||||
switch_task(0);
|
||||
}
|
||||
|
||||
/* Prepare to run /bin/init */
|
||||
char * argv[] = {
|
||||
"/bin/init",
|
||||
|
@ -634,6 +634,23 @@ static int sys_pipe(int pipes[2]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sys_mount(char * arg, char * mountpoint, char * type, unsigned long flags, void * data) {
|
||||
|
||||
if (validate_safe(arg) || validate_safe(mountpoint) || validate_safe(type)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (current_process->user != USER_ROOT_UID) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
/* I may or may not start using these eventually. */
|
||||
(void)flags;
|
||||
(void)data;
|
||||
|
||||
return vfs_mount_type(type, arg, mountpoint);
|
||||
}
|
||||
|
||||
/*
|
||||
* System Call Internals
|
||||
*/
|
||||
@ -682,6 +699,7 @@ static int (*syscalls[])() = {
|
||||
[SYS_UNLINK] = sys_unlink,
|
||||
[SYS_WAITPID] = sys_waitpid,
|
||||
[SYS_PIPE] = sys_pipe,
|
||||
[SYS_MOUNT] = sys_mount,
|
||||
};
|
||||
|
||||
uint32_t num_syscalls = sizeof(syscalls) / sizeof(int (*)());
|
||||
|
@ -205,14 +205,14 @@ static int shell_help(fs_node_t * tty, int argc, char * argv[]) {
|
||||
|
||||
static int shell_cd(fs_node_t * tty, int argc, char * argv[]) {
|
||||
if (argc < 2) {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
char * newdir = argv[1];
|
||||
char * path = canonicalize_path(current_process->wd_name, newdir);
|
||||
fs_node_t * chd = kopen(path, 0);
|
||||
if (chd) {
|
||||
if ((chd->flags & FS_DIRECTORY) == 0) {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
close_fs(chd);
|
||||
free(current_process->wd_name);
|
||||
@ -220,7 +220,7 @@ static int shell_cd(fs_node_t * tty, int argc, char * argv[]) {
|
||||
memcpy(current_process->wd_name, path, strlen(path) + 1);
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -494,6 +494,15 @@ static int shell_fix_mouse(fs_node_t * tty, int argc, char * argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int shell_mount(fs_node_t * tty, int argc, char * argv[]) {
|
||||
if (argc < 4) {
|
||||
fprintf(tty, "Usage: %s type device mountpoint\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return -vfs_mount_type(argv[1], argv[2], argv[3]);
|
||||
}
|
||||
|
||||
static int shell_exit(fs_node_t * tty, int argc, char * argv[]) {
|
||||
kexit(0);
|
||||
return 0;
|
||||
@ -530,6 +539,8 @@ static struct shell_command shell_commands[] = {
|
||||
"Attempt to discover TTY size of serial."},
|
||||
{"fix-mouse", &shell_fix_mouse,
|
||||
"Attempt to reset mouse device."},
|
||||
{"mount", &shell_mount,
|
||||
"Mount a filesystemp."},
|
||||
{"exit", &shell_exit,
|
||||
"Quit the shell."},
|
||||
{NULL, NULL, NULL}
|
||||
|
@ -939,18 +939,17 @@ static fs_node_t * mount_ext2(fs_node_t * block_device) {
|
||||
|
||||
fs_node_t * ext2_fs_mount(char * device, char * mount_path) {
|
||||
fs_node_t * dev = kopen(device, 0);
|
||||
if (!dev) return NULL;
|
||||
if (!dev) {
|
||||
debug_print(ERROR, "failed to open %s", device);
|
||||
return NULL;
|
||||
}
|
||||
fs_node_t * fs = mount_ext2(dev);
|
||||
if (!fs) return NULL;
|
||||
vfs_mount(mount_path, fs);
|
||||
return fs;
|
||||
}
|
||||
|
||||
int ext2_initialize(void) {
|
||||
|
||||
if (args_present("root")) {
|
||||
ext2_fs_mount(args_value("root"), "/");
|
||||
}
|
||||
vfs_register("ext2", ext2_fs_mount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,37 +0,0 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2014 Kevin Lange
|
||||
*/
|
||||
#include <system.h>
|
||||
#include <module.h>
|
||||
#include <fs.h>
|
||||
#include <printf.h>
|
||||
#include <mod/shell.h>
|
||||
|
||||
extern fs_node_t * ext2_fs_mount(char * device, char * mount_path);
|
||||
|
||||
DEFINE_SHELL_FUNCTION(mount, "Mount an ext2 filesystem") {
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(tty, "Usage: %s device mount_path", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ext2_fs_mount(argv[1], argv[2]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init(void) {
|
||||
BIND_SHELL_FUNCTION(mount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fini(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_DEF(ext2mount, init, fini);
|
||||
MODULE_DEPENDS(debugshell);
|
||||
MODULE_DEPENDS(ext2);
|
@ -419,9 +419,18 @@ fs_node_t * tmpfs_create(char * name) {
|
||||
return tmpfs_from_dir(tmpfs_root);
|
||||
}
|
||||
|
||||
fs_node_t * tmpfs_mount(char * device, char * mount_path) {
|
||||
fs_node_t * fs = tmpfs_create(device);
|
||||
return fs;
|
||||
}
|
||||
|
||||
static int tmpfs_initialize(void) {
|
||||
|
||||
vfs_mount("/tmp", tmpfs_create("tmp"));
|
||||
fs_root = tmpfs_create("/");
|
||||
vfs_mount("/var", tmpfs_create("var"));
|
||||
|
||||
vfs_register("tmpfs", tmpfs_mount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int tmpfs_finalize(void) {
|
||||
|
44
toolchain/patches/newlib/include/syscall_nums.h
Normal file
44
toolchain/patches/newlib/include/syscall_nums.h
Normal file
@ -0,0 +1,44 @@
|
||||
#define SYS_EXT 0
|
||||
#define SYS_OPEN 2
|
||||
#define SYS_READ 3
|
||||
#define SYS_WRITE 4
|
||||
#define SYS_CLOSE 5
|
||||
#define SYS_GETTIMEOFDAY 6
|
||||
#define SYS_EXECVE 7
|
||||
#define SYS_FORK 8
|
||||
#define SYS_GETPID 9
|
||||
#define SYS_SBRK 10
|
||||
#define SYS_UNAME 12
|
||||
#define SYS_OPENPTY 13
|
||||
#define SYS_SEEK 14
|
||||
#define SYS_STAT 15
|
||||
#define SYS_MKPIPE 21
|
||||
#define SYS_DUP2 22
|
||||
#define SYS_GETUID 23
|
||||
#define SYS_SETUID 24
|
||||
#define SYS_REBOOT 26
|
||||
#define SYS_READDIR 27
|
||||
#define SYS_CHDIR 28
|
||||
#define SYS_GETCWD 29
|
||||
#define SYS_CLONE 30
|
||||
#define SYS_SETHOSTNAME 31
|
||||
#define SYS_GETHOSTNAME 32
|
||||
#define SYS_MKDIR 34
|
||||
#define SYS_SHM_OBTAIN 35
|
||||
#define SYS_SHM_RELEASE 36
|
||||
#define SYS_KILL 37
|
||||
#define SYS_SIGNAL 38
|
||||
#define SYS_GETTID 41
|
||||
#define SYS_YIELD 42
|
||||
#define SYS_SYSFUNC 43
|
||||
#define SYS_SLEEPABS 45
|
||||
#define SYS_SLEEP 46
|
||||
#define SYS_IOCTL 47
|
||||
#define SYS_ACCESS 48
|
||||
#define SYS_STATF 49
|
||||
#define SYS_CHMOD 50
|
||||
#define SYS_UMASK 51
|
||||
#define SYS_UNLINK 52
|
||||
#define SYS_WAITPID 53
|
||||
#define SYS_PIPE 54
|
||||
#define SYS_MOUNT 55
|
@ -23,6 +23,8 @@
|
||||
#include "syscall.h"
|
||||
#include <bits/dirent.h>
|
||||
|
||||
#include <syscall_nums.h>
|
||||
|
||||
extern void *malloc(size_t size);
|
||||
extern void free(void *ptr);
|
||||
extern void *calloc(size_t nmemb, size_t size);
|
||||
@ -86,6 +88,7 @@ DEFN_SYSCALL1(umask, 51, mode_t);
|
||||
DEFN_SYSCALL1(unlink, 52, char *);
|
||||
DEFN_SYSCALL3(waitpid, 53, int, int *, int);
|
||||
DEFN_SYSCALL1(pipe, 54, int *);
|
||||
DEFN_SYSCALL5(mount, SYS_MOUNT, char *, char *, char *, unsigned long, void *);
|
||||
|
||||
#define DEBUG_STUB(...) { fprintf(stderr, "\033[1;32mUserspace Debug\033[0m pid%d ", getpid()); fprintf(stderr, __VA_ARGS__); }
|
||||
|
||||
@ -658,3 +661,14 @@ void sync() {
|
||||
DEBUG_STUB("sync();\n");
|
||||
}
|
||||
|
||||
int mount(char * source, char * target, char * type, unsigned long flags, void * data) {
|
||||
int r = syscall_mount(source, target, type, flags, data);
|
||||
|
||||
if (r < 0) {
|
||||
errno = -r;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
28
userspace/core/mount.c
Normal file
28
userspace/core/mount.c
Normal file
@ -0,0 +1,28 @@
|
||||
/* vim: tabstop=4 shiftwidth=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2014 Kevin Lange
|
||||
*
|
||||
* mount
|
||||
*
|
||||
* Mount a filesystem.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Probably should go somewhere */
|
||||
extern int mount(char* src,char* tgt,char* typ,unsigned long,void*);
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Usage: %s type device mountpoint\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mount(argv[2], argv[3], argv[1], 0, NULL) < 0) {
|
||||
perror("mount");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user