/* * \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 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::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::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_ */