part_blk: added optional partitions report

This commit is contained in:
Boris Mulder 2017-05-18 11:12:11 +02:00 committed by Christian Helmuth
parent 6299f4a7df
commit d094ff995f
6 changed files with 126 additions and 36 deletions

View File

@ -13,6 +13,7 @@ build {
drivers/timer
server/rom_blk
server/part_blk
server/report_rom
test/blk/cli
}
@ -36,8 +37,8 @@ if { ![file exists $img_path] } then {
exec parted -s $img_path mkpart logical fat32 12288s 20479s
} else {
exec parted -s $img_path mklabel gpt
exec parted -s $img_path mkpart 1 fat32 2048s 4095s
exec parted -s $img_path mkpart 2 fat32 4096s 20446s
exec parted -s $img_path mkpart one fat32 2048s 4095s
exec parted -s $img_path mkpart two fat32 4096s 20446s
}
}
@ -82,12 +83,14 @@ append config {
if { $mode == "mbr" } {
append config {
<config>
<report partitions="yes"/>
<policy label_prefix="test-part1" partition="6"/>
<policy label_prefix="test-part2" partition="1"/>
</config>}
} else {
append config {
<config use_gpt="yes">
<report partitions="yes"/>
<policy label_prefix="test-part1" partition="2"/>
<policy label_prefix="test-part2" partition="1"/>
</config>}
@ -95,6 +98,14 @@ if { $mode == "mbr" } {
append config {
</start>
<start name="report_rom">
<provides>
<service name="Report"/>
<service name="ROM"/>
</provides>
<resource name="RAM" quantum="5M" />
<config verbose="yes"/>
</start>
<start name="test-part1">
<binary name="test-blk-cli"/>
<resource name="RAM" quantum="5M" />
@ -117,7 +128,10 @@ install_config $config
# Boot modules
#
append boot_modules { core ld.lib.so init timer rom_blk part_blk test-blk-cli }
append boot_modules {
core ld.lib.so init timer
rom_blk part_blk test-blk-cli report_rom
}
append boot_modules $img_file
build_boot_image $boot_modules

View File

@ -24,6 +24,24 @@ configuration section looking for 'policy' tags.
XML Syntax:
! <policy labal="<program name>" parition="<partition number>" />
part_blk supports partition reporting, which can be enabled via the
<report> configuration node. See below for an example. The report
looks like follows (for MBR resp. GPT).
! <partitions type="mbr">
! <partition number="1" type="12" start="2048" length="2048"/>
! <partition number="2" type="15" start="4096" length="16384"/>
! <partition number="5" type="12" start="6144" length="4096"/>
! <partition number="6" type="12" start="12288" length="8192"/>
! </partitions>
! <partitions type="gpt">
! <partition number="1" name="one" type="ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
! guid="5f4061cc-8d4a-4e6f-ad15-10b881b79aee" start="2048" length="2048"/>
! <partition number="2" name="two" type="ebd0a0a2-b9e5-4433-87c0-68b6b72699c7"
! guid="87199a83-d0f4-4a01-b9e3-6516a8579d61" start="4096" length="16351"/>
! </partitions>
Usage
-----
@ -46,6 +64,7 @@ Configuration snippet with two clients and an (hypothetical) IDE driver:
! <!-- allow program 'test-part1' to access logical partition '6', while program
! 'test-part2' receives access to primary partition 1 -->
! <config>
! <report partitions="yes"/>
! <policy label_prefix="test-part1" partition="6"/>
! <policy label_prefix="test-part2" partition="1"/>
! </config>

View File

@ -251,6 +251,32 @@ class Gpt : public Block::Partition_table
" blocks) type: '", e->_type.to_string(),
"' name: '", e->name(), "'");
}
/* Report the partitions */
if (reporter.enabled())
{
Genode::Reporter::Xml_generator xml(reporter, [&] () {
xml.attribute("type", "gpt");
for (int i = 0; i < MAX_PARTITIONS; i++) {
Gpt_entry *e = (entries + i);
if (!e->valid()){
continue;
}
xml.node("partition", [&] () {
xml.attribute("number", i + 1);
xml.attribute("name", e->name());
xml.attribute("type", e->_type.to_string());
xml.attribute("guid", e->_guid.to_string());
xml.attribute("start", e->_lba_start);
xml.attribute("length", e->_lba_end - e->_lba_start + 1);
});
}
});
}
}
public:

View File

@ -33,11 +33,12 @@ class Main
Block::Partition_table & _table();
Genode::Env & _env;
Genode::Heap _heap { _env.ram(), _env.rm() };
Block::Driver _driver { _env, _heap };
Mbr_partition_table _mbr { _heap, _driver };
Gpt _gpt { _heap, _driver };
Block::Root _root { _env, _heap, _driver, _table() };
Genode::Heap _heap { _env.ram(), _env.rm() };
Block::Driver _driver { _env, _heap };
Genode::Reporter _reporter { _env, "partitions" };
Mbr_partition_table _mbr { _heap, _driver, _reporter };
Gpt _gpt { _heap, _driver, _reporter };
Block::Root _root { _env, _heap, _driver, _table() };
public:
@ -62,12 +63,21 @@ Block::Partition_table & Main::_table()
bool valid_mbr = false;
bool valid_gpt = false;
bool use_gpt = false;
bool report = false;
Genode::Attached_rom_dataspace config(_env, "config");
try {
Genode::Attached_rom_dataspace config(_env, "config");
use_gpt = config.xml().attribute_value("use_gpt", false);
} catch(...) {}
try {
report = config.xml().sub_node("report").attribute_value
("partitions", false);
if (report)
_reporter.enabled(true);
} catch(...) {}
if (use_gpt)
try { valid_gpt = _gpt.parse(); } catch (...) { }

View File

@ -49,7 +49,7 @@ struct Mbr_partition_table : public Block::Partition_table
Genode::uint32_t _sectors; /* number of sectors */
bool valid() { return _type != INVALID; }
bool extented() { return _type == EXTENTED_CHS
bool extended() { return _type == EXTENTED_CHS
|| _type == EXTENTED_LBA; }
bool protective() { return _type == PROTECTIVE; }
} __attribute__((packed));
@ -78,7 +78,8 @@ struct Mbr_partition_table : public Block::Partition_table
Block::Partition *_part_list[MAX_PARTITIONS]; /* contains pointers to valid
partitions or 0 */
void _parse_extented(Partition_record *record)
template <typename FUNC>
void _parse_extended(Partition_record *record, FUNC const &f)
{
Partition_record *r = record;
unsigned lba = r->_lba;
@ -96,12 +97,7 @@ struct Mbr_partition_table : public Block::Partition_table
* partition is relative to the lba of the current EBR */
Partition_record *logical = &(ebr->_records[0]);
if (logical->valid() && nr < MAX_PARTITIONS) {
_part_list[nr++] = new (&heap)
Block::Partition(logical->_lba + lba, logical->_sectors);
Genode::log("Partition ", nr - 1, ": LBA ", logical->_lba + lba,
" (", (unsigned int)logical->_sectors, " blocks) type ",
Genode::Hex(logical->_type, Genode::Hex::OMIT_PREFIX));
f(nr++, logical, lba);
}
/*
@ -114,12 +110,9 @@ struct Mbr_partition_table : public Block::Partition_table
} while (r->valid());
}
void _parse_mbr(Mbr *mbr)
template <typename FUNC>
void _parse_mbr(Mbr *mbr, FUNC const &f)
{
/* no partition table, use whole disc as partition 0 */
if (!(mbr->valid()))
_part_list[0] = new (&heap)
Block::Partition(0, driver.blk_cnt() - 1);
for (int i = 0; i < 4; i++) {
Partition_record *r = &(mbr->_records[i]);
@ -127,21 +120,14 @@ struct Mbr_partition_table : public Block::Partition_table
if (!r->valid())
continue;
Genode::log("Partition ", i + 1, ": LBA ",
(unsigned int) r->_lba, " (",
(unsigned int) r->_sectors, " blocks) type: ",
Genode::Hex(r->_type, Genode::Hex::OMIT_PREFIX));
if (r->protective())
throw Protective_mbr_found();
if (r->extented()) {
_parse_extented(r);
continue;
}
f(i + 1, r, 0);
_part_list[i + 1] = new (&heap)
Block::Partition(r->_lba, r->_sectors);
if (r->extended()) {
_parse_extended(r, f);
}
}
}
@ -155,7 +141,40 @@ struct Mbr_partition_table : public Block::Partition_table
bool parse()
{
Sector s(driver, 0, 1);
_parse_mbr(s.addr<Mbr *>());
Mbr *mbr = s.addr<Mbr *>();
/* no partition table, use whole disc as partition 0 */
if (!(mbr->valid()))
_part_list[0] = new (&heap)
Block::Partition(0, driver.blk_cnt() - 1);
_parse_mbr(mbr, [&] (int i, Partition_record *r, unsigned offset) {
Genode::log("Partition ", i, ": LBA ",
(unsigned int) r->_lba + offset, " (",
(unsigned int) r->_sectors, " blocks) type: ",
Genode::Hex(r->_type, Genode::Hex::OMIT_PREFIX));
if (!r->extended())
_part_list[i] = new (&heap)
Block::Partition(r->_lba + offset, r->_sectors);
});
/* Report the partitions */
if (reporter.enabled())
{
Genode::Reporter::Xml_generator xml(reporter, [&] () {
xml.attribute("type", "mbr");
_parse_mbr(mbr, [&] (int i, Partition_record *r, unsigned offset) {
xml.node("partition", [&] {
xml.attribute("number", i);
xml.attribute("type", r->_type);
xml.attribute("start", r->_lba + offset);
xml.attribute("length", r->_sectors);
});
});
});
}
for (unsigned num = 0; num < MAX_PARTITIONS; num++)
if (_part_list[num])
return true;

View File

@ -18,6 +18,7 @@
#include <base/env.h>
#include <base/log.h>
#include <block_session/client.h>
#include <os/reporter.h>
#include "driver.h"
@ -72,9 +73,10 @@ struct Block::Partition_table
Genode::Heap & heap;
Driver & driver;
Genode::Reporter & reporter;
Partition_table(Genode::Heap & h, Driver & d)
: heap(h), driver(d) {}
Partition_table(Genode::Heap & h, Driver & d, Genode::Reporter & r)
: heap(h), driver(d), reporter(r) {}
virtual Partition *partition(int num) = 0;