From 952382b413484f3d81e7387e8ec0916bd5f48dc1 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Sun, 16 Jun 2019 11:49:39 +0200 Subject: [PATCH] Kernel/Userland: Add a halt syscall, and a shutdown binary to invoke it --- Kernel/FileSystem/FileSystem.cpp | 8 ++++++++ Kernel/FileSystem/FileSystem.h | 1 + Kernel/Syscall.cpp | 10 ++++++++++ Kernel/Syscall.h | 3 ++- Userland/shutdown.cpp | 17 +++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 Userland/shutdown.cpp diff --git a/Kernel/FileSystem/FileSystem.cpp b/Kernel/FileSystem/FileSystem.cpp index 96728554bc..95a4f47093 100644 --- a/Kernel/FileSystem/FileSystem.cpp +++ b/Kernel/FileSystem/FileSystem.cpp @@ -68,3 +68,11 @@ void FS::sync() for (auto fs : fses) fs->flush_writes(); } + +void FS::lock_all() +{ + for (auto& it : all_fses()) { + it.value->m_lock.lock(); + } +} + diff --git a/Kernel/FileSystem/FileSystem.h b/Kernel/FileSystem/FileSystem.h index 81d953c832..a41063c0a8 100644 --- a/Kernel/FileSystem/FileSystem.h +++ b/Kernel/FileSystem/FileSystem.h @@ -32,6 +32,7 @@ public: unsigned fsid() const { return m_fsid; } static FS* from_fsid(dword); static void sync(); + static void lock_all(); virtual bool initialize() = 0; virtual const char* class_name() const = 0; diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 95d14e44d7..0f6fb51404 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -281,6 +282,15 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2); case Syscall::SC_sched_getparam: return current->process().sys$sched_setparam((pid_t)arg1, (struct sched_param*)arg2); + case Syscall::SC_halt: { + dbgprintf("<%u> halting! acquiring locks...\n"); + FS::lock_all(); + dbgprintf("<%u> halting! syncing...\n"); + FS::sync(); + dbgprintf("<%u> halting! bye, friends...\n"); + IO::out16(0x604, 0x2000); + break; + } default: kprintf("<%u> int0x82: Unknown function %u requested {%x, %x, %x}\n", current->process().pid(), function, arg1, arg2, arg3); return -ENOSYS; diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index fd2f7fceef..033148a76f 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -112,7 +112,8 @@ struct timeval; __ENUMERATE_SYSCALL(getpeername) \ __ENUMERATE_SYSCALL(sched_setparam) \ __ENUMERATE_SYSCALL(sched_getparam) \ - __ENUMERATE_SYSCALL(fchown) + __ENUMERATE_SYSCALL(fchown) \ + __ENUMERATE_SYSCALL(halt) namespace Syscall { diff --git a/Userland/shutdown.cpp b/Userland/shutdown.cpp new file mode 100644 index 0000000000..7884f12c15 --- /dev/null +++ b/Userland/shutdown.cpp @@ -0,0 +1,17 @@ +#include +#include + +int main(int argc, char** argv) +{ + CArgsParser args_parser("shutdown"); + args_parser.add_arg("n", "shut down now"); + CArgsParserResult args = args_parser.parse(argc, (const char**)argv); + + if (args.is_present("n")) { + syscall(SC_halt); + return 0; + } else { + args_parser.print_usage(); + return 0; + } +}