173 lines
4.5 KiB
C++
173 lines
4.5 KiB
C++
/*
|
|
* \brief Representation of block-device partition
|
|
* \author Norman Feske
|
|
* \date 2018-05-02
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2018 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU Affero General Public License version 3.
|
|
*/
|
|
|
|
#ifndef _MODEL__PARTITION_H_
|
|
#define _MODEL__PARTITION_H_
|
|
|
|
#include "types.h"
|
|
#include "capacity.h"
|
|
|
|
namespace Sculpt {
|
|
|
|
struct File_system;
|
|
struct Partition;
|
|
struct Partition_update_policy;
|
|
|
|
typedef List_model<Partition> Partitions;
|
|
};
|
|
|
|
|
|
struct Sculpt::File_system
|
|
{
|
|
enum Type { UNKNOWN, EXT2, FAT32, GEMDOS } type;
|
|
|
|
bool inspected = false;
|
|
|
|
bool accessible() const { return type == EXT2 || type == FAT32 || type == GEMDOS; }
|
|
|
|
bool expandable() const { return type == EXT2; }
|
|
|
|
File_system(Type type) : type(type) { }
|
|
};
|
|
|
|
|
|
struct Sculpt::Partition : List_model<Partition>::Element
|
|
{
|
|
typedef String<16> Number;
|
|
typedef String<32> Label;
|
|
|
|
enum Expandable { FIXED_SIZE, EXPANDABLE };
|
|
|
|
Number const number;
|
|
Label const label;
|
|
Capacity const capacity;
|
|
|
|
Expandable const _expandable;
|
|
|
|
Label next_label = label; /* used to set/unset the default partition */
|
|
|
|
File_system file_system;
|
|
|
|
bool check_in_progress = false;
|
|
bool format_in_progress = false;
|
|
bool gpt_expand_in_progress = false;
|
|
bool fs_resize_in_progress = false;
|
|
|
|
bool relabel_in_progress() const { return label != next_label; }
|
|
|
|
bool expand_in_progress() const { return gpt_expand_in_progress
|
|
|| fs_resize_in_progress; }
|
|
|
|
bool checkable() const { return file_system.type == File_system::EXT2; }
|
|
|
|
bool expandable() const
|
|
{
|
|
return file_system.expandable() && _expandable == EXPANDABLE;
|
|
}
|
|
|
|
bool idle() const { return !check_in_progress
|
|
&& !format_in_progress
|
|
&& !file_system.inspected
|
|
&& !relabel_in_progress(); }
|
|
|
|
bool genode_default() const { return label == "GENODE*"; }
|
|
bool genode() const { return label == "GENODE" || genode_default(); }
|
|
|
|
void toggle_default_label()
|
|
{
|
|
if (label == "GENODE") next_label = Label("GENODE*");
|
|
if (label == "GENODE*") next_label = Label("GENODE");
|
|
}
|
|
|
|
struct Args
|
|
{
|
|
Number number;
|
|
Label label;
|
|
Capacity capacity;
|
|
Expandable expandable;
|
|
File_system::Type fs_type;
|
|
|
|
static Args from_xml(Xml_node node)
|
|
{
|
|
auto const file_system = node.attribute_value("file_system", String<16>());
|
|
File_system::Type const fs_type = (file_system == "Ext2") ? File_system::EXT2
|
|
: (file_system == "GEMDOS") ? File_system::GEMDOS
|
|
: (file_system == "FAT32") ? File_system::FAT32
|
|
: File_system::UNKNOWN;
|
|
|
|
Number const number = node.attribute_value("number", Number());
|
|
|
|
unsigned long const block_size =
|
|
node.attribute_value("block_size", 512ULL);
|
|
|
|
unsigned long long const expandable =
|
|
node.attribute_value("expandable", 0ULL);
|
|
|
|
return Args { number == "0" ? Number{} : number,
|
|
node.attribute_value("name", Label()),
|
|
Capacity { node.attribute_value("length", 0ULL)*block_size },
|
|
(expandable*block_size > 1024*1024) ? EXPANDABLE : FIXED_SIZE,
|
|
fs_type };
|
|
}
|
|
|
|
static Args whole_device(Capacity capacity)
|
|
{
|
|
return { Number{}, "", capacity, FIXED_SIZE, File_system::UNKNOWN };
|
|
};
|
|
};
|
|
|
|
Partition(Args const &args)
|
|
:
|
|
number(args.number), label(args.label), capacity(args.capacity),
|
|
_expandable(args.expandable), file_system(args.fs_type)
|
|
{ }
|
|
|
|
bool whole_device() const { return !number.valid(); }
|
|
};
|
|
|
|
|
|
/**
|
|
* Policy for transforming a part_block report into a list of partitions
|
|
*/
|
|
struct Sculpt::Partition_update_policy : List_model<Partition>::Update_policy
|
|
{
|
|
Allocator &_alloc;
|
|
|
|
Partition_update_policy(Allocator &alloc) : _alloc(alloc) { }
|
|
|
|
void destroy_element(Partition &elem) { destroy(_alloc, &elem); }
|
|
|
|
Partition &create_element(Xml_node node)
|
|
{
|
|
return *new (_alloc) Partition(Partition::Args::from_xml(node));
|
|
}
|
|
|
|
void update_element(Partition &, Xml_node) { }
|
|
|
|
static bool node_is_element(Xml_node node)
|
|
{
|
|
/*
|
|
* Partition "0" is a pseudo partition that refers to the whole device
|
|
* with no partition table.
|
|
*/
|
|
return (node.attribute_value("number", Partition::Number()) != "0");
|
|
}
|
|
|
|
static bool element_matches_xml_node(Partition const &elem, Xml_node node)
|
|
{
|
|
return node.attribute_value("number", Partition::Number()) == elem.number;
|
|
}
|
|
};
|
|
|
|
#endif /* _MODEL__PARTITION_H_ */
|