Browse Source

Kernel: Merge PowerStateSwitchTask reboot and shutdown procedures

The reboot procedure should prepare to "shutdown" the system cleanly and
therefore has to be merged with how shutdown is handled.
Liav A 1 year ago
parent
commit
ef6133337e
2 changed files with 23 additions and 25 deletions
  1. 18 23
      Kernel/Tasks/PowerStateSwitchTask.cpp
  2. 5 2
      Kernel/Tasks/PowerStateSwitchTask.h

+ 18 - 23
Kernel/Tasks/PowerStateSwitchTask.cpp

@@ -35,10 +35,10 @@ void PowerStateSwitchTask::power_state_switch_task(void* raw_entry_data)
     auto entry_data = bit_cast<PowerStateCommand>(raw_entry_data);
     switch (entry_data) {
     case PowerStateCommand::Shutdown:
-        MUST(PowerStateSwitchTask::perform_shutdown());
+        MUST(PowerStateSwitchTask::perform_shutdown(DoReboot::No));
         break;
     case PowerStateCommand::Reboot:
-        MUST(PowerStateSwitchTask::perform_reboot());
+        MUST(PowerStateSwitchTask::perform_shutdown(DoReboot::Yes));
         break;
     default:
         PANIC("Unknown power state command: {}", to_underlying(entry_data));
@@ -57,24 +57,7 @@ void PowerStateSwitchTask::spawn(PowerStateCommand command)
     g_power_state_switch_task = move(power_state_switch_task_thread);
 }
 
-ErrorOr<void> PowerStateSwitchTask::perform_reboot()
-{
-    dbgln("acquiring FS locks...");
-    FileSystem::lock_all();
-    dbgln("syncing mounted filesystems...");
-    FileSystem::sync();
-
-    dbgln("attempting reboot via ACPI");
-    if (ACPI::is_enabled())
-        ACPI::Parser::the()->try_acpi_reboot();
-    arch_specific_reboot();
-
-    dbgln("reboot attempts failed, applications will stop responding.");
-    dmesgln("Reboot can't be completed. It's safe to turn off the computer!");
-    Processor::halt();
-}
-
-ErrorOr<void> PowerStateSwitchTask::perform_shutdown()
+ErrorOr<void> PowerStateSwitchTask::perform_shutdown(PowerStateSwitchTask::DoReboot do_reboot)
 {
     // We assume that by this point userland has tried as much as possible to shut down everything in an orderly fashion.
     // Therefore, we force kill remaining processes, including Kernel processes, except the finalizer and ourselves.
@@ -146,13 +129,25 @@ ErrorOr<void> PowerStateSwitchTask::perform_shutdown()
     // Therefore, we just lock the scheduler big lock to ensure nothing happens
     // beyond this point forward.
     SpinlockLocker lock(g_scheduler_lock);
-    dbgln("Attempting system shutdown...");
 
-    arch_specific_poweroff();
+    if (do_reboot == DoReboot::Yes) {
+        dbgln("Attempting system reboot...");
+        dbgln("attempting reboot via ACPI");
+        if (ACPI::is_enabled())
+            ACPI::Parser::the()->try_acpi_reboot();
+        arch_specific_reboot();
 
-    dbgln("shutdown attempts failed, applications will stop responding.");
+        dmesgln("Reboot can't be completed. It's safe to turn off the computer!");
+        Processor::halt();
+        VERIFY_NOT_REACHED();
+    }
+    VERIFY(do_reboot == DoReboot::No);
+
+    dbgln("Attempting system shutdown...");
+    arch_specific_poweroff();
     dmesgln("Shutdown can't be completed. It's safe to turn off the computer!");
     Processor::halt();
+    VERIFY_NOT_REACHED();
 }
 
 ErrorOr<void> PowerStateSwitchTask::kill_all_user_processes()

+ 5 - 2
Kernel/Tasks/PowerStateSwitchTask.h

@@ -29,10 +29,13 @@ private:
     static void spawn(PowerStateCommand);
 
     static void power_state_switch_task(void* raw_entry_data);
-    static ErrorOr<void> perform_reboot();
-    static ErrorOr<void> perform_shutdown();
 
     static ErrorOr<void> kill_all_user_processes();
+    enum class DoReboot {
+        No,
+        Yes,
+    };
+    static ErrorOr<void> perform_shutdown(DoReboot);
 };
 
 }