From ca0a318048749d21facd135322c44c78f2d5f1ac Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 24 Feb 2015 22:17:10 +0100 Subject: Implement fs_subfs (it's simple, really) ; add placeholders for more syscalls --- src/common/include/fs.h | 4 +- src/common/include/syscallproto.h | 60 +++++++++++++++++++++++++---- src/kernel/include/vfs.h | 5 ++- src/kernel/user/nullfs.c | 2 +- src/kernel/user/syscall.c | 79 +++++++++++++++++++++++++++++++++++++++ src/kernel/user/vfs.c | 39 ++++++++++++++++++- src/lib/include/syscall.h | 16 +++++++- src/lib/libkogata/syscall.c | 73 ++++++++++++++++++++++++++++++++++++ 8 files changed, 265 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/common/include/fs.h b/src/common/include/fs.h index b238c03..880202b 100644 --- a/src/common/include/fs.h +++ b/src/common/include/fs.h @@ -24,7 +24,9 @@ #define FM_BLOCKING (0x200) #define FM_DCREATE (0x1000) // create file in directory #define FM_DMOVE (0x2000) // move file from directory -#define FM_DUNLINK (0x4000) // delete file from directory +#define FM_DDELETE (0x4000) // delete file from directory + +#define FM_ALL_MODES (0xFFFF) typedef struct { int type; diff --git a/src/common/include/syscallproto.h b/src/common/include/syscallproto.h index 6f0418e..507bc2b 100644 --- a/src/common/include/syscallproto.h +++ b/src/common/include/syscallproto.h @@ -27,16 +27,60 @@ #define SC_IOCTL 36 // args: fd, command, out void* data #define SC_GET_MODE 37 // args: fd -- get mode for open file handle -#define SC_MAKE_FS 40 -#define SC_FS_ADD_SRC 41 -#define SC_RM_FS 42 +#define SC_MAKE_FS 40 // args: sc_make_fs_args_t +#define SC_FS_ADD_SRC 41 // args: fs_name, fs_name_strlen, fd, opts, opts_strlen +#define SC_SUBFS 42 // args: sc_subfs_args_t +#define SC_RM_FS 43 // args: fs_name, fs_name_strlen +// TODO : how do we enumerate filesystems ? -#define SC_NEW_PROC 50 -#define SC_BIND_FS 51 // bind FS to child process -#define SC_BIND_FD 52 // copy a file descriptor to child process -#define SC_PROC_EXEC 53 // execute binary in process +#define SC_NEW_PROC 50 // args: nothing ? +#define SC_BIND_FS 51 // args: pid, new_name, new_name_strlen, fs_name, fs_name_strlen -- bind FS to child process +#define SC_BIND_SUBFS 52 // args: sc_subfs_args_t -- subfs & bind to child process +#define SC_BIND_FD 53 // args: pid, new_fd, local_fd -- copy a file descriptor to child process +#define SC_PROC_EXEC 55 // args: pid, exec_name, exec_name_strlen -- execute binary in process +#define SC_PROC_STATUS 56 // args: pid, proc_status_t* +#define SC_PROC_KILL 57 // args: pid, proc_status_t* -- inconditionnally kill child process +#define SC_PROC_WAIT 58 // args: pid, proc_status_t* +#define SC_PROC_WAIT_ANY 59 // args: proc_status_t* -// much more to do +typedef struct { + const char* driver; + size_t driver_strlen; + + const char* fs_name; + size_t fs_name_strlen; + + int source_fd; + + const char* opts; + size_t opts_strlen; +} sc_make_fs_args_t; + +typedef struct { + const char* new_name; + size_t new_name_strlen; + + const char* from_fs; + size_t from_fs_strlen; + + const char* root; + size_t root_strlen; + + int ok_modes; + + int bind_to_pid; // used only for SC_BIND_SUBFS +} sc_subfs_args_t; + +#define PS_LOADING 1 +#define PS_RUNNING 2 +#define PS_DONE 3 +#define PS_FAILURE 4 // exception or segfault or stuff +#define PS_KILLED 5 +typedef struct { + int pid; + int state; // one of PS_* + int return_code; // an error code if state == PS_FAILURE +} proc_status_t; /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/kernel/include/vfs.h b/src/kernel/include/vfs.h index 0890663..066211b 100644 --- a/src/kernel/include/vfs.h +++ b/src/kernel/include/vfs.h @@ -124,7 +124,9 @@ typedef struct { typedef struct fs { // Filled by VFS's make_fs() int refs; - // Filled by FS's specific make() + struct fs *from_fs; + int ok_modes; + // Filled by FS's specific make() - all zero in the case of a subfs fs_ops_t *ops; fs_ptr data; // Filled by both according to what is specified for fs_node_t @@ -158,6 +160,7 @@ fs_node_t* fs_walk_path_except_last(fs_node_t* from, const char *p, char* last_f void register_fs_driver(const char* name, fs_driver_ops_t *ops); fs_t* make_fs(const char* driver, fs_handle_t *source, const char* opts); +fs_t* fs_subfs(fs_t *fs, const char *root, int ok_modes); bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts); void ref_fs(fs_t *fs); void unref_fs(fs_t *fs); diff --git a/src/kernel/user/nullfs.c b/src/kernel/user/nullfs.c index a44e4b3..534b0ba 100644 --- a/src/kernel/user/nullfs.c +++ b/src/kernel/user/nullfs.c @@ -294,7 +294,7 @@ bool nullfs_d_stat(fs_node_ptr n, stat_t *st) { st->access = FM_READDIR | (d->fs->can_create ? FM_DCREATE : 0) | (d->fs->can_move ? FM_DMOVE : 0) - | (d->fs->can_delete ? FM_DUNLINK : 0); + | (d->fs->can_delete ? FM_DDELETE : 0); st->size = 0; for (nullfs_item_t *i = d->items_list; i != 0; i = i->next) diff --git a/src/kernel/user/syscall.c b/src/kernel/user/syscall.c index bcf6ef4..3def3b5 100644 --- a/src/kernel/user/syscall.c +++ b/src/kernel/user/syscall.c @@ -29,6 +29,7 @@ static char* sc_copy_string(uint32_t s, uint32_t slen) { // THE SYSCALLS CODE !! // // ==================== // +// ---- Related to the current process's execution static uint32_t exit_sc(sc_args_t args) { dbg_printf("Proc %d exit with code %d\n", current_process()->pid, args.a); @@ -58,6 +59,8 @@ static uint32_t dbg_print_sc(sc_args_t args) { return 0; } +// ---- Memory management related + static uint32_t mmap_sc(sc_args_t args) { return mmap(current_process(), (void*)args.a, args.b, args.c); } @@ -78,6 +81,8 @@ static uint32_t munmap_sc(sc_args_t args) { return munmap(current_process(), (void*)args.a); } +// ---- Accessing the VFS - filesystems + static uint32_t create_sc(sc_args_t args) { bool ret = false; @@ -175,6 +180,8 @@ end_stat: return ret; } +// ---- Accessing the VFS - files + static uint32_t open_sc(sc_args_t args) { int ret = 0; @@ -260,6 +267,62 @@ static uint32_t get_mode_sc(sc_args_t args) { return file_get_mode(h); } +// ---- Managing file systems + +static uint32_t make_fs_sc(sc_args_t args) { + return -1; // TODO +} + +static uint32_t fs_add_src_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t fs_subfs_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t rm_fs_sc(sc_args_t args) { + return -1; //TODO +} + +// ---- Spawning new processes & giving them ressources + +static uint32_t new_proc_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t bind_fs_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t bind_subfs_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t bind_fd_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t proc_exec_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t proc_status_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t proc_kill_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t proc_wait_sc(sc_args_t args) { + return -1; //TODO +} + +static uint32_t proc_wait_any_sc(sc_args_t args) { + return -1; //TODO +} + // ====================== // // SYSCALLS SETUP ROUTINE // // ====================== // @@ -288,6 +351,21 @@ void setup_syscall_table() { sc_handlers[SC_STAT_OPEN] = stat_open_sc; sc_handlers[SC_IOCTL] = ioctl_sc; sc_handlers[SC_GET_MODE] = get_mode_sc; + + sc_handlers[SC_MAKE_FS] = make_fs_sc; + sc_handlers[SC_FS_ADD_SRC] = fs_add_src_sc; + sc_handlers[SC_SUBFS] = fs_subfs_sc; + sc_handlers[SC_RM_FS] = rm_fs_sc; + + sc_handlers[SC_NEW_PROC] = new_proc_sc; + sc_handlers[SC_BIND_FS] = bind_fs_sc; + sc_handlers[SC_BIND_SUBFS] = bind_subfs_sc; + sc_handlers[SC_BIND_FD] = bind_fd_sc; + sc_handlers[SC_PROC_EXEC] = proc_exec_sc; + sc_handlers[SC_PROC_STATUS] = proc_status_sc; + sc_handlers[SC_PROC_KILL] = proc_kill_sc; + sc_handlers[SC_PROC_WAIT] = proc_wait_sc; + sc_handlers[SC_PROC_WAIT_ANY] = proc_wait_any_sc; } void syscall_handler(registers_t *regs) { @@ -304,6 +382,7 @@ void syscall_handler(registers_t *regs) { .e = regs->edi}; regs->eax = h(args); } else { + dbg_printf("Unimplemented syscall %d\n", regs->eax); regs->eax = -1; } } diff --git a/src/kernel/user/vfs.c b/src/kernel/user/vfs.c index 1c841f7..15f37cc 100644 --- a/src/kernel/user/vfs.c +++ b/src/kernel/user/vfs.c @@ -6,6 +6,11 @@ // FILESYSTEM DRIVER REGISTERING // // ============================= // +static fs_ops_t no_fs_ops = { + .shutdown = 0, + .add_source = 0, +}; + typedef struct fs_driver { const char* name; fs_driver_ops_t *ops; @@ -37,6 +42,8 @@ fs_t *make_fs(const char* drv_name, fs_handle_t *source, const char* opts) { if (fs->root == 0) goto fail; fs->refs = 1; + fs->from_fs = 0; + fs->ok_modes = FM_ALL_MODES; fs->root->refs = 1; fs->root->fs = fs; fs->root->parent = 0; @@ -60,6 +67,27 @@ fail: return 0; } +fs_t *fs_subfs(fs_t *fs, const char* root, int ok_modes) { + fs_node_t* new_root = fs_walk_path(fs->root, root); + if (new_root == 0) return 0; + + fs_t *subfs = (fs_t*)malloc(sizeof(fs_t)); + if (subfs == 0) return 0; + + subfs->refs = 1; + subfs->from_fs = fs; + subfs->ok_modes = ok_modes & fs->ok_modes; + + subfs->ops = &no_fs_ops; + subfs->data = 0; + + subfs->root = new_root; + + ref_fs(fs); + + return subfs; +} + bool fs_add_source(fs_t *fs, fs_handle_t *source, const char* opts) { return fs->ops->add_source && fs->ops->add_source(fs->data, source, opts); } @@ -72,7 +100,8 @@ void unref_fs(fs_t *fs) { fs->refs--; if (fs->refs == 0) { unref_fs_node(fs->root); - fs->ops->shutdown(fs->data); + if (fs->ops->shutdown) fs->ops->shutdown(fs->data); + if (fs->from_fs) unref_fs(fs->from_fs); free(fs); } } @@ -260,6 +289,8 @@ fs_node_t* fs_walk_path_except_last(fs_node_t* from, const char* path, char* las // DOING THINGS IN FILESYSTEMS // bool fs_create(fs_t *fs, const char* file, int type) { + if (!(fs->ok_modes & FM_DCREATE)) return false; + char name[DIR_MAX]; fs_node_t *n = fs_walk_path_except_last(fs->root, file, name); if (n == 0) return false; @@ -273,6 +304,8 @@ bool fs_create(fs_t *fs, const char* file, int type) { } bool fs_delete(fs_t *fs, const char* file) { + if (!(fs->ok_modes & FM_DDELETE)) return false; + char name[DIR_MAX]; fs_node_t* n = fs_walk_path_except_last(fs->root, file, name); @@ -292,6 +325,8 @@ bool fs_delete(fs_t *fs, const char* file) { } bool fs_move(fs_t *fs, const char* from, const char* to) { + if (!(fs->ok_modes & FM_DMOVE)) return false; + char old_name[DIR_MAX]; fs_node_t *old_parent = fs_walk_path_except_last(fs->root, from, old_name); if (old_parent == 0) return false; @@ -369,6 +404,8 @@ bool fs_stat(fs_t *fs, const char* file, stat_t *st) { // =================== // fs_handle_t* fs_open(fs_t *fs, const char* file, int mode) { + if (mode & ~fs->ok_modes) return 0; + fs_node_t *n = fs_walk_path(fs->root, file); if (n == 0 && (mode & FM_CREATE)) { if (fs_create(fs, file, FT_REGULAR)) { diff --git a/src/lib/include/syscall.h b/src/lib/include/syscall.h index 991b081..246c84c 100644 --- a/src/lib/include/syscall.h +++ b/src/lib/include/syscall.h @@ -11,6 +11,7 @@ #include typedef int fd_t; +typedef int pid_t; void dbg_print(const char* str); void yield(); @@ -36,6 +37,19 @@ bool stat_open(fd_t file, stat_t *s); int ioctl(fd_t file, int command, void* data); int get_mode(fd_t file); -// more todo +bool make_fs(const char* name, const char* driver, fd_t source, const char* options); +bool fs_add_source(const char* fs, fd_t source, const char* options); +bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes); +void fs_remove(const char* name); + +pid_t new_proc(); +bool bind_fs(pid_t pid, const char* new_name, const char* fs); +bool bind_subfs(pid_t pid, const char* new_name, const char* fs, const char* root, int ok_modes); +bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd); +bool proc_exec(pid_t pid, const char* file); +bool proc_status(pid_t pid, proc_status_t *s); +bool proc_kill(pid_t pid, proc_status_t *s); +void proc_wait(pid_t pid, proc_status_t *s); +void proc_wait_any(proc_status_t *s); /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/lib/libkogata/syscall.c b/src/lib/libkogata/syscall.c index 52e320c..88e9aa2 100644 --- a/src/lib/libkogata/syscall.c +++ b/src/lib/libkogata/syscall.c @@ -90,4 +90,77 @@ int get_mode(fd_t file) { return call(SC_GET_MODE, file, 0, 0, 0, 0); } +bool make_fs(const char* name, const char* driver, fd_t source, const char* options) { + sc_make_fs_args_t args = { + .driver = driver, + .driver_strlen = strlen(driver), + .fs_name = name, + .fs_name_strlen = strlen(name), + .source_fd = source, + .opts = options, + .opts_strlen = strlen(options), + }; + return call(SC_MAKE_FS, (uint32_t)&args, 0, 0, 0, 0); +} +bool fs_add_source(const char* fs, fd_t source, const char* options) { + return call(SC_FS_ADD_SRC, (uint32_t)fs, strlen(fs), source, (uint32_t)options, strlen(options)); +} +bool fs_subfs(const char* name, const char* orig_fs, const char* root, int ok_modes) { + sc_subfs_args_t args = { + .new_name = name, + .new_name_strlen = strlen(name), + .from_fs = orig_fs, + .from_fs_strlen = strlen(orig_fs), + .root = root, + .root_strlen = strlen(root), + .ok_modes = ok_modes, + .bind_to_pid = 0 + }; + return call(SC_SUBFS, (uint32_t)&args, 0, 0, 0, 0); +} +void fs_remove(const char* name) { + call(SC_RM_FS, (uint32_t)name, strlen(name), 0, 0, 0); +} + +pid_t new_proc() { + return call(SC_NEW_PROC, 0, 0, 0, 0, 0); +} +bool bind_fs(pid_t pid, const char* new_name, const char* fs) { + return call(SC_BIND_FS, pid, (uint32_t)new_name, strlen(new_name), (uint32_t)fs, strlen(fs)); +} +bool bind_subfs(pid_t pid, const char* new_name, const char* orig_fs, const char* root, int ok_modes) { + sc_subfs_args_t args = { + .new_name = new_name, + .new_name_strlen = strlen(new_name), + .from_fs = orig_fs, + .from_fs_strlen = strlen(orig_fs), + .root = root, + .root_strlen = strlen(root), + .ok_modes = ok_modes, + .bind_to_pid = pid + }; + return call(SC_BIND_SUBFS, (uint32_t)&args, 0, 0, 0, 0); +} +bool bind_fd(pid_t pid, fd_t new_fd, fd_t fd) { + return call(SC_BIND_FD, new_fd, fd, 0, 0, 0); +} +bool proc_exec(pid_t pid, const char* file) { + return call(SC_PROC_EXEC, pid, (uint32_t)file, strlen(file), 0, 0); +} +bool proc_status(pid_t pid, proc_status_t *s) { + return call(SC_PROC_STATUS, pid, (uint32_t)s, 0, 0, 0); +} +bool proc_kill(pid_t pid, proc_status_t *s) { + return call(SC_PROC_KILL, pid, (uint32_t)s, 0, 0, 0); +} +void proc_wait(pid_t pid, proc_status_t *s) { + call(SC_PROC_WAIT, pid, (uint32_t)s, 0, 0, 0); +} +void proc_wait_any(proc_status_t *s) { + call(SC_PROC_WAIT_ANY, (uint32_t)s, 0, 0, 0, 0); +} + + + + /* vim: set ts=4 sw=4 tw=0 noet :*/ -- cgit v1.2.3