Add procfs

This commit is contained in:
Mark
2020-07-12 17:10:51 +03:00
parent fd0ec4150f
commit f79fc98967
7 changed files with 141 additions and 43 deletions
+1
View File
@@ -30,6 +30,7 @@ struct vnode *vnode_create(enum vnode_type t, const char *name) {
void vnode_destroy(struct vnode *vn) {
_assert(vnode_cache);
_assert(!vn->open_count);
slab_free(vnode_cache, vn);
}
+28 -28
View File
@@ -146,7 +146,6 @@ static int sysfs_vnode_stat(struct vnode *node, struct stat *st) {
////
int sysfs_config_getter(void *ctx, char *buf, size_t lim) {
sysfs_buf_puts(buf, lim, ctx);
sysfs_buf_puts(buf, lim, "\n");
@@ -159,6 +158,33 @@ int sysfs_config_int64_getter(void *ctx, char *buf, size_t lim) {
return 0;
}
int sysfs_del_ent(struct vnode *ent) {
_assert(ent);
_assert(ent->parent);
vnode_detach(ent);
switch (ent->type) {
case VN_LNK:
break;
case VN_REG:
_assert(ent->op == &g_sysfs_vnode_ops);
_assert(ent->fs_data);
kfree(ent->fs_data);
break;
case VN_DIR:
while (ent->first_child) {
sysfs_del_ent(ent->first_child);
}
break;
default:
panic("Unsupported sysfs node type\n");
break;
}
vnode_destroy(ent);
return 0;
}
int sysfs_add_dir(struct vnode *at, const char *name, struct vnode **res) {
struct vnode *tmp;
sysfs_ensure_root();
@@ -172,7 +198,7 @@ int sysfs_add_dir(struct vnode *at, const char *name, struct vnode **res) {
kdebug("Can't find %s in %s, creating\n", name, at->name);
tmp = vnode_create(VN_DIR, name);
tmp->flags |= VN_MEMORY;
tmp->op = &g_sysfs_vnode_ops;
//tmp->op = &g_sysfs_vnode_ops;
tmp->mode = S_IXUSR | S_IXGRP | S_IXOTH |
S_IRUSR | S_IRGRP | S_IROTH;
@@ -218,28 +244,6 @@ int sysfs_add_config_endpoint(struct vnode *at, const char *name, mode_t mode, s
return 0;
}
// TODO: move this to an appropriate place
#define PROC_PROP_PID 1
#define PROC_PROP_NAME 2
static int proc_property_getter(void *ctx, char *buf, size_t lim) {
uint64_t prop = (uint64_t) ctx;
struct process *proc = thread_self->proc;
_assert(proc);
switch (prop) {
case PROC_PROP_PID:
sysfs_buf_printf(buf, lim, "%d\n", (int) proc->pid);
break;
case PROC_PROP_NAME:
sysfs_buf_puts(buf, lim, proc->name);
sysfs_buf_puts(buf, lim, "\n");
break;
}
return 0;
}
static int system_uptime_getter(void *ctx, char *buf, size_t lim) {
char *p = buf;
uint64_t t = system_time / 1000000000ULL;
@@ -295,10 +299,6 @@ void sysfs_populate(void) {
sysfs_add_config_endpoint(dir, "uptime", SYSFS_MODE_DEFAULT, 32, NULL, system_uptime_getter, NULL);
sysfs_add_config_endpoint(dir, "modules", SYSFS_MODE_DEFAULT, 512, NULL, mod_list, NULL);
sysfs_add_dir(NULL, "self", &dir);
sysfs_add_config_endpoint(dir, "pid", SYSFS_MODE_DEFAULT, 16, (void *) PROC_PROP_PID, proc_property_getter, NULL);
sysfs_add_config_endpoint(dir, "name", SYSFS_MODE_DEFAULT, 128, (void *) PROC_PROP_NAME, proc_property_getter, NULL);
sysfs_add_config_endpoint(NULL, "mem", SYSFS_MODE_DEFAULT, 512, NULL, system_mem_getter, NULL);
}
+2
View File
@@ -36,6 +36,8 @@ int sysfs_config_getter(void *ctx, char *buf, size_t lim);
// ctx: a pointer to an (u)int64_t value
int sysfs_config_int64_getter(void *ctx, char *buf, size_t lim);
int sysfs_del_ent(struct vnode *dir);
int sysfs_add_dir(struct vnode *at, const char *path, struct vnode **result);
int sysfs_add_config_endpoint(struct vnode *at, const char *name, mode_t mode, size_t bufsz, void *ctx, cfg_read_func_t read, cfg_write_func_t write);
void sysfs_populate(void);
+5 -1
View File
@@ -87,6 +87,9 @@ struct process {
// Signal
uint64_t sigq;
// procfs
struct vnode *fs_entry;
// State
char name[256];
uint32_t flags;
@@ -113,7 +116,8 @@ struct thread *process_first_thread(struct process *proc);
#define THR_INIT_STACK_SET (1 << 1)
int thread_init(struct thread *thr, uintptr_t entry, void *arg, int flags);
void thread_dump(struct thread *thr);
//void thread_cleanup(struct thread *thr);
void proc_add_entry(struct process *proc);
struct process *process_child(struct process *of, pid_t pid);
void process_unchild(struct process *proc);
+6
View File
@@ -131,6 +131,7 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
uintptr_t entry;
size_t argc;
int res;
int was_kernel = 0;
if ((res = vfs_stat(&proc->ioctx, path, &st)) != 0) {
kerror("execve(%s): %s\n", path, kstrerror(res));
@@ -205,6 +206,7 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
}
if (proc->space == mm_kernel) {
was_kernel = 1;
// Have to allocate a new PID for kernel -> userspace transition
proc->pid = process_alloc_pid(1); //thread_alloc_pid(1);
proc->pgid = proc->pid;
@@ -281,6 +283,10 @@ int sys_execve(const char *path, const char **argv, const char **envp) {
thr->data.rsp3_base = ustack;
thr->data.rsp3_size = 4 * MM_PAGE_SIZE;
if (was_kernel) {
proc_add_entry(proc);
}
// Up to 4095 argc and envc
_assert(procv_vecp[0] < 4096);
_assert(procv_vecp[2] < 4096);
+89 -8
View File
@@ -5,6 +5,7 @@
#include "sys/binfmt_elf.h"
#include "sys/sys_proc.h"
#include "sys/mem/phys.h"
#include "sys/snprintf.h"
#include "user/signum.h"
#include "user/errno.h"
#include "user/fcntl.h"
@@ -13,6 +14,7 @@
#include "sys/thread.h"
#include "sys/sched.h"
#include "sys/debug.h"
#include "fs/sysfs.h"
#include "fs/ofile.h"
#include "sys/heap.h"
@@ -37,6 +39,60 @@ static pid_t last_kernel_pid = 0;
static pid_t last_user_pid = 0;
// TODO: MAKE THIS PER-PROCESSOR
static uint64_t fxsave_buf[FXSAVE_REGION / 8] __attribute__((aligned(16)));
static struct vnode *g_sysfs_proc_dir;
static int sysfs_proc_name(void *ctx, char *buf, size_t lim) {
sysfs_buf_printf(buf, lim, "%s\n", ((struct process *) ctx)->name);
return 0;
}
static int sysfs_proc_ioctx(void *ctx, char *buf, size_t lim) {
struct process *proc = ctx;
sysfs_buf_printf(buf, lim, "%d:%d\n", proc->ioctx.uid, proc->ioctx.gid);
return 0;
}
static struct vnode *sysfs_proc_self(struct thread *ctx, struct vnode *link) {
_assert(ctx && ctx->proc);
return ctx->proc->fs_entry;
}
static void proc_ensure_dir(void) {
if (!g_sysfs_proc_dir) {
_assert(sysfs_add_dir(NULL, "proc", &g_sysfs_proc_dir) == 0);
struct vnode *vn = vnode_create(VN_LNK, "self");
vn->flags = VN_MEMORY | VN_PER_PROCESS;
vn->target_func = sysfs_proc_self;
vnode_attach(g_sysfs_proc_dir, vn);
}
}
void proc_add_entry(struct process *proc) {
char name[16];
_assert(proc && !(proc->flags & THREAD_KERNEL));
_assert(proc->pid > 0);
proc_ensure_dir();
kdebug("BEGIN ADD ENTRY %d\n", proc->pid);
snprintf(name, sizeof(name), "%d", proc->pid);
_assert(sysfs_add_dir(g_sysfs_proc_dir, name, &proc->fs_entry) == 0);
_assert(sysfs_add_config_endpoint(proc->fs_entry, "name", SYSFS_MODE_DEFAULT, 64,
proc, sysfs_proc_name, NULL) == 0);
_assert(sysfs_add_config_endpoint(proc->fs_entry, "ioctx", SYSFS_MODE_DEFAULT, 64,
proc, sysfs_proc_ioctx, NULL) == 0);
kdebug("END ADD ENTRY %d\n", proc->pid);
}
void proc_del_entry(struct process *proc) {
_assert(proc && !(proc->flags & THREAD_KERNEL));
_assert(proc->pid > 0);
kdebug("BEGIN DEL ENTRY %d\n", proc->pid);
sysfs_del_ent(proc->fs_entry);
kdebug("END DEL ENTRY %d\n", proc->pid);
}
void context_save_fpu(struct thread *new, struct thread *old) {
_assert(old);
@@ -45,7 +101,6 @@ void context_save_fpu(struct thread *new, struct thread *old) {
memcpy(old->data.fxsave, fxsave_buf, FXSAVE_REGION);
old->flags |= THREAD_FPU_SAVED;
}
}
void context_restore_fpu(struct thread *new, struct thread *old) {
@@ -86,8 +141,6 @@ void process_ioctx_fork(struct process *dst, struct process *src) {
}
}
int process_signal_pgid(pid_t pgid, int signum) {
int ret = 0;
@@ -99,7 +152,18 @@ int process_signal_pgid(pid_t pgid, int signum) {
}
}
return ret == 0 ? -1 : ret;
return ret == 0 ? -ECHILD : ret;
}
int process_signal_children(struct process *proc, int signum) {
int ret = 0;
for (struct process *chld = proc->first_child; chld; chld = chld->next_child) {
if (proc->proc_state != PROC_FINISHED) {
process_signal(chld, signum);
++ret;
}
}
return ret == 0 ? -ECHILD : 0;
}
struct process *process_find(pid_t pid) {
@@ -156,6 +220,8 @@ void process_unchild(struct process *proc) {
void process_cleanup(struct process *proc) {
// Leave only the system context required for hierachy tracking and error code/pid
proc_del_entry(proc);
_assert(proc->proc_state == PROC_FINISHED);
_assert(proc->thread_count == 1);
proc->flags |= PROC_EMPTY;
@@ -176,6 +242,13 @@ void process_free(struct process *proc) {
// only main remains
_assert(proc->thread_count == 1);
// Reparent children to #1 if any
for (struct process *chld = proc->first_child; chld; chld = chld->next_child) {
panic("Not implemented: #%d (%s) has children: #%d (%s)\n",
proc->pid, proc->name,
chld->pid, chld->name);
}
// Sure that no code of this thread will be running anymore -
// can clean up its stuff
process_cleanup(proc);
@@ -248,6 +321,9 @@ int process_init_thread(struct process *proc, uintptr_t entry, void *arg, int us
proc->proc_state = PROC_ACTIVE;
list_add(&proc->g_link, &proc_all_head);
if (user) {
proc_add_entry(proc);
}
return 0;
}
@@ -441,6 +517,10 @@ int sys_fork(struct sys_fork_frame *frame) {
struct process *src = src_thread->proc;
_assert(src);
if (src->flags & THREAD_KERNEL) {
panic("XXX: kthread fork()ing not implemented\n");
}
if (src->thread_count != 1) {
panic("XXX: fork() a multithreaded process\n");
}
@@ -567,6 +647,7 @@ int sys_fork(struct sys_fork_frame *frame) {
dst_thread->data.rsp0 = (uintptr_t) stack;
list_add(&dst->g_link, &proc_all_head);
proc_add_entry(dst);
sched_queue(dst_thread);
return dst->pid;
@@ -739,10 +820,10 @@ int sys_kill(pid_t pid, int signum) {
} else if (pid == 0) {
proc = thread_self->proc;
} else if (pid < -1) {
// TODO: check if there's any process in that group
process_signal_pgid(-pid, signum);
return 0;
return process_signal_pgid(-pid, signum);
} else if (pid == -1) {
proc = thread_self->proc;
return process_signal_children(proc, signum);
} else {
panic("Not implemented\n");
}
+10 -6
View File
@@ -144,7 +144,7 @@ static int wait_check_pid(struct process *chld, int flags) {
static int wait_check_pgrp(struct process *proc_self, pid_t pgrp, int flags, struct process **chld) {
for (struct process *_chld = proc_self->first_child; _chld; _chld = _chld->next_child) {
if (_chld->pgid == pgrp) {
if (pgrp == -1 || _chld->pgid == -pgrp) {
if (wait_check_pid(_chld, flags) == 0) {
*chld = _chld;
return 0;
@@ -155,6 +155,7 @@ static int wait_check_pgrp(struct process *proc_self, pid_t pgrp, int flags, str
}
int sys_waitpid(pid_t pid, int *status, int flags) {
pid_t result_pid = -ECHILD;
struct thread *thr = thread_self;
_assert(thr);
struct process *proc_self = thr->proc;
@@ -180,7 +181,7 @@ int sys_waitpid(pid_t pid, int *status, int flags) {
if (!any_proc) {
return -ECHILD;
}
} else {
} else if (pid != -1) {
panic("Not implemented: waitpid(%d, ...)\n", pid);
}
@@ -191,16 +192,16 @@ int sys_waitpid(pid_t pid, int *status, int flags) {
}
res = thread_wait_io(thr, &chld->pid_notify);
} else if (pid < -1) {
} else if (pid <= -1) {
// Check if anybody in pgrp has changed status
if (wait_check_pgrp(proc_self, -pid, flags, &chld) == 0) {
if (wait_check_pgrp(proc_self, pid, flags, &chld) == 0) {
_assert(chld);
break;
}
// Build wait list
for (struct process *_chld = proc_self->first_child; _chld; _chld = _chld->next_child) {
if (_chld->pgid == -pid) {
if (pid == -1 || _chld->pgid == -pid) {
thread_wait_io_add(thr, &_chld->pid_notify);
}
}
@@ -209,6 +210,8 @@ int sys_waitpid(pid_t pid, int *status, int flags) {
res = thread_wait_io_any(thr, &notify);
thread_wait_io_clear(thr);
} else {
panic("Shouldn't run\n");
}
if (res < 0) {
@@ -217,6 +220,7 @@ int sys_waitpid(pid_t pid, int *status, int flags) {
}
}
result_pid = chld->pid;
if (chld->proc_state == PROC_FINISHED) {
if (status) {
*status = chld->exit_status;
@@ -234,5 +238,5 @@ int sys_waitpid(pid_t pid, int *status, int flags) {
}
}
return 0;
return result_pid;
}