From 9f8369c01ea9455fb142d59d6fa147db9c4e46c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Josef=20S=C3=B6ntgen?= Date: Thu, 3 May 2018 11:44:23 +0200 Subject: [PATCH] part_blk: change behaviour regarding GPT usage The component will now always try to parse the MBR as well as the GPT (in this order). It will bail out if both are considered valid, using GPT/MBR hybrid tables is not supported. Fixes #2803. --- repos/os/src/server/part_blk/README | 12 +++-- repos/os/src/server/part_blk/main.cc | 69 ++++++++++++++++++++++------ 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/repos/os/src/server/part_blk/README b/repos/os/src/server/part_blk/README index cb79114400..41563e300d 100644 --- a/repos/os/src/server/part_blk/README +++ b/repos/os/src/server/part_blk/README @@ -14,9 +14,15 @@ extended boot records (EBRs) are parsed and offered as separate block sessions to the front-end clients. The four primary partitions will receive partition numbers '1' to '4' whereas the first logical partition will be assigned to '5'. -The partition server also understands the GUID partition table (GPT). If the -config attribute 'use_gpt' is set to 'yes' it will first try to parse any -existing GPT. In case there is no GPT it will fall back to parsing the MBR. +The partition server also understands the GUID partition table (GPT). It will +always try to read the MBR as well as the GPT and will bail out if both are +considered valid. It is up to the user to choose the right table. To do so, +the 'ignore_mbr' or 'ignore_gpt' config attribute may be specified. Using both +at the same time is a configuration error. Apart from that, the server will +show a warning in case a protective MBR is found but GPT is ignored and abort. +If valid GPT was encountered without a proper protective MBR it will use the +GPT but show a diagnostic warning. + In order to route a client to the right partition, the server parses its configuration section looking for 'policy' tags. diff --git a/repos/os/src/server/part_blk/main.cc b/repos/os/src/server/part_blk/main.cc index 01da406147..933eae1fda 100644 --- a/repos/os/src/server/part_blk/main.cc +++ b/repos/os/src/server/part_blk/main.cc @@ -45,7 +45,9 @@ class Main public: - class No_partion_table : Genode::Exception {}; + struct No_partion_table : Genode::Exception { }; + struct Ambiguous_tables : Genode::Exception { }; + struct Invalid_config : Genode::Exception { }; Main(Genode::Env &env) : _env(env) { @@ -63,15 +65,25 @@ class Main Block::Partition_table & Main::_table() { - bool valid_mbr = false; - bool valid_gpt = false; - bool use_gpt = false; - bool report = false; + using namespace Genode; + + bool valid_mbr = false; + bool valid_gpt = false; + bool ignore_gpt = false; + bool ignore_mbr = false; + bool pmbr_found = false; + bool report = false; try { - use_gpt = _config.xml().attribute_value("use_gpt", false); + ignore_gpt = _config.xml().attribute_value("ignore_gpt", false); + ignore_mbr = _config.xml().attribute_value("ignore_mbr", false); } catch(...) {} + if (ignore_gpt && ignore_mbr) { + error("invalid configuration: cannot ignore GPT as well as MBR"); + throw Invalid_config(); + } + try { report = _config.xml().sub_node("report").attribute_value ("partitions", false); @@ -79,24 +91,51 @@ Block::Partition_table & Main::_table() _reporter.enabled(true); } catch(...) {} - if (use_gpt) - try { valid_gpt = _gpt.parse(); } catch (...) { } + /* + * Try to parse MBR as well as GPT first if not instructued + * to ignore either one of them. + */ - /* fall back to MBR */ - if (!valid_gpt) { + if (!ignore_mbr) { try { valid_mbr = _mbr.parse(); } catch (Mbr_partition_table::Protective_mbr_found) { - if (!use_gpt) - Genode::error("Aborting: found protective MBR but ", - "GPT usage was not requested."); - throw; + pmbr_found = true; } } + if (!ignore_gpt) { + try { valid_gpt = _gpt.parse(); } + catch (...) { } + } + + /* + * Both tables are valid (although we would have expected a PMBR in + * conjunction with a GPT header - hybrid operation is not supported) + * and we will not decide which one to use, it is up to the user. + */ + + if (valid_mbr && valid_gpt) { + error("ambigious tables: found valid MBR as well as valid GPT"); + throw Ambiguous_tables(); + } + + if (valid_gpt && !pmbr_found) { + warning("will use GPT without proper protective MBR"); + } + + /* PMBR missing, i.e, MBR part[0] contains whole disk and GPT valid */ + if (pmbr_found && ignore_gpt) { + warning("found protective MBR but GPT is to be ignored"); + } + + /* + * Return the appropriate table or abort if none is found. + */ + if (valid_gpt) return _gpt; if (valid_mbr) return _mbr; - Genode::error("Aborting: no partition table found."); + error("Aborting: no partition table found."); throw No_partion_table(); }