| 81 | } |
| 82 | |
| 83 | static BAN::RefPtr<FileSystem> load_root_filesystem(BAN::StringView root_path) |
| 84 | { |
| 85 | if (root_path.empty()) |
| 86 | return load_fallback_root_filesystem(); |
| 87 | |
| 88 | enum class RootType |
| 89 | { |
| 90 | PartitionUUID, |
| 91 | BlockDeviceName, |
| 92 | }; |
| 93 | |
| 94 | BAN::StringView entry; |
| 95 | RootType type; |
| 96 | |
| 97 | if (root_path.starts_with("PARTUUID="_sv)) |
| 98 | { |
| 99 | entry = root_path.substring(9); |
| 100 | if (entry.size() != 36) |
| 101 | { |
| 102 | derrorln("Invalid UUID '{}'", entry); |
| 103 | return load_fallback_root_filesystem(); |
| 104 | } |
| 105 | type = RootType::PartitionUUID; |
| 106 | } |
| 107 | else if (root_path.starts_with("/dev/"_sv)) |
| 108 | { |
| 109 | entry = root_path.substring(5); |
| 110 | if (entry.empty() || entry.contains('/')) |
| 111 | { |
| 112 | derrorln("Invalid root path '{}'", root_path); |
| 113 | return load_fallback_root_filesystem(); |
| 114 | } |
| 115 | type = RootType::BlockDeviceName; |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | derrorln("Unsupported root path format '{}'", root_path); |
| 120 | return load_fallback_root_filesystem(); |
| 121 | } |
| 122 | |
| 123 | constexpr size_t timeout_ms = 10'000; |
| 124 | constexpr size_t sleep_ms = 500; |
| 125 | |
| 126 | for (size_t i = 0; i < timeout_ms / sleep_ms; i++) |
| 127 | { |
| 128 | BAN::ErrorOr<BAN::RefPtr<BlockDevice>> ret = BAN::Error::from_errno(EINVAL); |
| 129 | |
| 130 | switch (type) |
| 131 | { |
| 132 | case RootType::PartitionUUID: |
| 133 | ret = find_partition_by_uuid(entry); |
| 134 | break; |
| 135 | case RootType::BlockDeviceName: |
| 136 | ret = find_block_device_by_name(entry); |
| 137 | break; |
| 138 | } |
| 139 | |
| 140 | if (!ret.is_error()) |
no test coverage detected