Commit graph

1350 commits

Author SHA1 Message Date
kleines Filmröllchen
b645f87b7a Kernel: Overhaul system shutdown procedure
For a long time, our shutdown procedure has basically been:
- Acquire big process lock.
- Switch framebuffer to Kernel debug console.
- Sync and lock all file systems so that disk caches are flushed and
  files are in a good state.
- Use firmware and architecture-specific functionality to perform
  hardware shutdown.

This naive and simple shutdown procedure has multiple issues:
- No processes are terminated properly, meaning they cannot perform more
  complex cleanup work. If they were in the middle of I/O, for instance,
  only the data that already reached the Kernel is written to disk, and
  data corruption due to unfinished writes can therefore still occur.
- No file systems are unmounted, meaning that any important unmount work
  will never happen. This is important for e.g. Ext2, which has
  facilites for detecting improper unmounts (see superblock's s_state
  variable) and therefore requires a proper unmount to be performed.
  This was also the starting point for this PR, since I wanted to
  introduce basic Ext2 file system checking and unmounting.
- No hardware is properly shut down beyond what the system firmware does
  on its own.
- Shutdown is performed within the write() call that asked the Kernel to
  change its power state. If the shutdown procedure takes longer (i.e.
  when it's done properly), this blocks the process causing the shutdown
  and prevents any potentially-useful interactions between Kernel and
  userland during shutdown.

In essence, current shutdown is a glorified system crash with minimal
file system cleanliness guarantees.

Therefore, this commit is the first step in improving our shutdown
procedure. The new shutdown flow is now as follows:
- From the write() call to the power state SysFS node, a new task is
  started, the Power State Switch Task. Its only purpose is to change
  the operating system's power state. This task takes over shutdown and
  reboot duties, although reboot is not modified in this commit.
- The Power State Switch Task assumes that userland has performed all
  shutdown duties it can perform on its own. In particular, it assumes
  that all kinds of clean process shutdown have been done, and remaining
  processes can be hard-killed without consequence. This is an important
  separation of concerns: While this commit does not modify userland, in
  the future SystemServer will be responsible for performing proper
  shutdown of user processes, including timeouts for stubborn processes
  etc.
- As mentioned above, the task hard-kills remaining user processes.
- The task hard-kills all Kernel processes except itself and the
  Finalizer Task. Since Kernel processes can delay their own shutdown
  indefinitely if they want to, they have plenty opportunity to perform
  proper shutdown if necessary. This may become a problem with
  non-cooperative Kernel tasks, but as seen two commits earlier, for now
  all tasks will cooperate within a few seconds.
- The task waits for the Finalizer Task to clean up all processes.
- The task hard-kills and finalizes the Finalizer Task itself, meaning
  that it now is the only remaining process in the system.
- The task syncs and locks all file systems, and then unmounts them. Due
  to an unknown refcount bug we currently cannot unmount the root file
  system; therefore the task is able to abort the clean unmount if
  necessary.
- The task performs platform-dependent hardware shutdown as before.

This commit has multiple remaining issues (or exposed existing ones)
which will need to be addressed in the future but are out of scope for
now:
- Unmounting the root filesystem is impossible due to remaining
  references to the inodes /home and /home/anon. I investigated this
  very heavily and could not find whoever is holding the last two
  references.
- Userland cannot perform proper cleanup, since the Kernel's power state
  variable is accessed directly by tools instead of a proper userland
  shutdown procedure directed by SystemServer.

The recently introduced Firmware/PowerState procedures are removed
again, since all of the architecture-independent code can live in the
power state switch task. The architecture-specific code is kept,
however.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
021fb3ea05 Kernel/Tasks: Allow Kernel processes to be shut down
Since we never check a kernel process's state like a userland process,
it's possible for a kernel process to ignore the fact that someone is
trying to kill it, and continue running. This is not desireable if we
want to properly shutdown all processes, including Kernel ones.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
8940552d1d Kernel/VirtualFileSystem: Allow unmounting via inode and mount path
This pair of information uniquely identifies any mount point, and it can
be used in situations where mount point custodies are not available.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
abc1eaff36 Kernel/VirtualFileSystem: Count bind mounts towards normal FS mountcount
This is correct since unmount doesn't treat bind mounts specially. If we
don't do this, unmounting bind mounts will call
prepare_for_last_unmount() on the guest FS much too early, which will
most likely fail due to a busy file system.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
251b17085b Kernel/Ext2: Check and set file system state
This is supposed to detect whether a file system was unmounted
cleanly or not.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
8fb126bec6 Kernel/FileSystem: Pass last mount point guest inode to unmount prepare
This will be important later on when we check file system busyness.
2023-07-15 00:12:01 +02:00
kleines Filmröllchen
2fe5ece449 Kernel: Add accessor for mount host custody
There's no reason this information needs to be secret.
2023-07-15 00:12:01 +02:00
Taj Morton
1d2f1abf97 FileSystem/FATFS: Convert internal FAT inode attributes to dirent types 2023-07-10 21:54:23 -06:00
Timothy Flynn
c911781c21 Everywhere: Remove needless trailing semi-colons after functions
This is a new option in clang-format-16.
2023-07-08 10:32:56 +01:00
Liav A
23a7ccf607 Kernel+LibCore+LibC: Split the mount syscall into multiple syscalls
This is a preparation before we can create a usable mechanism to use
filesystem-specific mount flags.
To keep some compatibility with userland code, LibC and LibCore mount
functions are kept being usable, but now instead of doing an "atomic"
syscall, they do multiple syscalls to perform the complete procedure of
mounting a filesystem.

The FileBackedFileSystem IntrusiveList in the VFS code is now changed to
be protected by a Mutex, because when we mount a new filesystem, we need
to check if a filesystem is already created for a given source_fd so we
do a scan for that OpenFileDescription in that list. If we fail to find
an already-created filesystem we create a new one and register it in the
list if we successfully mounted it. We use a Mutex because we might need
to initiate disk access during the filesystem creation, which will take
other mutexes in other parts of the kernel, therefore making it not
possible to take a spinlock while doing this.
2023-07-02 01:04:51 +02:00
Liav A
9b8b8c0e04 Kernel: Simplify reboot & poweroff code flow a bit
Instead of using ifdefs to use the correct platform-specific methods, we
can just use the same pattern we use for the microseconds_delay function
which has specific implementations for each Arch CPU subdirectory.

When linking a kernel image, the actual correct and platform-specific
power-state changing methods will be called in Firmware/PowerState.cpp
file.
2023-06-27 20:04:42 +02:00
Liav A
d550b09871 Kernel: Move PC BIOS-related code to the x86_64 architecture directory
All code that is related to PC BIOS should not be in the Kernel/Firmware
directory as this directory is for abstracted and platform-agnostic code
like ACPI (and device tree parsing in the future).

This fixes a problem with the aarch64 architecure, as these machines
don't have any PC-BIOS in them so actually trying to access these memory
locations (EBDA, BIOS ROM) does not make any sense, as they're specific
to x86 machines only.
2023-06-19 23:49:00 +02:00
Liav A
be16a91aec Kernel: Rename FirmwareSysFSDirectory => SysFSFirmwareDirectory
This matches how we give the pattern names for other classses for SysFS
components.
2023-06-19 23:49:00 +02:00
Robin Voetter
a433cbefbe Kernel: Fix reading expansion ROM SysFS node
Previously, reads would only be successful for offset 0. For this
reason, the maximum size that could be correctly read from the PCI
expansion ROM SysFS node was limited to the block size, and
subsequent blocks would fail. This commit fixes the computation of
the number of bytes to read.
2023-06-19 21:35:37 +02:00
Tim Ledbetter
f95dccdb45 Kernel+LibCore: Add process creation time to /sys/kernel/processes 2023-06-10 07:13:25 +02:00
Tim Ledbetter
7f855ad6b3 Kernel: Initialize ProcFS timestamps to process creation time 2023-06-09 17:15:41 +02:00
Liav A
9ee098b119 Kernel: Move all Graphics-related code into Devices/GPU directory
Like the HID, Audio and Storage subsystem, the Graphics subsystem (which
handles GPUs technically) exposes unix device files (typically in /dev).
To ensure consistency across the repository, move all related files to a
new directory under Kernel/Devices called "GPU".

Also remove the redundant "GPU" word from the VirtIO driver directory,
and the word "Graphics" from GraphicsManagement.{h,cpp} filenames.
2023-06-06 00:40:32 +02:00
Liav A
336fb4f313 Kernel: Move InterruptDisabler to the Interrupts subdirectory 2023-06-04 21:32:34 +02:00
Liav A
927926b924 Kernel: Move Performance-measurement code to the Tasks subdirectory 2023-06-04 21:32:34 +02:00
Liav A
8f21420a1d Kernel: Move all boot-related code to the new Boot subdirectory 2023-06-04 21:32:34 +02:00
Liav A
7c0540a229 Everywhere: Move global Kernel pattern code to Kernel/Library directory
This has KString, KBuffer, DoubleBuffer, KBufferBuilder, IOWindow,
UserOrKernelBuffer and ScopedCritical classes being moved to the
Kernel/Library subdirectory.

Also, move the panic and assertions handling code to that directory.
2023-06-04 21:32:34 +02:00
Liav A
f1cbfc5a6e Kernel: Move task-crash related code to the Tasks subdirectory 2023-06-04 21:32:34 +02:00
Liav A
aaa1de7878 Kernel: Move {Virtual,Physical}Address classes to the Memory directory 2023-06-04 21:32:34 +02:00
Liav A
1b04726c85 Kernel: Move all tasks-related code to the Tasks subdirectory 2023-06-04 21:32:34 +02:00
Liav A
788022d5d1 Kernel: Move Jail code to a new subdirectory 2023-06-04 21:32:34 +02:00
Liav A
b40b1c8d93 Kernel+Userland: Ensure proper unveil permissions before using rm/rmdir
When deleting a directory, the rmdir syscall should fail if the path was
unveiled without the 'c' permission. This matches the same behavior that
OpenBSD enforces when doing this kind of operation.

When deleting a file, the unlink syscall should fail if the path was
unveiled without the 'w' permission, to ensure that userspace is aware
of the possibility of removing a file only when the path was unveiled as
writable.

When using the userdel utility, we now unveil that directory path with
the unveil 'c' permission so removal of an account home directory is
done properly.
2023-06-02 17:53:55 +02:00
Liav A
500b7b08d6 Kernel: Move the Storage directory to be a new directory under Devices
The Storage subsystem, like the Audio and HID subsystems, exposes Unix
device files (for example, in the /dev directory). To ensure consistency
across the repository, we should make the Storage subsystem to reside in
the Kernel/Devices directory like the two other mentioned subsystems.
2023-06-02 11:04:37 +02:00
Ben Wiederhake
5fafd82927 AK+Everywhere: Don't crash on invalid months
Sadly, we don't have proper error propagation here. However, crashing
the Kernel just because a CDROM contains an invalid month seems like a
bad idea.
2023-05-27 12:17:50 +02:00
Ben Wiederhake
815ea06d2c AK: Test from_unix_time_parts intensively 2023-05-27 12:17:50 +02:00
Liav A
2ab657d3b5 Kernel: Make Ext2FSInode::traverse_as_directory to take m_inode_lock
The contents of the directory inode could change if we are not taking so
we must take the m_inode_lock to prevent corruption when reading the
directory contents.
2023-05-27 10:58:58 +02:00
Liav A
902dac7f5f Kernel: Don't lock ProcFS mutex when calling traverse_as_directory
This is not needed, because when we are doing this traversing, functions
that are called from this function are using proper and more "atomic"
locking.
2023-05-27 10:58:58 +02:00
Liav A
bce17d06f5 Kernel: Don't lock SysFS filesystem mutex calling traverse_as_directory
This locking is simply not needed because the associated SysFS component
will use proper and more "atomic" locking on its own.
2023-05-27 10:58:58 +02:00
kleines Filmröllchen
939600d2d4 Kernel: Use UnixDateTime wherever applicable
"Wherever applicable" = most places, actually :^), especially for
networking and filesystem timestamps.

