expose mounting to userspace

This commit is contained in:
Kevin Lange 2014-06-09 20:13:11 -07:00
parent b59871ca67
commit 17e332b5e7
13 changed files with 186 additions and 98 deletions

View File

@ -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))

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -0,0 +1 @@
../../toolchain/patches/newlib/include/syscall_nums.h

View File

@ -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",

View File

@ -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 (*)());

View File

@ -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}

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View 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

View File

@ -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
View 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;
}