From 1252bdeaf795629ac34161bc59a263e998483247 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Mon, 8 Aug 2022 01:00:48 +0200 Subject: user: separate tmpfs into its own executable, add `mount` --- src/kernel/syscalls.c | 1 + src/user/app/init/driver/tmpfs.c | 132 --------------------------------------- src/user/app/init/init.c | 5 +- src/user/app/shell/shell.c | 12 +++- src/user/app/tmpfs/tmpfs.c | 131 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 136 deletions(-) delete mode 100644 src/user/app/init/driver/tmpfs.c create mode 100644 src/user/app/tmpfs/tmpfs.c (limited to 'src') diff --git a/src/kernel/syscalls.c b/src/kernel/syscalls.c index 07e2e36..5dca49f 100644 --- a/src/kernel/syscalls.c +++ b/src/kernel/syscalls.c @@ -287,6 +287,7 @@ long _syscall_close(handle_t hid) { long _syscall_fs_wait(char __user *buf, long max_len, struct fs_wait_response __user *res) { struct vfs_backend *backend = process_current->controlled; + // TODO can be used to tell if you're init if (!backend) SYSCALL_RETURN(-1); process_transition(process_current, PS_WAITS4REQUEST); diff --git a/src/user/app/init/driver/tmpfs.c b/src/user/app/init/driver/tmpfs.c deleted file mode 100644 index c7abf50..0000000 --- a/src/user/app/init/driver/tmpfs.c +++ /dev/null @@ -1,132 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -struct node { - const char *name; - size_t namelen; - struct node *next; - char *buf; - size_t size, capacity; -}; - -struct node *root = NULL; -static struct node special_root = { - .size = 0, -}; - -static struct node *lookup(const char *path, size_t len) { - for (struct node *iter = root; iter; iter = iter->next) { - if (iter->namelen == len && !memcmp(path, iter->name, len)) - return iter; - } - return NULL; -} - -static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) { - struct node *node; - if (res->len == 0) return NULL; - path++; - res->len--; - - if (res->len == 0) return &special_root; - - // no directory support (yet) - if (memchr(path, '/', res->len)) return NULL; - - node = lookup(path, res->len); - if (!node && (res->flags & OPEN_CREATE)) { - node = malloc(sizeof *node); - memset(node, 0, sizeof *node); - - char *namebuf = malloc(res->len + 1); - memcpy(namebuf, path, res->len); - namebuf[res->len] = '\0'; - node->name = namebuf; - node->namelen = res->len; - node->next = root; - root = node; - } - return node; -} - -void tmpfs_drv(void) { - const size_t buflen = 4096; - char *buf = malloc(buflen); - struct fs_wait_response res; - struct node *ptr; - while (!_syscall_fs_wait(buf, buflen, &res)) { - switch (res.op) { - case VFSOP_OPEN: - ptr = tmpfs_open(buf, &res); - _syscall_fs_respond(ptr, ptr ? 0 : -1, 0); - break; - - case VFSOP_READ: - ptr = (void*)res.id; - if (ptr == &special_root) { - struct dirbuild db; - dir_start(&db, res.offset, buf, buflen); - for (struct node *iter = root; iter; iter = iter->next) - dir_append(&db, iter->name); - _syscall_fs_respond(buf, dir_finish(&db), 0); - } else { - fs_normslice(&res.offset, &res.len, ptr->size, false); - _syscall_fs_respond(ptr->buf + res.offset, res.len, 0); - break; - } - break; - - case VFSOP_WRITE: - ptr = (void*)res.id; - if (ptr == &special_root) { - _syscall_fs_respond(NULL, -1, 0); - break; - } - if (res.len > 0 && !ptr->buf) { - ptr->buf = malloc(256); - if (!ptr->buf) { - _syscall_fs_respond(NULL, -1, 0); - break; - } - memset(ptr->buf, 0, 256); - ptr->capacity = 256; - } - - fs_normslice(&res.offset, &res.len, ptr->size, true); - if (ptr->capacity <= res.offset + res.len) { - size_t newcap = 1; - while (newcap && newcap <= res.offset + res.len) - newcap *= 2; - if (!newcap) { /* overflow */ - _syscall_fs_respond(NULL, -1, 0); - break; - } - ptr->capacity = newcap; - ptr->buf = realloc(ptr->buf, ptr->capacity); - } - - memcpy(ptr->buf + res.offset, buf, res.len); - if ((res.flags & WRITE_TRUNCATE) || ptr->size < res.offset + res.len) { - ptr->size = res.offset + res.len; - } - _syscall_fs_respond(NULL, res.len, 0); - break; - - case VFSOP_GETSIZE: - ptr = (void*)res.id; - _syscall_fs_respond(NULL, ptr->size, 0); - break; - - default: - _syscall_fs_respond(NULL, -1, 0); - break; - } - } - - exit(1); -} diff --git a/src/user/app/init/init.c b/src/user/app/init/init.c index 9e7ab7b..f011ca5 100644 --- a/src/user/app/init/init.c +++ b/src/user/app/init/init.c @@ -29,9 +29,12 @@ int main(void) { freopen("/kdev/com1", "a+", stderr); printf("in init (stage 2), main at 0x%x\n", &main); - MOUNT_AT("/tmp/") { tmpfs_drv(); } MOUNT_AT("/keyboard") { ps2_drv(); } MOUNT_AT("/bin/") { fs_passthru("/init/bin"); } + MOUNT_AT("/tmp/") { + const char *argv[] = {"/bin/tmpfs", NULL}; + execv(argv[0], (void*)argv); + } MOUNT_AT("/vtty") { const char *argv[] = {"/bin/vterm", NULL}; execv(argv[0], (void*)argv); diff --git a/src/user/app/shell/shell.c b/src/user/app/shell/shell.c index 6083578..d96ef4c 100644 --- a/src/user/app/shell/shell.c +++ b/src/user/app/shell/shell.c @@ -37,9 +37,15 @@ void run_args(int argc, char **argv, struct redir *redir) { if (!*argv) return; /* "special" commands that can't be handled in a subprocess */ - if (!strcmp(argv[0], "shadow")) { - // TODO process groups - _syscall_mount(-1, argv[1], strlen(argv[1])); + if (!strcmp(argv[0], "mount")) { + if (argc < 3) { + eprintf("not enough arguments"); + return; + } + MOUNT_AT(argv[1]) { + run_args(argc - 2, argv + 2, redir); + exit(1); + } return; } else if (!strcmp(argv[0], "time")) { uint64_t time = __rdtsc(); diff --git a/src/user/app/tmpfs/tmpfs.c b/src/user/app/tmpfs/tmpfs.c new file mode 100644 index 0000000..88a9fac --- /dev/null +++ b/src/user/app/tmpfs/tmpfs.c @@ -0,0 +1,131 @@ +#include +#include +#include +#include +#include +#include +#include + +struct node { + const char *name; + size_t namelen; + struct node *next; + char *buf; + size_t size, capacity; +}; + +struct node *root = NULL; +static struct node special_root = { + .size = 0, +}; + +static struct node *lookup(const char *path, size_t len) { + for (struct node *iter = root; iter; iter = iter->next) { + if (iter->namelen == len && !memcmp(path, iter->name, len)) + return iter; + } + return NULL; +} + +static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) { + struct node *node; + if (res->len == 0) return NULL; + path++; + res->len--; + + if (res->len == 0) return &special_root; + + // no directory support (yet) + if (memchr(path, '/', res->len)) return NULL; + + node = lookup(path, res->len); + if (!node && (res->flags & OPEN_CREATE)) { + node = malloc(sizeof *node); + memset(node, 0, sizeof *node); + + char *namebuf = malloc(res->len + 1); + memcpy(namebuf, path, res->len); + namebuf[res->len] = '\0'; + node->name = namebuf; + node->namelen = res->len; + node->next = root; + root = node; + } + return node; +} + +int main(void) { + const size_t buflen = 4096; + char *buf = malloc(buflen); + struct fs_wait_response res; + struct node *ptr; + while (!_syscall_fs_wait(buf, buflen, &res)) { + switch (res.op) { + case VFSOP_OPEN: + ptr = tmpfs_open(buf, &res); + _syscall_fs_respond(ptr, ptr ? 0 : -1, 0); + break; + + case VFSOP_READ: + ptr = (void*)res.id; + if (ptr == &special_root) { + struct dirbuild db; + dir_start(&db, res.offset, buf, buflen); + for (struct node *iter = root; iter; iter = iter->next) + dir_append(&db, iter->name); + _syscall_fs_respond(buf, dir_finish(&db), 0); + } else { + fs_normslice(&res.offset, &res.len, ptr->size, false); + _syscall_fs_respond(ptr->buf + res.offset, res.len, 0); + break; + } + break; + + case VFSOP_WRITE: + ptr = (void*)res.id; + if (ptr == &special_root) { + _syscall_fs_respond(NULL, -1, 0); + break; + } + if (res.len > 0 && !ptr->buf) { + ptr->buf = malloc(256); + if (!ptr->buf) { + _syscall_fs_respond(NULL, -1, 0); + break; + } + memset(ptr->buf, 0, 256); + ptr->capacity = 256; + } + + fs_normslice(&res.offset, &res.len, ptr->size, true); + if (ptr->capacity <= res.offset + res.len) { + size_t newcap = 1; + while (newcap && newcap <= res.offset + res.len) + newcap *= 2; + if (!newcap) { /* overflow */ + _syscall_fs_respond(NULL, -1, 0); + break; + } + ptr->capacity = newcap; + ptr->buf = realloc(ptr->buf, ptr->capacity); + } + + memcpy(ptr->buf + res.offset, buf, res.len); + if ((res.flags & WRITE_TRUNCATE) || ptr->size < res.offset + res.len) { + ptr->size = res.offset + res.len; + } + _syscall_fs_respond(NULL, res.len, 0); + break; + + case VFSOP_GETSIZE: + ptr = (void*)res.id; + _syscall_fs_respond(NULL, ptr->size, 0); + break; + + default: + _syscall_fs_respond(NULL, -1, 0); + break; + } + } + return 1; +} -- cgit v1.2.3