aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 22:17:10 +0100
committerAlex Auvolat <alex.auvolat@ens.fr>2015-02-24 22:17:10 +0100
commitca0a318048749d21facd135322c44c78f2d5f1ac (patch)
tree3ebd06132c5b89dea513f456225941a2cf8da16a /src
parent858f78702424e4c0eb59bf7678e84f7b3a65fde2 (diff)
downloadkogata-ca0a318048749d21facd135322c44c78f2d5f1ac.tar.gz
kogata-ca0a318048749d21facd135322c44c78f2d5f1ac.zip
Implement fs_subfs (it's simple, really) ; add placeholders for more syscalls
Diffstat (limited to 'src')
-rw-r--r--src/common/include/fs.h4
-rw-r--r--src/common/include/syscallproto.h60
-rw-r--r--src/kernel/include/vfs.h5
-rw-r--r--src/kernel/user/nullfs.c2
-rw-r--r--src/kernel/user/syscall.c79
-rw-r--r--src/kernel/user/vfs.c39
-rw-r--r--src/lib/include/syscall.h16
-rw-r--r--src/lib/libkogata/syscall.c73
8 files changed, 265 insertions, 13 deletions
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 <debug.h>
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 :*/