ish/kernel/init.c
2020-10-11 19:36:01 -07:00

170 lines
4.9 KiB
C

#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include "fs/devices.h"
#include "fs/fd.h"
#include "fs/real.h"
#include "fs/tty.h"
#include "kernel/calls.h"
#include "kernel/init.h"
#include "kernel/personality.h"
int mount_root(const struct fs_ops *fs, const char *source) {
char source_realpath[MAX_PATH + 1];
if (realpath(source, source_realpath) == NULL)
return errno_map();
int err = do_mount(fs, source_realpath, "", "", 0);
if (err < 0)
return err;
return 0;
}
static void establish_signal_handlers() {
extern void sigusr1_handler(int sig);
struct sigaction sigact;
sigact.sa_handler = sigusr1_handler;
sigact.sa_flags = 0;
sigemptyset(&sigact.sa_mask);
sigaddset(&sigact.sa_mask, SIGUSR1);
sigaction(SIGUSR1, &sigact, NULL);
signal(SIGPIPE, SIG_IGN);
}
// copied from include/asm-generic/resource.h in the kernel
static struct rlimit_ init_rlimits[16] = {
[RLIMIT_CPU_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_FSIZE_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_DATA_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_STACK_] = {8*1024*1024, RLIM_INFINITY_},
[RLIMIT_CORE_] = {0, RLIM_INFINITY_},
[RLIMIT_RSS_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_NPROC_] = {1024, 1024},
[RLIMIT_NOFILE_] = {1024, 4096},
[RLIMIT_MEMLOCK_] = {64*1024, 64*1024},
[RLIMIT_AS_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_LOCKS_] = {RLIM_INFINITY_, RLIM_INFINITY_},
[RLIMIT_SIGPENDING_] = {1024, 1024},
[RLIMIT_MSGQUEUE_] = {819200, 819200},
[RLIMIT_NICE_] = {0, 0},
[RLIMIT_RTPRIO_] = {0, 0},
[RLIMIT_RTTIME_] = {RLIM_INFINITY_, RLIM_INFINITY_},
};
// TODO error propagation
static struct task *construct_task(struct task *parent) {
struct task *task = task_create_(parent);
struct tgroup *group = malloc(sizeof(struct tgroup));
*group = (struct tgroup) {};
list_init(&group->threads);
lock_init(&group->lock);
cond_init(&group->child_exit);
cond_init(&group->stopped_cond);
memcpy(group->limits, init_rlimits, sizeof(init_rlimits));
group->leader = task;
group->personality = ADDR_NO_RANDOMIZE_;
list_add(&group->threads, &task->group_links);
task->group = group;
task->tgid = task->pid;
task_setsid(task);
task_set_mm(task, mm_new());
task->sighand = sighand_new();
task->files = fdtable_new(3); // why is there a 3 here
task->fs = fs_info_new();
task->fs->umask = 0022;
// we'll need to have current set to do the open call
struct task *old_current = current;
current = task;
task->fs->root = generic_open("/", O_RDONLY_, 0);
if (IS_ERR(task->fs->root))
return ERR_PTR(task->fs->root);
task->fs->pwd = fd_retain(task->fs->root);
current = old_current;
return task;
}
int become_first_process() {
// now seems like a nice time
establish_signal_handlers();
struct task *task = construct_task(NULL);
if (IS_ERR(task))
return PTR_ERR(task);
current = task;
return 0;
}
int become_new_init_child() {
// locking? who needs locking?!
struct task *init = pid_get_task(1);
assert(init != NULL);
struct task *task = construct_task(init);
if (IS_ERR(task))
return PTR_ERR(task);
// these are things we definitely don't want to inherit
task->clear_tid = 0;
task->vfork = NULL;
task->blocked = task->pending = task->waiting = 0;
list_init(&task->queue);
// TODO: think about whether it would be a good idea to inherit fs_info
current = task;
return 0;
}
extern int console_major;
extern int console_minor;
void set_console_device(int major, int minor) {
console_major = major;
console_minor = minor;
}
int create_stdio(const char *file, int major, int minor) {
struct fd *fd = generic_open(file, O_RDWR_, 0);
if (IS_ERR(fd)) {
// fallback to adhoc files for stdio
fd = adhoc_fd_create(NULL);
fd->stat.rdev = dev_make(major, minor);
fd->stat.mode = S_IFCHR | S_IRUSR;
fd->flags = O_RDWR_;
int err = dev_open(major, minor, DEV_CHAR, fd);
if (err < 0)
return err;
}
fd->refcount = 0;
current->files->files[0] = fd_retain(fd);
current->files->files[1] = fd_retain(fd);
current->files->files[2] = fd_retain(fd);
return 0;
}
static struct fd *open_fd_from_actual_fd(int fd_no) {
struct fd *fd = adhoc_fd_create(&realfs_fdops);
if (fd == NULL) {
return NULL;
}
fd->real_fd = fd_no;
fd->dir = NULL;
return fd;
}
int create_piped_stdio() {
if (!(current->files->files[0] = open_fd_from_actual_fd(STDIN_FILENO))) {
return -1;
}
if (!(current->files->files[1] = open_fd_from_actual_fd(STDOUT_FILENO))) {
return -1;
}
if (!(current->files->files[2] = open_fd_from_actual_fd(STDERR_FILENO))) {
return -1;
}
return 0;
}