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.
This commit is contained in:
Josef Söntgen 2018-05-03 11:44:23 +02:00 committed by Christian Helmuth
parent cfe6e0f15b
commit 9f8369c01e
2 changed files with 63 additions and 18 deletions

View File

@ -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.

View File

@ -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();
}