This includes changes to unzip, which uses DOSPackedTime, since that is
changed for the FAT file systems.
2023-05-24 23:18:07 +02:00
kleines Filmröllchen
213025f210 AK: Rename Time to Duration
That's what this class really is; in fact that's what the first line of
the comment says it is.

This commit does not rename the main files, since those will contain
other time-related classes in a little bit.
2023-05-24 23:18:07 +02:00
Liav A
4617c05a08 Kernel: Move a bunch of generic devices code into new subdirectory 2023-05-19 21:49:21 +02:00
Daniel Bertalan
d9c557d0b4 Kernel: Add RPi Watchdog and use it for system shutdown
The Raspberry Pi hardware doesn't support a proper software-initiated
shutdown, so this instead uses the watchdog to reboot to a special
partition which the firmware interprets as an immediate halt on
shutdown. When running under Qemu, this causes the emulator to exit.
2023-05-17 01:32:43 -06:00
Daniel Bertalan
2123fdd678 Kernel: Remove FIFO::{attach,detach}(Direction)
These functions would have caused a `-Woverloaded-virtual` warning with
GCC 13, as they shadow `File::{attach,detach}(OpenFileDescription&)`.

Both of these functions had a single call site. This commit inlines
`attach` into its only caller, `FIFO::open_direction`.

