diff --git a/kernel/include/kernel/Storage/Partition.h b/kernel/include/kernel/Storage/Partition.h index aec7c5ec..a2ec014b 100644 --- a/kernel/include/kernel/Storage/Partition.h +++ b/kernel/include/kernel/Storage/Partition.h @@ -25,6 +25,8 @@ namespace Kernel virtual BAN::StringView name() const override { return m_name; } + BAN::StringView uuid() const { return m_guid_string; } + private: Partition(BAN::RefPtr, const BAN::GUID&, const BAN::GUID&, uint64_t, uint64_t, uint64_t, const char*, uint32_t, BAN::StringView); @@ -32,6 +34,7 @@ namespace Kernel BAN::RefPtr m_device; const BAN::GUID m_type; const BAN::GUID m_guid; + const BAN::String m_guid_string; const uint64_t m_first_block; const uint64_t m_last_block; const uint64_t m_attributes; diff --git a/kernel/kernel/FS/VirtualFileSystem.cpp b/kernel/kernel/FS/VirtualFileSystem.cpp index 8c1181f5..c89eabaf 100644 --- a/kernel/kernel/FS/VirtualFileSystem.cpp +++ b/kernel/kernel/FS/VirtualFileSystem.cpp @@ -5,6 +5,8 @@ #include #include #include +#include + #include namespace Kernel @@ -17,13 +19,57 @@ namespace Kernel ASSERT(!s_instance); s_instance = MUST(BAN::RefPtr::create()); - ASSERT(root_path.size() >= 5 && root_path.substring(0, 5) == "/dev/"_sv);; - root_path = root_path.substring(5); + BAN::RefPtr root_device; + if (root_path.size() >= 5 && root_path.substring(0, 5) == "UUID="_sv) + { + auto uuid = root_path.substring(5); + if (uuid.size() != 36) + panic("Invalid UUID specified for root '{}'", uuid); - auto root_inode = MUST(DevFileSystem::get().root_inode()->find_inode(root_path)); - if (!root_inode->mode().ifblk()) - Kernel::panic("Specified root '/dev/{}' does not name a block device", root_path); - s_instance->m_root_fs = MUST(FileSystem::from_block_device(static_cast(root_inode.ptr()))); + BAN::RefPtr root_partition; + DevFileSystem::get().for_each_inode( + [&root_partition, uuid](BAN::RefPtr inode) -> BAN::Iteration + { + if (!inode->is_device()) + return BAN::Iteration::Continue; + if (!static_cast(inode.ptr())->is_partition()) + return BAN::Iteration::Continue; + auto* partition = static_cast(inode.ptr()); + dprintln("compare '{}' vs '{}'", partition->uuid(), uuid); + if (partition->uuid() != uuid) + return BAN::Iteration::Continue; + dprintln("FOUND"); + root_partition = partition; + return BAN::Iteration::Break; + } + ); + if (!root_partition) + panic("Could not find partition with UUID '{}'", uuid); + root_device = root_partition; + } + else if (root_path.size() >= 5 && root_path.substring(0, 5) == "/dev/"_sv) + { + auto device_name = root_path.substring(5); + + auto device_result = DevFileSystem::get().root_inode()->find_inode(device_name); + if (device_result.is_error()) + panic("Could not open root device '{}': {}", root_path, device_result.error()); + + auto device_inode = device_result.release_value(); + if (!device_inode->mode().ifblk()) + panic("Root inode '{}' is not an block device", root_path); + + root_device = static_cast(device_inode.ptr()); + } + else + { + panic("Unknown root path format '{}' specified", root_path); + } + + auto filesystem_result = FileSystem::from_block_device(root_device); + if (filesystem_result.is_error()) + panic("Could not create filesystem from '{}': {}", root_path, filesystem_result.error()); + s_instance->m_root_fs = filesystem_result.release_value(); Credentials root_creds { 0, 0, 0, 0 }; MUST(s_instance->mount(root_creds, &DevFileSystem::get(), "/dev"_sv)); diff --git a/kernel/kernel/Storage/Partition.cpp b/kernel/kernel/Storage/Partition.cpp index 54e343e1..e74104fc 100644 --- a/kernel/kernel/Storage/Partition.cpp +++ b/kernel/kernel/Storage/Partition.cpp @@ -18,6 +18,7 @@ namespace Kernel , m_device(device) , m_type(type) , m_guid(guid) + , m_guid_string(MUST(guid.to_string())) , m_first_block(first_block) , m_last_block(last_block) , m_attributes(attr)