Instead of explicitly checking `is_fifo()` in `~OpenFileDescription`
before running the `detach(Direction)` overload, let's just override the
regular `detach(OpenFileDescription&)` for `FIFO` to perform this action
instead.
2023-05-15 07:00:29 +02:00
Pankaj Raghav
ac9d60bb13 Kernel: Promote the entry to the front during a cache hit
Whenever an entry is added to the cache, the last element is removed to
make space for the new entry(if the cache is full). To make this an LRU
cache, the entry needs to be moved to the front of the list when there
is a cache hit so that the least recently used entry moves to the end
to be evicted first.
2023-05-06 08:00:55 +02:00
Timothy Flynn
3d4d0a1243 Kernel: Colorize log message for paths which haven't been unveiled
The log message can be hard to spot in a sea of debug messages. Colorize
it to make the message more immediately pop out.
2023-04-25 18:04:15 +02:00
Liav A
ee4e9b807a Kernel: Protect internal structures in InodeWatcher with spinlocks
This was the last change that was needed to be able boot with the flag
of LOCK_IN_CRITICAL_DEBUG. That flag is not always enabled because there
are still other issues in which we hold a spinlock and still try to lock
a mutex.

Instead of using one global mutex we can protect internal structures of
the InodeWatcher class with SpinlockProtected wrappers. This in turn
allows the InodeWatcher code to be called from other parts in the kernel
while holding a prior spinlock properly.
2023-04-22 07:16:41 +02:00
Tim Schumacher
12ce6ef3d7 Kernel+Userland: Remove the nfds entry from /sys/kernel/processes
`process.fds()` is protected by a Mutex, which causes issues when we try
to acquire it while holding a Spinlock. Since nothing seems to use this
value, let's just remove it entirely for now.
2023-04-21 13:55:23 +02:00
Tim Schumacher
d4e114a31e Kernel: Remove unused functions related to reading full inodes 2023-04-17 01:20:23 +02:00
Tim Schumacher
6f524e35a7 Kernel: Use purpose-sized buffers when resolving inodes as links 2023-04-17 01:20:23 +02:00
Tim Schumacher
acd8c8dba4 Kernel: Add Inode::read_until_filled_or_end
The existing `read_entire` is quite slow due to allocating and copying
multiple times, but it is simultaneously quite hard to get rid of in a
single step. As a replacement, add a new function that reads as much as
possible directly into a user-provided buffer.
2023-04-17 01:20:23 +02:00
Liav A
b02ee664e7 Kernel: Get rid of *LockRefPtr in the SysFS filesystem code
To do this we also need to get rid of LockRefPtrs in the USB code as
well.
Most of the SysFS nodes are statically generated during boot and are not
mutated afterwards.

The same goes for general device code - once we generate the appropriate
SysFS nodes, we almost never mutate the node pointers afterwards, making
locking unnecessary.
2023-04-14 19:24:54 +02:00
Liav A
cbf78975f1 Kernel: Add the futimens syscall
We have a problem with the original utimensat syscall because when we
do call LibC futimens function, internally we provide an empty path,
and the Kernel get_syscall_path_argument method will detect this as an
invalid path.

This happens to spit an error for example in the touch utility, so if a
user is running "touch non_existing_file", it will create that file, but
the user will still see an error coming from LibC futimens function.

This new syscall gets an open file description and it provides the same
functionality as utimensat, on the specified open file description.
The new syscall will be used later by LibC to properly implement LibC
futimens function so the situation described with relation to the
"touch" utility could be fixed.
2023-04-10 10:21:28 +02:00
Liav A
6c4a47d916 Kernel: Remove redundant HID name from all associated files 2023-04-09 18:11:37 +02:00
Liav A
7b745a20f1 Kernel: Mark a bunch of NonnullRefPtrs also const to ensure immutability
These were easy to pick-up as these pointers are assigned during the
construction point and are never changed afterwards.

This small change to these pointers will ensure that our code will not
accidentally assign these pointers with a new object which is always a
kind of bug we will want to prevent.
2023-04-08 13:44:21 +02:00
Andreas Kling
1c77803845 Kernel: Stop using *LockRefPtr for TTY
TTY was only stored in Process::m_tty, so make that a SpinlockProtected.
2023-04-05 11:37:27 +02:00
Andreas Kling
c3915e4058 Kernel: Stop using *LockRefPtr for Thread
These were stored in a bunch of places. The main one that's a bit iffy
is the Mutex::m_holder one, which I'm going to simplify in a subsequent
commit.

In Plan9FS and WorkQueue, we can't make the NNRPs const due to
initialization order problems. That's probably doable with further
cleanup, but left as an exercise for our future selves.

Before starting this, I expected the thread blockers to be a problem,
but as it turns out they were super straightforward (for once!) as they
don't mutate the thread after initiating a block, so they can just use
simple const-ified NNRPs.
2023-04-04 10:33:42 +02:00